Document -no_explicit
[openssl.git] / apps / genpkey.c
index 70e2e31..fef21dc 100644 (file)
@@ -1,6 +1,7 @@
 /* apps/genpkey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
- * project 2006
+/*
+ * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
+ * 2006
  */
 /* ====================================================================
  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
@@ -10,7 +11,7 @@
  * are met:
  *
  * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
+ *    notice, this list of conditions and the following disclaimer.
  *
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #ifndef OPENSSL_NO_ENGINE
-#include <openssl/engine.h>
+# include <openssl/engine.h>
 #endif
 
 static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
-                               const char *file, ENGINE *e);
-static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
-                               const char *algname, ENGINE *e, int do_param);
+                            const char *file, ENGINE *e);
 static int genpkey_cb(EVP_PKEY_CTX *ctx);
 
 #define PROG genpkey_main
@@ -76,352 +75,331 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx);
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
-       {
-       ENGINE *e = NULL;
-       char **args, *outfile = NULL;
-       char *passarg = NULL;
-       BIO *in = NULL, *out = NULL;
-       const EVP_CIPHER *cipher = NULL;
-       int outformat;
-       int text = 0;
-       EVP_PKEY *pkey=NULL;
-       EVP_PKEY_CTX *ctx = NULL;
-       char *pass = NULL;
-       int badarg = 0;
-       int ret = 1, rv;
-
-       int do_param = 0;
-
-       if (bio_err == NULL)
-               bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
-
-       if (!load_config(bio_err, NULL))
-               goto end;
-
-       outformat=FORMAT_PEM;
-
-       ERR_load_crypto_strings();
-       OpenSSL_add_all_algorithms();
-       args = argv + 1;
-       while (!badarg && *args && *args[0] == '-')
-               {
-               if (!strcmp(*args,"-outform"))
-                       {
-                       if (args[1])
-                               {
-                               args++;
-                               outformat=str2fmt(*args);
-                               }
-                       else badarg = 1;
-                       }
-               else if (!strcmp(*args,"-pass"))
-                       {
-                       if (!args[1]) goto bad;
-                       passarg= *(++args);
-                       }
+{
+    ENGINE *e = NULL;
+    char **args, *outfile = NULL;
+    char *passarg = NULL;
+    BIO *in = NULL, *out = NULL;
+    const EVP_CIPHER *cipher = NULL;
+    int outformat;
+    int text = 0;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    char *pass = NULL;
+    int badarg = 0;
+    int ret = 1, rv;
+
+    int do_param = 0;
+
+    if (bio_err == NULL)
+        bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
+
+    if (!load_config(bio_err, NULL))
+        goto end;
+
+    outformat = FORMAT_PEM;
+
+    ERR_load_crypto_strings();
+    OpenSSL_add_all_algorithms();
+    args = argv + 1;
+    while (!badarg && *args && *args[0] == '-') {
+        if (!strcmp(*args, "-outform")) {
+            if (args[1]) {
+                args++;
+                outformat = str2fmt(*args);
+            } else
+                badarg = 1;
+        } else if (!strcmp(*args, "-pass")) {
+            if (!args[1])
+                goto bad;
+            passarg = *(++args);
+        }
 #ifndef OPENSSL_NO_ENGINE
-               else if (strcmp(*args,"-engine") == 0)
-                       {
-                       if (!args[1])
-                               goto bad;
-                       e = setup_engine(bio_err, *(++args), 0);
-                       }
+        else if (strcmp(*args, "-engine") == 0) {
+            if (!args[1])
+                goto bad;
+            e = setup_engine(bio_err, *(++args), 0);
+        }
 #endif
-               else if (!strcmp (*args, "-paramfile"))
-                       {
-                       if (!args[1])
-                               goto bad;
-                       args++;
-                       if (do_param == 1)
-                               goto bad;
-                       if (!init_keygen_file(bio_err, &ctx, *args, e))
-                               goto end;
-                       }
-               else if (!strcmp (*args, "-out"))
-                       {
-                       if (args[1])
-                               {
-                               args++;
-                               outfile = *args;
-                               }
-                       else badarg = 1;
-                       }
-               else if (strcmp(*args,"-algorithm") == 0)
-                       {
-                       if (!args[1])
-                               goto bad;
-                       if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
-                               goto end;
-                       }
-               else if (strcmp(*args,"-pkeyopt") == 0)
-                       {
-                       if (!args[1])
-                               goto bad;
-                       if (!ctx)
-                               {
-                               BIO_puts(bio_err, "No keytype specified\n");
-                               goto bad;
-                               }
-                       else if (pkey_ctrl_string(ctx, *(++args)) <= 0)
-                               {
-                               BIO_puts(bio_err, "parameter setting error\n");
-                               ERR_print_errors(bio_err);
-                               goto end;
-                               }
-                       }
-               else if (strcmp(*args,"-genparam") == 0)
-                       {
-                       if (ctx)
-                               goto bad;
-                       do_param = 1;
-                       }
-               else if (strcmp(*args,"-text") == 0)
-                       text=1;
-               else
-                       {
-                       cipher = EVP_get_cipherbyname(*args + 1);
-                       if (!cipher)
-                               {
-                               BIO_printf(bio_err, "Unknown cipher %s\n",
-                                                               *args + 1);
-                               badarg = 1;
-                               }
-                       if (do_param == 1)
-                               badarg = 1;
-                       }
-               args++;
-               }
-
-       if (!ctx)
-               badarg = 1;
-
-       if (badarg)
-               {
-               bad:
-               BIO_printf(bio_err, "Usage genpkey [options]\n");
-               BIO_printf(bio_err, "where options are\n");
-               BIO_printf(bio_err, "-paramfile file parameter file\n");
-               BIO_printf(bio_err, "-pass arg       output file pass phrase source\n");
-               BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
-               BIO_printf(bio_err, "-out file       output file\n");
+        else if (!strcmp(*args, "-paramfile")) {
+            if (!args[1])
+                goto bad;
+            args++;
+            if (do_param == 1)
+                goto bad;
+            if (!init_keygen_file(bio_err, &ctx, *args, e))
+                goto end;
+        } else if (!strcmp(*args, "-out")) {
+            if (args[1]) {
+                args++;
+                outfile = *args;
+            } else
+                badarg = 1;
+        } else if (strcmp(*args, "-algorithm") == 0) {
+            if (!args[1])
+                goto bad;
+            if (!init_gen_str(bio_err, &ctx, *(++args), e, do_param))
+                goto end;
+        } else if (strcmp(*args, "-pkeyopt") == 0) {
+            if (!args[1])
+                goto bad;
+            if (!ctx) {
+                BIO_puts(bio_err, "No keytype specified\n");
+                goto bad;
+            } else if (pkey_ctrl_string(ctx, *(++args)) <= 0) {
+                BIO_puts(bio_err, "parameter setting error\n");
+                ERR_print_errors(bio_err);
+                goto end;
+            }
+        } else if (strcmp(*args, "-genparam") == 0) {
+            if (ctx)
+                goto bad;
+            do_param = 1;
+        } else if (strcmp(*args, "-text") == 0)
+            text = 1;
+        else {
+            cipher = EVP_get_cipherbyname(*args + 1);
+            if (!cipher) {
+                BIO_printf(bio_err, "Unknown cipher %s\n", *args + 1);
+                badarg = 1;
+            }
+            if (do_param == 1)
+                badarg = 1;
+        }
+        args++;
+    }
+
+    if (!ctx)
+        badarg = 1;
+
+    if (badarg) {
+ bad:
+        BIO_printf(bio_err, "Usage: genpkey [options]\n");
+        BIO_printf(bio_err, "where options may be\n");
+        BIO_printf(bio_err, "-out file          output file\n");
+        BIO_printf(bio_err,
+                   "-outform X         output format (DER or PEM)\n");
+        BIO_printf(bio_err,
+                   "-pass arg          output file pass phrase source\n");
+        BIO_printf(bio_err,
+                   "-<cipher>          use cipher <cipher> to encrypt the key\n");
 #ifndef OPENSSL_NO_ENGINE
-               BIO_printf(bio_err, "-engine e       use engine e, possibly a hardware device.\n");
+        BIO_printf(bio_err,
+                   "-engine e          use engine e, possibly a hardware device.\n");
 #endif
-               goto end;
-               }
-
-       if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
-               {
-               BIO_puts(bio_err, "Error getting password\n");
-               goto end;
-               }
-
-       if (outfile)
-               {
-               if (!(out = BIO_new_file (outfile, "wb")))
-                       {
-                       BIO_printf(bio_err,
-                                "Can't open output file %s\n", outfile);
-                       goto end;
-                       }
-               }
-       else
-               {
-               out = BIO_new_fp (stdout, BIO_NOCLOSE);
+        BIO_printf(bio_err, "-paramfile file    parameters file\n");
+        BIO_printf(bio_err, "-algorithm alg     the public key algorithm\n");
+        BIO_printf(bio_err,
+                   "-pkeyopt opt:value set the public key algorithm option <opt>\n"
+                   "                   to value <value>\n");
+        BIO_printf(bio_err,
+                   "-genparam          generate parameters, not key\n");
+        BIO_printf(bio_err, "-text              print the in text\n");
+        BIO_printf(bio_err,
+                   "NB: options order may be important!  See the manual page.\n");
+        goto end;
+    }
+
+    if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
+        BIO_puts(bio_err, "Error getting password\n");
+        goto end;
+    }
+
+    if (outfile) {
+        if (!(out = BIO_new_file(outfile, "wb"))) {
+            BIO_printf(bio_err, "Can't open output file %s\n", outfile);
+            goto end;
+        }
+    } else {
+        out = BIO_new_fp(stdout, BIO_NOCLOSE);
 #ifdef OPENSSL_SYS_VMS
-                       {
-                       BIO *tmpbio = BIO_new(BIO_f_linebuffer());
-                       out = BIO_push(tmpbio, out);
-                       }
+        {
+            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+            out = BIO_push(tmpbio, out);
+        }
 #endif
-               }
-
-       EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
-       EVP_PKEY_CTX_set_app_data(ctx, bio_err);
-
-       if (do_param)
-               {
-               if (EVP_PKEY_paramgen(ctx, &pkey) <= 0)
-                       {
-                       BIO_puts(bio_err, "Error generating parameters\n");
-                       ERR_print_errors(bio_err);
-                       goto end;
-                       }
-               }
-       else
-               {
-               if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
-                       {
-                       BIO_puts(bio_err, "Error generating key\n");
-                       ERR_print_errors(bio_err);
-                       goto end;
-                       }
-               }
-
-       if (do_param)
-               rv = PEM_write_bio_Parameters(out, pkey);
-       else if (outformat == FORMAT_PEM) 
-               rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
-                                                               NULL, pass);
-       else if (outformat == FORMAT_ASN1)
-               rv = i2d_PrivateKey_bio(out, pkey);
-       else
-               {
-               BIO_printf(bio_err, "Bad format specified for key\n");
-               goto end;
-               }
-
-       if (rv <= 0)
-               {
-               BIO_puts(bio_err, "Error writing key\n");
-               ERR_print_errors(bio_err);
-               }
-
-       if (text)
-               {
-               if (do_param)
-                       rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
-               else
-                       rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
-
-               if (rv <= 0)
-                       {
-                       BIO_puts(bio_err, "Error printing key\n");
-                       ERR_print_errors(bio_err);
-                       }
-               }
-
-       ret = 0;
-
-       end:
-       if (pkey)
-               EVP_PKEY_free(pkey);
-       if (ctx)
-               EVP_PKEY_CTX_free(ctx);
-       if (out)
-               BIO_free_all(out);
-       BIO_free(in);
-       if (pass)
-               OPENSSL_free(pass);
-
-       return ret;
-       }
+    }
+
+    EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+    EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+    if (do_param) {
+        if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
+            BIO_puts(bio_err, "Error generating parameters\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    } else {
+        if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
+            BIO_puts(bio_err, "Error generating key\n");
+            ERR_print_errors(bio_err);
+            goto end;
+        }
+    }
+
+    if (do_param)
+        rv = PEM_write_bio_Parameters(out, pkey);
+    else if (outformat == FORMAT_PEM)
+        rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0, NULL, pass);
+    else if (outformat == FORMAT_ASN1)
+        rv = i2d_PrivateKey_bio(out, pkey);
+    else {
+        BIO_printf(bio_err, "Bad format specified for key\n");
+        goto end;
+    }
+
+    if (rv <= 0) {
+        BIO_puts(bio_err, "Error writing key\n");
+        ERR_print_errors(bio_err);
+    }
+
+    if (text) {
+        if (do_param)
+            rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
+        else
+            rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+        if (rv <= 0) {
+            BIO_puts(bio_err, "Error printing key\n");
+            ERR_print_errors(bio_err);
+        }
+    }
+
+    ret = 0;
+
+ end:
+    if (pkey)
+        EVP_PKEY_free(pkey);
+    if (ctx)
+        EVP_PKEY_CTX_free(ctx);
+    if (out)
+        BIO_free_all(out);
+    BIO_free(in);
+    if (pass)
+        OPENSSL_free(pass);
+
+    return ret;
+}
 
 static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
-                               const char *file, ENGINE *e)
-       {
-       BIO *pbio;
-       EVP_PKEY *pkey = NULL;
-       EVP_PKEY_CTX *ctx = NULL;
-       if (*pctx)
-               {
-               BIO_puts(err, "Parameters already set!\n");
-               return 0;
-               }
-
-       pbio = BIO_new_file(file, "r");
-       if (!pbio)
-               {
-               BIO_printf(err, "Can't open parameter file %s\n", file);
-               return 0;
-               }
-
-       pkey = PEM_read_bio_Parameters(pbio, NULL);
-       BIO_free(pbio);
-
-       if (!pkey)
-               {
-               BIO_printf(bio_err, "Error reading parameter file %s\n", file);
-               return 0;
-               }
-
-       ctx = EVP_PKEY_CTX_new(pkey, e);
-       if (!ctx)
-               goto err;
-       if (EVP_PKEY_keygen_init(ctx) <= 0)
-               goto err;
-       EVP_PKEY_free(pkey);
-       *pctx = ctx;
-       return 1;
-
-       err:
-       BIO_puts(err, "Error initializing context\n");
-       ERR_print_errors(err);
-       if (ctx)
-               EVP_PKEY_CTX_free(ctx);
-       if (pkey)
-               EVP_PKEY_free(pkey);
-       return 0;
-
-       }
-
-static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
-                               const char *algname, ENGINE *e, int do_param)
-       {
-       EVP_PKEY_CTX *ctx = NULL;
-       const EVP_PKEY_ASN1_METHOD *ameth;
-       ENGINE *tmpeng = NULL;
-       int pkey_id;
-
-       if (*pctx)
-               {
-               BIO_puts(err, "Algorithm already set!\n");
-               return 0;
-               }
-       ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
-
-       if (!ameth)
-               {
-               BIO_printf(bio_err, "Algorithm %s not found\n", algname);
-               return 0;
-               }
-
-       EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+                            const char *file, ENGINE *e)
+{
+    BIO *pbio;
+    EVP_PKEY *pkey = NULL;
+    EVP_PKEY_CTX *ctx = NULL;
+    if (*pctx) {
+        BIO_puts(err, "Parameters already set!\n");
+        return 0;
+    }
+
+    pbio = BIO_new_file(file, "r");
+    if (!pbio) {
+        BIO_printf(err, "Can't open parameter file %s\n", file);
+        return 0;
+    }
+
+    pkey = PEM_read_bio_Parameters(pbio, NULL);
+    BIO_free(pbio);
+
+    if (!pkey) {
+        BIO_printf(bio_err, "Error reading parameter file %s\n", file);
+        return 0;
+    }
+
+    ctx = EVP_PKEY_CTX_new(pkey, e);
+    if (!ctx)
+        goto err;
+    if (EVP_PKEY_keygen_init(ctx) <= 0)
+        goto err;
+    EVP_PKEY_free(pkey);
+    *pctx = ctx;
+    return 1;
+
+ err:
+    BIO_puts(err, "Error initializing context\n");
+    ERR_print_errors(err);
+    if (ctx)
+        EVP_PKEY_CTX_free(ctx);
+    if (pkey)
+        EVP_PKEY_free(pkey);
+    return 0;
+
+}
+
+int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
+                 const char *algname, ENGINE *e, int do_param)
+{
+    EVP_PKEY_CTX *ctx = NULL;
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    ENGINE *tmpeng = NULL;
+    int pkey_id;
+
+    if (*pctx) {
+        BIO_puts(err, "Algorithm already set!\n");
+        return 0;
+    }
+
+    ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
+
+#ifndef OPENSSL_NO_ENGINE
+    if (!ameth && e)
+        ameth = ENGINE_get_pkey_asn1_meth_str(e, algname, -1);
+#endif
+
+    if (!ameth) {
+        BIO_printf(bio_err, "Algorithm %s not found\n", algname);
+        return 0;
+    }
+
+    ERR_clear_error();
+
+    EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
 #ifndef OPENSSL_NO_ENGINE
-       if (tmpeng)
-               ENGINE_finish(tmpeng);
+    if (tmpeng)
+        ENGINE_finish(tmpeng);
 #endif
-       ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
-
-       if (!ctx)
-               goto err;
-       if (do_param)
-               {
-               if (EVP_PKEY_paramgen_init(ctx) <= 0)
-                       goto err;
-               }
-       else
-               {
-               if (EVP_PKEY_keygen_init(ctx) <= 0)
-                       goto err;
-               }
-
-       *pctx = ctx;
-       return 1;
-
-       err:
-       BIO_printf(err, "Error initializing %s context\n", algname);
-       ERR_print_errors(err);
-       if (ctx)
-               EVP_PKEY_CTX_free(ctx);
-       return 0;
-
-       }
+    ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
+
+    if (!ctx)
+        goto err;
+    if (do_param) {
+        if (EVP_PKEY_paramgen_init(ctx) <= 0)
+            goto err;
+    } else {
+        if (EVP_PKEY_keygen_init(ctx) <= 0)
+            goto err;
+    }
+
+    *pctx = ctx;
+    return 1;
+
+ err:
+    BIO_printf(err, "Error initializing %s context\n", algname);
+    ERR_print_errors(err);
+    if (ctx)
+        EVP_PKEY_CTX_free(ctx);
+    return 0;
+
+}
 
 static int genpkey_cb(EVP_PKEY_CTX *ctx)
-       {
-       char c='*';
-       BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
-       int p;
-       p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
-       if (p == 0) c='.';
-       if (p == 1) c='+';
-       if (p == 2) c='*';
-       if (p == 3) c='\n';
-       BIO_write(b,&c,1);
-       (void)BIO_flush(b);
+{
+    char c = '*';
+    BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
+    int p;
+    p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
+    if (p == 0)
+        c = '.';
+    if (p == 1)
+        c = '+';
+    if (p == 2)
+        c = '*';
+    if (p == 3)
+        c = '\n';
+    BIO_write(b, &c, 1);
+    (void)BIO_flush(b);
 #ifdef LINT
-       p=n;
+    p = n;
 #endif
-       return 1;
-       }
+    return 1;
+}