summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-04-11 13:28:52 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-04-11 13:28:52 +0000
commitf5cda4cbb17c908ceef33f4f52d94e8e04b7c1ab (patch)
tree851abcd3b7178040056cbb1ce397bbc526774041 /apps
parentf9a6348a537290f65fd76d945419a4c9bafff012 (diff)
Initial keygen support.
Diffstat (limited to 'apps')
-rw-r--r--apps/Makefile6
-rw-r--r--apps/genpkey.c375
-rw-r--r--apps/pkeyutl.c2
-rw-r--r--apps/progs.h2
4 files changed, 381 insertions, 4 deletions
diff --git a/apps/Makefile b/apps/Makefile
index 79f8e5772e..eca57d2a3c 100644
--- a/apps/Makefile
+++ b/apps/Makefile
@@ -37,7 +37,7 @@ EXE= $(PROGRAM)$(EXE_EXT)
E_EXE= verify asn1pars req dgst dh dhparam enc passwd gendh errstr \
ca crl rsa rsautl dsa dsaparam ec ecparam \
- x509 genrsa gendsa s_server s_client speed \
+ x509 genrsa gendsa genpkey s_server s_client speed \
s_time version pkcs7 crl2pkcs7 sess_id ciphers nseq pkcs12 \
pkcs8 pkey pkeyparam pkeyutl spkac smime rand engine ocsp prime ts
@@ -53,7 +53,7 @@ RAND_SRC=app_rand.c
E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o errstr.o \
ca.o pkcs7.o crl2p7.o crl.o \
rsa.o rsautl.o dsa.o dsaparam.o ec.o ecparam.o \
- x509.o genrsa.o gendsa.o s_server.o s_client.o speed.o \
+ x509.o genrsa.o gendsa.o genpkey.o s_server.o s_client.o speed.o \
s_time.o $(A_OBJ) $(S_OBJ) $(RAND_OBJ) version.o sess_id.o \
ciphers.o nseq.o pkcs12.o pkcs8.o pkey.o pkeyparam.o pkeyutl.o \
spkac.o smime.o rand.o engine.o ocsp.o prime.o ts.o
@@ -61,7 +61,7 @@ E_OBJ= verify.o asn1pars.o req.o dgst.o dh.o dhparam.o enc.o passwd.o gendh.o er
E_SRC= verify.c asn1pars.c req.c dgst.c dh.c enc.c passwd.c gendh.c errstr.c ca.c \
pkcs7.c crl2p7.c crl.c \
rsa.c rsautl.c dsa.c dsaparam.c ec.c ecparam.c \
- x509.c genrsa.c gendsa.c s_server.c s_client.c speed.c \
+ x509.c genrsa.c gendsa.c genpkey.c s_server.c s_client.c speed.c \
s_time.c $(A_SRC) $(S_SRC) $(RAND_SRC) version.c sess_id.c \
ciphers.c nseq.c pkcs12.c pkcs8.c pkey.c pkeyparam.c pkeyutl.c \
spkac.c smime.c rand.c engine.c ocsp.c prime.c ts.c
diff --git a/apps/genpkey.c b/apps/genpkey.c
new file mode 100644
index 0000000000..b0c06f0240
--- /dev/null
+++ b/apps/genpkey.c
@@ -0,0 +1,375 @@
+/* apps/genpkey.c */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2006
+ */
+/* ====================================================================
+ * Copyright (c) 2006 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * 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
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#include <stdio.h>
+#include <string.h>
+#include "apps.h"
+#include <openssl/pem.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+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
+
+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;
+
+ 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);
+ }
+#endif
+ else if (!strcmp (*args, "-paramfile"))
+ {
+ if (!args[1])
+ goto bad;
+ args++;
+ 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, 0))
+ goto end;
+ }
+ else if (strcmp(*args,"-param") == 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,"-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;
+ }
+ }
+ 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");
+#ifndef OPENSSL_NO_ENGINE
+ BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
+#endif
+ return 1;
+ }
+
+ 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);
+ }
+#endif
+ }
+
+ EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
+ EVP_PKEY_CTX_set_app_data(ctx, bio_err);
+
+ if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
+ {
+ BIO_puts(bio_err, "Error generating key\n");
+ goto end;
+ }
+
+ if (outformat == FORMAT_PEM)
+ PEM_write_bio_PrivateKey(out, pkey, cipher, NULL, 0,
+ NULL, pass);
+ else if (outformat == FORMAT_ASN1)
+ i2d_PrivateKey_bio(out, pkey);
+ else
+ {
+ BIO_printf(bio_err, "Bad format specified for key\n");
+ goto end;
+ }
+
+
+ if (text)
+ EVP_PKEY_print_private(out, pkey, 0, NULL);
+
+ 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;
+ int pkey_id;
+ if (*pctx)
+ {
+ BIO_puts(err, "Algorithm already set!\n");
+ return 0;
+ }
+
+ ameth = EVP_PKEY_asn1_find_str(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);
+ 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);
+#ifdef LINT
+ p=n;
+#endif
+ return 1;
+ }
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 82b59a805c..1ecde3cd85 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -435,7 +435,7 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
if (!pkey)
goto end;
- ctx = EVP_PKEY_CTX_new(pkey);
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
EVP_PKEY_free(pkey);
diff --git a/apps/progs.h b/apps/progs.h
index d5b5995c3f..3458b11c16 100644
--- a/apps/progs.h
+++ b/apps/progs.h
@@ -22,6 +22,7 @@ extern int ecparam_main(int argc,char *argv[]);
extern int x509_main(int argc,char *argv[]);
extern int genrsa_main(int argc,char *argv[]);
extern int gendsa_main(int argc,char *argv[]);
+extern int genpkey_main(int argc,char *argv[]);
extern int s_server_main(int argc,char *argv[]);
extern int s_client_main(int argc,char *argv[]);
extern int speed_main(int argc,char *argv[]);
@@ -100,6 +101,7 @@ FUNCTION functions[] = {
#ifndef OPENSSL_NO_DSA
{FUNC_TYPE_GENERAL,"gendsa",gendsa_main},
#endif
+ {FUNC_TYPE_GENERAL,"genpkey",genpkey_main},
#if !defined(OPENSSL_NO_SOCK) && !(defined(OPENSSL_NO_SSL2) && defined(OPENSSL_NO_SSL3))
{FUNC_TYPE_GENERAL,"s_server",s_server_main},
#endif