Initial keygen support.
This commit is contained in:
parent
f9a6348a53
commit
f5cda4cbb1
8
CHANGES
8
CHANGES
@ -4,6 +4,12 @@
|
||||
|
||||
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) New utility "genpkey" this is analagous to "genrsa" etc except it can
|
||||
generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to
|
||||
support key and parameter generation and add initial key generation
|
||||
functionality for RSA.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add functions for main EVP_PKEY_method operations. The undocumented
|
||||
functions EVP_PKEY_{encrypt,decrypt} have been renamed to
|
||||
EVP_PKEY_{encrypt,decrypt}_old.
|
||||
@ -27,7 +33,7 @@
|
||||
[Steve Henson]
|
||||
|
||||
*) New utilities pkey and pkeyparam. These are similar to algorithm specific
|
||||
utilities such as rsa, dsa, dsaparam etc except they processes any key
|
||||
utilities such as rsa, dsa, dsaparam etc except they process any key
|
||||
type.
|
||||
[Steve Henson]
|
||||
|
||||
|
@ -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
|
||||
|
375
apps/genpkey.c
Normal file
375
apps/genpkey.c
Normal file
@ -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;
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -160,6 +160,8 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len)
|
||||
{
|
||||
int i;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (len == -1)
|
||||
len = strlen(str);
|
||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
|
||||
{
|
||||
ameth = EVP_PKEY_asn1_get0(i);
|
||||
|
@ -28,7 +28,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c \
|
||||
bio_md.c bio_b64.c bio_enc.c evp_err.c e_null.c \
|
||||
c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
|
||||
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
|
||||
e_old.c pmeth_lib.c pmeth_fn.c
|
||||
e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c
|
||||
|
||||
LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
|
||||
e_des.o e_bf.o e_idea.o e_des3.o \
|
||||
@ -40,7 +40,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o \
|
||||
bio_md.o bio_b64.o bio_enc.o evp_err.o e_null.o \
|
||||
c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
|
||||
evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
|
||||
e_old.o pmeth_lib.o pmeth_fn.o
|
||||
e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o
|
||||
|
||||
SRC= $(LIBSRC)
|
||||
|
||||
|
@ -937,7 +937,8 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
#define EVP_PKEY_ALG_CTRL 0x1000
|
||||
|
||||
const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type, ENGINE *e);
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey);
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
|
||||
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
|
||||
|
||||
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
@ -945,6 +946,10 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
|
||||
int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type,
|
||||
const char *value);
|
||||
|
||||
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data);
|
||||
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx);
|
||||
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data);
|
||||
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
|
||||
|
||||
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx);
|
||||
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
|
||||
@ -967,6 +972,16 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
||||
unsigned char *out, int *outlen,
|
||||
const unsigned char *in, int inlen);
|
||||
|
||||
typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
|
||||
|
||||
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
|
||||
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
|
||||
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
|
||||
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
|
||||
|
||||
void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
|
||||
int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx);
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
/* The following lines are auto generated by the script mkerr.pl. Any changes
|
||||
* made after this point may be overwritten when the script is next run.
|
||||
@ -1006,7 +1021,11 @@ void ERR_load_EVP_strings(void);
|
||||
#define EVP_F_EVP_PKEY_GET1_ECDSA 130
|
||||
#define EVP_F_EVP_PKEY_GET1_EC_KEY 131
|
||||
#define EVP_F_EVP_PKEY_GET1_RSA 121
|
||||
#define EVP_F_EVP_PKEY_KEYGEN 146
|
||||
#define EVP_F_EVP_PKEY_KEYGEN_INIT 147
|
||||
#define EVP_F_EVP_PKEY_NEW 106
|
||||
#define EVP_F_EVP_PKEY_PARAMGEN 148
|
||||
#define EVP_F_EVP_PKEY_PARAMGEN_INIT 149
|
||||
#define EVP_F_EVP_PKEY_SIGN 140
|
||||
#define EVP_F_EVP_PKEY_SIGN_INIT 141
|
||||
#define EVP_F_EVP_PKEY_VERIFY 142
|
||||
|
@ -100,7 +100,11 @@ static ERR_STRING_DATA EVP_str_functs[]=
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_KEYGEN"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_KEYGEN_INIT"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_PARAMGEN"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_PARAMGEN_INIT"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"},
|
||||
{ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"},
|
||||
|
@ -235,7 +235,6 @@ const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; }
|
||||
EVP_CIPHER_get_asn1_iv, \
|
||||
NULL)
|
||||
|
||||
|
||||
struct evp_pkey_ctx_st
|
||||
{
|
||||
/* Method associated with this operation */
|
||||
@ -246,6 +245,13 @@ struct evp_pkey_ctx_st
|
||||
int operation;
|
||||
/* Algorithm specific data */
|
||||
void *data;
|
||||
/* Application specific data */
|
||||
void *app_data;
|
||||
/* Keygen callback */
|
||||
EVP_PKEY_gen_cb *pkey_gencb;
|
||||
/* implementation specific keygen data */
|
||||
int *keygen_info;
|
||||
int keygen_info_count;
|
||||
} /* EVP_PKEY_CTX */;
|
||||
|
||||
struct evp_pkey_method_st
|
||||
@ -257,10 +263,10 @@ struct evp_pkey_method_st
|
||||
void (*cleanup)(EVP_PKEY_CTX *ctx);
|
||||
|
||||
int (*paramgen_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*paramgen)(EVP_PKEY_CTX *ctx);
|
||||
int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
|
||||
|
||||
int (*keygen_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*keygen)(EVP_PKEY_CTX *ctx);
|
||||
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
|
||||
|
||||
int (*sign_init)(EVP_PKEY_CTX *ctx);
|
||||
int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, int *siglen,
|
||||
@ -296,3 +302,5 @@ struct evp_pkey_method_st
|
||||
|
||||
|
||||
} /* EVP_PKEY_METHOD */;
|
||||
|
||||
void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx);
|
||||
|
193
crypto/evp/pmeth_gn.c
Normal file
193
crypto/evp/pmeth_gn.c
Normal file
@ -0,0 +1,193 @@
|
||||
/* pmeth_gn.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 <stdlib.h>
|
||||
#include <openssl/objects.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/evp.h>
|
||||
#include "evp_locl.h"
|
||||
|
||||
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_PARAMGEN;
|
||||
if (!ctx->pmeth->paramgen_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->paramgen_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (ctx->operation != EVP_PKEY_OP_PARAMGEN)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ppkey)
|
||||
return -1;
|
||||
|
||||
if (!*ppkey)
|
||||
*ppkey = EVP_PKEY_new();
|
||||
|
||||
ret = ctx->pmeth->paramgen(ctx, *ppkey);
|
||||
if (ret <= 0)
|
||||
{
|
||||
EVP_PKEY_free(*ppkey);
|
||||
*ppkey = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
int ret;
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
ctx->operation = EVP_PKEY_OP_KEYGEN;
|
||||
if (!ctx->pmeth->keygen_init)
|
||||
return 1;
|
||||
ret = ctx->pmeth->keygen_init(ctx);
|
||||
if (ret <= 0)
|
||||
ctx->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN,
|
||||
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
}
|
||||
if (ctx->operation != EVP_PKEY_OP_KEYGEN)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ppkey)
|
||||
return -1;
|
||||
|
||||
if (!*ppkey)
|
||||
*ppkey = EVP_PKEY_new();
|
||||
|
||||
ret = ctx->pmeth->keygen(ctx, *ppkey);
|
||||
if (ret <= 0)
|
||||
{
|
||||
EVP_PKEY_free(*ppkey);
|
||||
*ppkey = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb)
|
||||
{
|
||||
ctx->pkey_gencb = cb;
|
||||
}
|
||||
|
||||
/* "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB
|
||||
* style callbacks.
|
||||
*/
|
||||
|
||||
static int trans_cb(int a, int b, BN_GENCB *gcb)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx = gcb->arg;
|
||||
ctx->keygen_info[0] = a;
|
||||
ctx->keygen_info[1] = b;
|
||||
return ctx->pkey_gencb(ctx);
|
||||
}
|
||||
|
||||
void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
BN_GENCB_set(cb, trans_cb, ctx)
|
||||
}
|
||||
|
||||
int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx)
|
||||
{
|
||||
if (idx == -1)
|
||||
return ctx->keygen_info_count;
|
||||
if (idx < 0 || idx > ctx->keygen_info_count)
|
||||
return 0;
|
||||
return ctx->keygen_info[idx];
|
||||
}
|
@ -101,20 +101,25 @@ const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type, ENGINE *e)
|
||||
return *ret;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey)
|
||||
static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
||||
{
|
||||
EVP_PKEY_CTX *ret;
|
||||
const EVP_PKEY_METHOD *pmeth;
|
||||
if (!pkey || !pkey->ameth)
|
||||
return NULL;
|
||||
pmeth = EVP_PKEY_meth_find(pkey->ameth->pkey_id, NULL);
|
||||
if (id == -1)
|
||||
{
|
||||
if (!pkey || !pkey->ameth)
|
||||
return NULL;
|
||||
id = pkey->ameth->pkey_id;
|
||||
}
|
||||
pmeth = EVP_PKEY_meth_find(id, e);
|
||||
if (pmeth == NULL)
|
||||
return NULL;
|
||||
ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
|
||||
ret->pmeth = pmeth;
|
||||
ret->operation = EVP_PKEY_OP_UNDEFINED;
|
||||
CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
|
||||
ret->pkey = pkey;
|
||||
if (pkey)
|
||||
CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
|
||||
ret->data = NULL;
|
||||
|
||||
if (pmeth->init)
|
||||
@ -129,6 +134,16 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey)
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e)
|
||||
{
|
||||
return int_ctx_new(pkey, e, -1);
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e)
|
||||
{
|
||||
return int_ctx_new(NULL, e, id);
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
if (ctx->pmeth && ctx->pmeth->cleanup)
|
||||
@ -191,3 +206,23 @@ int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
}
|
||||
return ctx->pmeth->ctrl_str(ctx, name, value);
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data)
|
||||
{
|
||||
ctx->data = data;
|
||||
}
|
||||
|
||||
void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
return ctx->data;
|
||||
}
|
||||
|
||||
void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data)
|
||||
{
|
||||
ctx->app_data = data;
|
||||
}
|
||||
|
||||
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
return ctx->app_data;
|
||||
}
|
||||
|
@ -75,6 +75,8 @@ typedef struct
|
||||
/* Key gen parameters */
|
||||
int nbits;
|
||||
BIGNUM *pub_exp;
|
||||
/* Keygen callback info */
|
||||
int gentmp[2];
|
||||
/* RSA padding mode */
|
||||
int pad_mode;
|
||||
/* message digest */
|
||||
@ -100,6 +102,8 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx)
|
||||
rctx->saltlen = -2;
|
||||
|
||||
ctx->data = rctx;
|
||||
ctx->keygen_info = rctx->gentmp;
|
||||
ctx->keygen_info_count = 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -427,6 +431,36 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||
return -2;
|
||||
}
|
||||
|
||||
static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||
{
|
||||
RSA *rsa = NULL;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
BN_GENCB *pcb, cb;
|
||||
int ret;
|
||||
if (!rctx->pub_exp)
|
||||
{
|
||||
rctx->pub_exp = BN_new();
|
||||
if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4))
|
||||
return 0;
|
||||
}
|
||||
rsa = RSA_new();
|
||||
if (!rsa)
|
||||
return 0;
|
||||
if (ctx->pkey_gencb)
|
||||
{
|
||||
pcb = &cb;
|
||||
evp_pkey_set_cb_translate(pcb, ctx);
|
||||
}
|
||||
else
|
||||
pcb = NULL;
|
||||
ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb);
|
||||
if (ret > 0)
|
||||
EVP_PKEY_assign_RSA(pkey, rsa);
|
||||
else
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const EVP_PKEY_METHOD rsa_pkey_meth =
|
||||
{
|
||||
EVP_PKEY_RSA,
|
||||
@ -436,7 +470,8 @@ const EVP_PKEY_METHOD rsa_pkey_meth =
|
||||
|
||||
0,0,
|
||||
|
||||
0,0,
|
||||
0,
|
||||
pkey_rsa_keygen,
|
||||
|
||||
0,
|
||||
pkey_rsa_sign,
|
||||
|
Loading…
x
Reference in New Issue
Block a user