Fix free errors in ocsp utility.
[openssl.git] / apps / genpkey.c
index 9a58b64e9299083755aff35332a37fcb750b2c02..6dfda08b9e09f2d7ca3e4bea10f3ce27e8ffebeb 100644 (file)
@@ -1,5 +1,5 @@
 /* apps/genpkey.c */
 /* apps/genpkey.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006
  */
 /* ====================================================================
  * project 2006
  */
 /* ====================================================================
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#ifndef OPENSSL_NO_ENGINE
+#include <openssl/engine.h>
+#endif
 
 static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
                                const char *file, ENGINE *e);
 
 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);
 static int genpkey_cb(EVP_PKEY_CTX *ctx);
 
 #define PROG genpkey_main
 static int genpkey_cb(EVP_PKEY_CTX *ctx);
 
 #define PROG genpkey_main
@@ -85,7 +86,7 @@ int MAIN(int argc, char **argv)
        EVP_PKEY_CTX *ctx = NULL;
        char *pass = NULL;
        int badarg = 0;
        EVP_PKEY_CTX *ctx = NULL;
        char *pass = NULL;
        int badarg = 0;
-       int ret = 1;
+       int ret = 1, rv;
 
        int do_param = 0;
 
 
        int do_param = 0;
 
@@ -150,7 +151,7 @@ int MAIN(int argc, char **argv)
                        if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
                                goto end;
                        }
                        if (!init_gen_str(bio_err, &ctx, *(++args),e, do_param))
                                goto end;
                        }
-               else if (strcmp(*args,"-param") == 0)
+               else if (strcmp(*args,"-pkeyopt") == 0)
                        {
                        if (!args[1])
                                goto bad;
                        {
                        if (!args[1])
                                goto bad;
@@ -195,16 +196,23 @@ int MAIN(int argc, char **argv)
        if (badarg)
                {
                bad:
        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");
+               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
 #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
 #endif
-               return 1;
+               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))
                }
 
        if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
@@ -256,25 +264,36 @@ int MAIN(int argc, char **argv)
                }
 
        if (do_param)
                }
 
        if (do_param)
-               PEM_write_bio_Parameters(out, pkey);
+               rv = PEM_write_bio_Parameters(out, pkey);
        else if (outformat == FORMAT_PEM) 
        else if (outformat == FORMAT_PEM) 
-               PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
+               rv = PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
                                                                NULL, pass);
        else if (outformat == FORMAT_ASN1)
                                                                NULL, pass);
        else if (outformat == FORMAT_ASN1)
-               i2d_PrivateKey_bio(out, pkey);
+               rv = i2d_PrivateKey_bio(out, pkey);
        else
                {
                BIO_printf(bio_err, "Bad format specified for key\n");
                goto end;
                }
 
        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)
 
        if (text)
                {
                if (do_param)
-                       EVP_PKEY_print_params(out, pkey, 0, NULL);
+                       rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
                else
                else
-                       EVP_PKEY_print_private(out, pkey, 0, NULL);
+                       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;
                }
 
        ret = 0;
@@ -341,26 +360,40 @@ static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
 
        }
 
 
        }
 
-static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
-                               const char *algname, ENGINE *e, int do_param)
+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;
        {
        EVP_PKEY_CTX *ctx = NULL;
        const EVP_PKEY_ASN1_METHOD *ameth;
+       ENGINE *tmpeng = NULL;
        int pkey_id;
        int pkey_id;
+
        if (*pctx)
                {
                BIO_puts(err, "Algorithm already set!\n");
                return 0;
                }
 
        if (*pctx)
                {
                BIO_puts(err, "Algorithm already set!\n");
                return 0;
                }
 
-       ameth = EVP_PKEY_asn1_find_str(algname, -1);
+       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;
                }
 
        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);
        EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
+#ifndef OPENSSL_NO_ENGINE
+       if (tmpeng)
+               ENGINE_finish(tmpeng);
+#endif
        ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
 
        if (!ctx)
        ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
 
        if (!ctx)