Skip to content

Commit

Permalink
Complete EVP_PKEY_ASN1_METHOD ENGINE support.
Browse files Browse the repository at this point in the history
  • Loading branch information
snhenson committed Jun 5, 2006
1 parent 8fecd4b commit 01b8b3c
Show file tree
Hide file tree
Showing 18 changed files with 359 additions and 128 deletions.
4 changes: 3 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]

*) Initial engine support for EVP_PKEY_ASN1_METHOD.
*) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process
an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code.
[Steve Henson]

*) Initial engine support for EVP_PKEY_METHOD. New functions to permit
an engine to register a method. Add ENGINE lookups for methods and
Expand Down
36 changes: 28 additions & 8 deletions apps/genpkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
#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);
Expand All @@ -85,7 +88,7 @@ int MAIN(int argc, char **argv)
EVP_PKEY_CTX *ctx = NULL;
char *pass = NULL;
int badarg = 0;
int ret = 1;
int ret = 1, rv;

int do_param = 0;

Expand Down Expand Up @@ -204,7 +207,7 @@ int MAIN(int argc, char **argv)
#ifndef OPENSSL_NO_ENGINE
BIO_printf(bio_err, "-engine e use engine e, possibly a hardware device.\n");
#endif
return 1;
goto end;
}

if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
Expand Down Expand Up @@ -256,25 +259,36 @@ int MAIN(int argc, char **argv)
}

if (do_param)
PEM_write_bio_Parameters(out, pkey);
rv = PEM_write_bio_Parameters(out, pkey);
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)
i2d_PrivateKey_bio(out, pkey);
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)
EVP_PKEY_print_params(out, pkey, 0, NULL);
rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
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;
Expand Down Expand Up @@ -346,21 +360,27 @@ static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
{
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);

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);
#ifndef OPENSSL_NO_ENGINE
if (tmpeng)
ENGINE_finish(tmpeng);
#endif
ctx = EVP_PKEY_CTX_new_id(pkey_id, e);

if (!ctx)
Expand Down
73 changes: 46 additions & 27 deletions apps/req.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx);
static int req_check_len(int len,int n_min,int n_max);
static int check_end(const char *str, const char *end);
static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
long *pkeylen, const char **palgnam,
ENGINE *e);
long *pkeylen, char **palgnam,
ENGINE *keygen_engine);
#ifndef MONOLITH
static char *default_config_file=NULL;
#endif
Expand All @@ -157,19 +157,14 @@ int MAIN(int, char **);

int MAIN(int argc, char **argv)
{
ENGINE *e = NULL;
#ifndef OPENSSL_NO_DSA
DSA *dsa_params=NULL;
#endif
#ifndef OPENSSL_NO_ECDSA
EC_KEY *ec_params = NULL;
#endif
ENGINE *e = NULL, *gen_eng = NULL;
unsigned long nmflag = 0, reqflag = 0;
int ex=1,x509=0,days=30;
X509 *x509ss=NULL;
X509_REQ *req=NULL;
EVP_PKEY_CTX *genctx = NULL;
const char *keyalg = NULL, *keyalgstr;
const char *keyalg = NULL;
char *keyalgstr = NULL;
STACK *pkeyopts = NULL;
EVP_PKEY *pkey=NULL;
int i=0,badops=0,newreq=0,verbose=0,pkey_type=EVP_PKEY_RSA;
Expand Down Expand Up @@ -235,6 +230,16 @@ int MAIN(int argc, char **argv)
if (--argc < 1) goto bad;
engine= *(++argv);
}
else if (strcmp(*argv,"-keygen_engine") == 0)
{
if (--argc < 1) goto bad;
gen_eng = ENGINE_by_id(*(++argv));
if (gen_eng == NULL)
{
BIO_printf(bio_err, "Can't find keygen engine %s\n", *argv);
goto end;
}
}
#endif
else if (strcmp(*argv,"-key") == 0)
{
Expand Down Expand Up @@ -634,7 +639,7 @@ int MAIN(int argc, char **argv)
if (keyalg)
{
genctx = set_keygen_ctx(bio_err, keyalg, &newkey,
&keyalgstr, e);
&keyalgstr, gen_eng);
if (!genctx)
goto end;
}
Expand All @@ -655,7 +660,7 @@ int MAIN(int argc, char **argv)
if (!genctx)
{
genctx = set_keygen_ctx(bio_err, NULL, &newkey,
&keyalgstr, e);
&keyalgstr, gen_eng);
if (!genctx)
goto end;
}
Expand Down Expand Up @@ -1080,18 +1085,18 @@ int MAIN(int argc, char **argv)
EVP_PKEY_CTX_free(genctx);
if (pkeyopts)
sk_free(pkeyopts);
#ifndef OPENSSL_NO_ENGINE
if (gen_eng)
ENGINE_free(gen_eng);
#endif
if (keyalgstr)
OPENSSL_free(keyalgstr);
X509_REQ_free(req);
X509_free(x509ss);
ASN1_INTEGER_free(serial);
if(passargin && passin) OPENSSL_free(passin);
if(passargout && passout) OPENSSL_free(passout);
OBJ_cleanup();
#ifndef OPENSSL_NO_DSA
if (dsa_params != NULL) DSA_free(dsa_params);
#endif
#ifndef OPENSSL_NO_ECDSA
if (ec_params != NULL) EC_KEY_free(ec_params);
#endif
apps_shutdown();
OPENSSL_EXIT(ex);
}
Expand Down Expand Up @@ -1566,8 +1571,8 @@ static int check_end(const char *str, const char *end)
}

static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
long *pkeylen, const char **palgnam,
ENGINE *e)
long *pkeylen, char **palgnam,
ENGINE *keygen_engine)
{
EVP_PKEY_CTX *gctx = NULL;
EVP_PKEY *param = NULL;
Expand All @@ -1593,14 +1598,18 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
{
const char *p = strchr(gstr, ':');
int len;
ENGINE *tmpeng;
const EVP_PKEY_ASN1_METHOD *ameth;

if (p)
len = p - gstr;
else
len = strlen(gstr);
/* The lookup of a the string will cover all engines so
* keep a note of the implementation.
*/

ameth = EVP_PKEY_asn1_find_str(gstr, len);
ameth = EVP_PKEY_asn1_find_str(&tmpeng, gstr, len);

if (!ameth)
{
Expand All @@ -1609,7 +1618,11 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
}

EVP_PKEY_asn1_get0_info(NULL, &pkey_type, NULL, NULL, NULL,
ameth);
ameth);
#ifndef OPENSSL_NO_ENGINE
if (tmpeng)
ENGINE_finish(tmpeng);
#endif
if (pkey_type == EVP_PKEY_RSA)
{
if (p)
Expand Down Expand Up @@ -1666,24 +1679,30 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
if (palgnam)
{
const EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_asn1_find(pkey_type);
ENGINE *tmpeng;
const char *anam;
ameth = EVP_PKEY_asn1_find(&tmpeng, pkey_type);
if (!ameth)
{
BIO_puts(err, "Internal error: can't find key algorithm\n");
return NULL;
}
EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, palgnam,
ameth);
EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
*palgnam = BUF_strdup(anam);
#ifndef OPENSSL_NO_ENGINE
if (tmpeng)
ENGINE_finish(tmpeng);
#endif
}

if (param)
{
gctx = EVP_PKEY_CTX_new(param, e);
gctx = EVP_PKEY_CTX_new(param, keygen_engine);
*pkeylen = EVP_PKEY_bits(param);
EVP_PKEY_free(param);
}
else
gctx = EVP_PKEY_CTX_new_id(pkey_type, e);
gctx = EVP_PKEY_CTX_new_id(pkey_type, keygen_engine);

if (!gctx)
{
Expand Down
67 changes: 62 additions & 5 deletions crypto/asn1/ameth_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@
#include "cryptlib.h"
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/ec.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_locl.h"

extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
Expand Down Expand Up @@ -132,7 +134,7 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
return (const EVP_PKEY_ASN1_METHOD *)sk_value(app_methods, idx);
}

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type)
static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
{
EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret;
tmp.pkey_id = type;
Expand All @@ -151,17 +153,72 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type)
(int (*)(const void *, const void *))ameth_cmp);
if (!ret || !*ret)
return NULL;
if ((*ret)->pkey_flags & ASN1_PKEY_ALIAS)
return EVP_PKEY_asn1_find((*ret)->pkey_base_id);
return *ret;
}

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len)
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
* also search through engines and set *pe to a functional reference
* to the engine implementing 'type' or NULL if no engine implements
* it.
*/

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
{
const EVP_PKEY_ASN1_METHOD *t;
ENGINE *e;

for (;;)
{
t = pkey_asn1_find(type);
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
break;
type = t->pkey_base_id;
}
if (pe)
{
#ifndef OPENSSL_NO_ENGINE
/* type will contain the final unaliased type */
e = ENGINE_get_pkey_asn1_meth_engine(type);
if (e)
{
*pe = e;
return ENGINE_get_pkey_asn1_meth(e, type);
}
#endif
*pe = NULL;
}
return t;
}

const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
const char *str, int len)
{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
if (len == -1)
len = strlen(str);
if (pe)
{
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
{
ameth = ENGINE_get_pkey_asn1_meth_str(e, str, len);
if (ameth)
{
/* Convert structural into
* functional reference
*/
if (!ENGINE_init(e))
ameth = NULL;
ENGINE_free(e);
*pe = e;
return ameth;
}
}
#endif
*pe = NULL;
}
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
{
ameth = EVP_PKEY_asn1_get0(i);
Expand Down

0 comments on commit 01b8b3c

Please sign in to comment.