const fixes
[openssl.git] / apps / ecparam.c
index 4c3054e..181cccc 100644 (file)
@@ -1,4 +1,7 @@
 /* apps/ecparam.c */
+/*
+ * Written by Nils Larsch for the OpenSSL project.
+ */
 /* ====================================================================
  * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
  *
  * The Contribution is licensed pursuant to the OpenSSL open source
  * license provided above.
  *
- * In addition, Sun covenants to all licensees who provide a reciprocal
- * covenant with respect to their own patents if any, not to sue under
- * current and future patent claims necessarily infringed by the making,
- * using, practicing, selling, offering for sale and/or otherwise
- * disposing of the Contribution as delivered hereunder 
- * (or portions thereof), provided that such covenant shall not apply:
- *  1) for code that a licensee deletes from the Contribution;
- *  2) separates from the Contribution; or
- *  3) for infringements caused by:
- *       i) the modification of the Contribution or
- *      ii) the combination of the Contribution with other software or
- *          devices where such combination causes the infringement.
- *
  * The elliptic curve binary polynomial software is originally written by 
  * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
  *
  */
-#ifndef OPENSSL_NO_ECDSA
+#ifndef OPENSSL_NO_EC
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <openssl/err.h>
 #include <openssl/bn.h>
 #include <openssl/ec.h>
-#include <openssl/ecdsa.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 
 #undef PROG
 #define PROG   ecparam_main
 
-/* -inform arg            - input format - default PEM (DER or PEM)
- * -outform arg           - output format - default PEM
- * -in arg                - input file  - default stdin
- * -out arg               - output file - default stdout
- * -noout
- * -text
- * -check                 - validate the ec parameters
- * -C
- * -noout
- * -name file             - use the ecparameters with 'short name' name
- * -list_curves           - prints a list of all currently available curve
- *                          'short names' and exits
- * -conv_form                  - specifies the point conversion form 
- *                          possible values : compressed
- *                                            uncompressed (default)
- *                                            hybrid
- * -param_enc             - specifies the way the ec parameters are encoded
- *                          in the asn1 der encoding
- *                          possilbe values : named_curve (default)
- *                                            explicit
- * -no_seed               - if 'explicit' parameters are choosen do not
- *                          use the seed
- * -genkey                - generates a ecdsa private key
- * -rand file
- * -engine e              - use engine e, possible a hardware device
+/* -inform arg      - input format - default PEM (DER or PEM)
+ * -outform arg     - output format - default PEM
+ * -in  arg         - input file  - default stdin
+ * -out arg         - output file - default stdout
+ * -noout           - do not print the ec parameter
+ * -text            - print the ec parameters in text form
+ * -check           - validate the ec parameters
+ * -C               - print a 'C' function creating the parameters
+ * -name arg        - use the ec parameters with 'short name' name
+ * -list_curves     - prints a list of all currently available curve 'short names'
+ * -conv_form arg   - specifies the point conversion form 
+ *                  - possible values: compressed
+ *                                     uncompressed (default)
+ *                                     hybrid
+ * -param_enc arg   - specifies the way the ec parameters are encoded
+ *                    in the asn1 der encoding
+ *                    possible values: named_curve (default)
+ *                                     explicit
+ * -no_seed         - if 'explicit' parameters are choosen do not use the seed
+ * -genkey          - generate ec key
+ * -rand file       - files to use for random number input
+ * -engine e        - use engine e, possibly a hardware device
  */
 
-static const char *curve_list[67] = {
-       "prime192v1   - 192 bit prime curve from the X9.62 draft",
-       "prime192v2   - 192 bit prime curve from the X9.62 draft",
-       "prime192v3   - 192 bit prime curve from the X9.62 draft",
-       "prime239v1   - 239 bit prime curve from the X9.62 draft",
-       "prime239v2   - 239 bit prime curve from the X9.62 draft",
-       "prime239v3   - 239 bit prime curve from the X9.62 draft", 
-       "prime256v1   - 256 bit prime curve from the X9.62 draft", 
-       "secp112r1    - SECG recommended curve over a 112 bit prime field", 
-       "secp112r2    - SECG recommended curve over a 112 bit prime field", 
-       "secp128r1    - SECG recommended curve over a 128 bit prime field",
-       "secp128r2    - SECG recommended curve over a 128 bit prime field", 
-       "secp160k1    - SECG recommended curve over a 160 bit prime field", 
-       "secp160r1    - SECG recommended curve over a 160 bit prime field", 
-       "secp160r2    - SECG recommended curve over a 160 bit prime field", 
-       "secp192k1    - SECG recommended curve over a 192 bit prime field",
-       "prime192v1   - SECG recommended curve over a 192 bit prime field (aka secp192r1)",
-       "secp224k1    - SECG recommended curve over a 224 bit prime field", 
-       "secp224r1    - SECG/NIST recommended curve over a 224 bit prime field", 
-       "secp256k1    - SECG recommended curve over a 256 bit prime field",
-       "prime256v1   - SECG recommended curve over a 256 bit prime field (aka secp256r1)",
-       "secp384r1    - SECG/NIST recommended curve over a 384 bit prime field", 
-       "secp521r1    - SECG/NIST recommended curve over a 521 bit prime field",
-       "wap-wsg-idm-ecid-wtls6  - 112 bit prime curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls8  - 112 bit prime curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls7  - 160 bit prime curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls9  - 160 bit prime curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls12 - 224 bit prime curve from the WTLS standard",
-       "c2pnb163v1   - 163 bit binary curve from the X9.62 draft",
-       "c2pnb163v2   - 163 bit binary curve from the X9.62 draft",
-       "c2pnb163v3   - 163 bit binary curve from the X9.62 draft",
-       "c2pnb176v1   - 176 bit binary curve from the X9.62 draft",
-       "c2tnb191v1   - 191 bit binary curve from the X9.62 draft",
-       "c2tnb191v2   - 191 bit binary curve from the X9.62 draft",
-       "c2tnb191v3   - 191 bit binary curve from the X9.62 draft",
-       "c2pnb208w1   - 208 bit binary curve from the X9.62 draft",
-       "c2tnb239v1   - 239 bit binary curve from the X9.62 draft",
-       "c2tnb239v2   - 239 bit binary curve from the X9.62 draft",
-       "c2tnb239v3   - 239 bit binary curve from the X9.62 draft",
-       "c2pnb272w1   - 272 bit binary curve from the X9.62 draft",
-       "c2pnb304w1   - 304 bit binary curve from the X9.62 draft",
-       "c2tnb359v1   - 359 bit binary curve from the X9.62 draft",
-       "c2pnb368w1   - 368 bit binary curve from the X9.62 draft",
-       "c2tnb431r1   - 431 bit binary curve from the X9.62 draft",
-       "sect113r1    - SECG recommended curve over a 113 bit binary field",
-       "sect113r2    - SECG recommended curve over a 113 bit binary field",
-       "sect131r1    - SECG recommended curve over a 131 bit binary field",
-       "sect131r2    - SECG recommended curve over a 131 bit binary field",
-       "sect163k1    - SECG/NIST recommended curve over a 163 bit binary field",
-       "sect163r1    - SECG recommended curve over a 163 bit binary field",
-       "sect163r2    - SECG/NIST recommended curve over a 163 bit binary field",
-       "sect193r1    - SECG recommended curve over a 193 bit binary field",
-       "sect193r2    - SECG recommended curve over a 193 bit binary field",
-       "sect233k1    - SECG/NIST recommended curve over a 233 bit binary field",
-       "sect233r1    - SECG/NIST recommended curve over a 233 bit binary field",
-       "sect239k1    - SECG recommended curve over a 239 bit binary field",
-       "sect283k1    - SECG/NIST recommended curve over a 283 bit binary field",
-       "sect283r1    - SECG/NIST recommended curve over a 283 bit binary field",
-       "sect409k1    - SECG/NIST recommended curve over a 409 bit binary field",
-       "sect409r1    - SECG/NIST recommended curve over a 409 bit binary field",
-       "sect571k1    - SECG/NIST recommended curve over a 571 bit binary field",
-       "sect571r1    - SECG/NIST recommended curve over a 571 bit binary field",
-       "wap-wsg-idm-ecid-wtls1  - 113 bit binary curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls4  - 113 bit binary curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls3  - 163 bit binary curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls5  - 163 bit binary curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls10 - 233 bit binary curve from the WTLS standard",
-       "wap-wsg-idm-ecid-wtls11 - 233 bit binary curve from the WTLS standard"
-};
 
 static int ecparam_print_var(BIO *,BIGNUM *,const char *,int,unsigned char *);
 
@@ -210,7 +127,9 @@ int MAIN(int argc, char **argv)
        char    *infile = NULL, *outfile = NULL, *prog;
        BIO     *in = NULL, *out = NULL;
        int     informat, outformat, noout = 0, C = 0, ret = 1;
+#ifndef OPENSSL_NO_ENGINE
        ENGINE  *e = NULL;
+#endif
        char    *engine = NULL;
 
        BIGNUM  *ec_p = NULL, *ec_a = NULL, *ec_b = NULL,
@@ -331,52 +250,51 @@ int MAIN(int argc, char **argv)
 bad:
                BIO_printf(bio_err, "%s [options] <infile >outfile\n",prog);
                BIO_printf(bio_err, "where options are\n");
-               BIO_printf(bio_err, " -inform arg             input format - "
+               BIO_printf(bio_err, " -inform arg       input format - "
                                "default PEM (DER or PEM)\n");
-               BIO_printf(bio_err, " -outform arg            output format - "
+               BIO_printf(bio_err, " -outform arg      output format - "
                                "default PEM\n");
-               BIO_printf(bio_err, " -in  arg                input file  - "
+               BIO_printf(bio_err, " -in  arg          input file  - "
                                "default stdin\n");
-               BIO_printf(bio_err, " -out arg                output file - "
+               BIO_printf(bio_err, " -out arg          output file - "
                                "default stdout\n");
-               BIO_printf(bio_err, " -noout                  do not print the "
+               BIO_printf(bio_err, " -noout            do not print the "
                                "ec parameter\n");
-               BIO_printf(bio_err, " -text                   print the ec "
+               BIO_printf(bio_err, " -text             print the ec "
                                "parameters in text form\n");
-               BIO_printf(bio_err, " -check                  validate the ec "
+               BIO_printf(bio_err, " -check            validate the ec "
                                "parameters\n");
-               BIO_printf(bio_err, " -C                      print a 'C' "
+               BIO_printf(bio_err, " -C                print a 'C' "
                                "function creating the parameters\n");
-               BIO_printf(bio_err, " -name arg               use the "
+               BIO_printf(bio_err, " -name arg         use the "
                                "ec parameters with 'short name' name\n");
-               BIO_printf(bio_err, " -list_curves            prints a list of "
-                               "all currently available curve\n");
-               BIO_printf(bio_err, "                         'short names'\n");
-               BIO_printf(bio_err, " -conv_form arg          specifies the "
+               BIO_printf(bio_err, " -list_curves      prints a list of "
+                               "all currently available curve 'short names'\n");
+               BIO_printf(bio_err, " -conv_form arg    specifies the "
                                "point conversion form \n");
-               BIO_printf(bio_err, "                         possible values :"
+               BIO_printf(bio_err, "                   possible values:"
                                " compressed\n");
-               BIO_printf(bio_err, "                                          "
+               BIO_printf(bio_err, "                                   "
                                " uncompressed (default)\n");
-               BIO_printf(bio_err, "                                          "
+               BIO_printf(bio_err, "                                   "
                                " hybrid\n");
-               BIO_printf(bio_err, " -param_enc arg          specifies the way"
+               BIO_printf(bio_err, " -param_enc arg    specifies the way"
                                " the ec parameters are encoded\n");
-               BIO_printf(bio_err, "                         in the asn1 der "
+               BIO_printf(bio_err, "                   in the asn1 der "
                                "encoding\n");
-               BIO_printf(bio_err, "                         possilbe values :"
+               BIO_printf(bio_err, "                   possible values:"
                                " named_curve (default)\n");
-               BIO_printf(bio_err,"                                      "
-                               "     explicit\n");
-               BIO_printf(bio_err, " -no_seed                if 'explicit'"
-                               " parameters are choosen do not\n");
-               BIO_printf(bio_err, "                         use the seed\n");
-               BIO_printf(bio_err, " -genkey                 generate ecdsa"
+               BIO_printf(bio_err, "                                   "
+                               " explicit\n");
+               BIO_printf(bio_err, " -no_seed          if 'explicit'"
+                               " parameters are choosen do not"
+                               " use the seed\n");
+               BIO_printf(bio_err, " -genkey           generate ec"
                                " key\n");
-               BIO_printf(bio_err, " -rand file              files to use for"
+               BIO_printf(bio_err, " -rand file        files to use for"
                                " random number input\n");
-               BIO_printf(bio_err, " -engine e               use engine e, "
-                               "possible a hardware device\n");
+               BIO_printf(bio_err, " -engine e         use engine e, "
+                               "possibly a hardware device\n");
                goto end;
                }
 
@@ -419,23 +337,72 @@ bad:
                        }
                }
 
+#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine, 0);
+#endif
 
        if (list_curves)
                {
-               int counter=0;
+               EC_builtin_curve *curves = NULL;
+               size_t crv_len = 0;
+               size_t n = 0;
 
-               for (; counter < sizeof(curve_list)/sizeof(char *); counter++)
-                       if (BIO_printf(bio_err, " %s\n", curve_list[counter]) 
-                               <= 0) 
-                               goto end;
+               crv_len = EC_get_builtin_curves(NULL, 0);
+
+               curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
+
+               if (curves == NULL)
+                       goto end;
+
+               if (!EC_get_builtin_curves(curves, crv_len))
+                       {
+                       OPENSSL_free(curves);
+                       goto end;
+                       }
+
+               
+               for (n = 0; n < crv_len; n++)
+                       {
+                       const char *comment;
+                       const char *sname;
+                       comment = curves[n].comment;
+                       sname   = OBJ_nid2sn(curves[n].nid);
+                       if (comment == NULL)
+                               comment = "CURVE DESCRIPTION NOT AVAILABLE";
+                       if (sname == NULL)
+                               sname = "";
+
+                       BIO_printf(out, "  %-10s: ", sname);
+                       BIO_printf(out, "%s\n", comment);
+                       } 
+
+               OPENSSL_free(curves);
                ret = 0;
                goto end;
                }
 
        if (curve_name != NULL)
                {
-               int nid = OBJ_sn2nid(curve_name);
+               int nid;
+
+               /* workaround for the SECG curve names secp192r1
+                * and secp256r1 (which are the same as the curves
+                * prime192v1 and prime256v1 defined in X9.62)
+                */
+               if (!strcmp(curve_name, "secp192r1"))
+                       {
+                       BIO_printf(bio_err, "using curve name prime192v1 "
+                               "instead of secp192r1\n");
+                       nid = NID_X9_62_prime192v1;
+                       }
+               else if (!strcmp(curve_name, "secp256r1"))
+                       {
+                       BIO_printf(bio_err, "using curve name prime256v1 "
+                               "instead of secp256r1\n");
+                       nid = NID_X9_62_prime256v1;
+                       }
+               else
+                       nid = OBJ_sn2nid(curve_name);
        
                if (nid == 0)
                        {
@@ -673,36 +640,36 @@ bad:
 
        if (genkey)
                {
-               ECDSA *ecdsa = ECDSA_new();
+               EC_KEY *eckey = EC_KEY_new();
 
-               if (ecdsa == NULL)
+               if (eckey == NULL)
                        goto end;
 
                assert(need_rand);
 
-               ecdsa->group = group;
+               eckey->group = group;
                
-               if (!ECDSA_generate_key(ecdsa))
+               if (!EC_KEY_generate_key(eckey))
                        {
-                       ecdsa->group = NULL;
-                       ECDSA_free(ecdsa);
+                       eckey->group = NULL;
+                       EC_KEY_free(eckey);
                        goto end;
                        }
                if (outformat == FORMAT_ASN1)
-                       i = i2d_ECDSAPrivateKey_bio(out, ecdsa);
+                       i = i2d_ECPrivateKey_bio(out, eckey);
                else if (outformat == FORMAT_PEM)
-                       i = PEM_write_bio_ECDSAPrivateKey(out, ecdsa, NULL,
+                       i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
                                NULL, 0, NULL, NULL);
                else    
                        {
                        BIO_printf(bio_err, "bad output format specified "
                                "for outfile\n");
-                       ecdsa->group = NULL;
-                       ECDSA_free(ecdsa);
+                       eckey->group = NULL;
+                       EC_KEY_free(eckey);
                        goto end;
                        }
-               ecdsa->group = NULL;
-               ECDSA_free(ecdsa);
+               eckey->group = NULL;
+               EC_KEY_free(eckey);
                }
 
        if (need_rand)
@@ -731,10 +698,10 @@ end:
        if (group != NULL)
                EC_GROUP_free(group);
        apps_shutdown();
-       EXIT(ret);
+       OPENSSL_EXIT(ret);
 }
 
-int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
+static int ecparam_print_var(BIO *out, BIGNUM *in, const char *var,
        int len, unsigned char *buffer)
        {
        BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);