diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-04-11 13:28:52 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-04-11 13:28:52 +0000 |
commit | f5cda4cbb17c908ceef33f4f52d94e8e04b7c1ab (patch) | |
tree | 851abcd3b7178040056cbb1ce397bbc526774041 /apps | |
parent | f9a6348a537290f65fd76d945419a4c9bafff012 (diff) |
Initial keygen support.
Diffstat (limited to 'apps')
-rw-r--r-- | apps/Makefile | 6 | ||||
-rw-r--r-- | apps/genpkey.c | 375 | ||||
-rw-r--r-- | apps/pkeyutl.c | 2 | ||||
-rw-r--r-- | apps/progs.h | 2 |
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 |