Complete EVP_PKEY_ASN1_METHOD ENGINE support.
This commit is contained in:
parent
8fecd4b4f1
commit
01b8b3c7d2
4
CHANGES
4
CHANGES
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
|
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
|
*) Initial engine support for EVP_PKEY_METHOD. New functions to permit
|
||||||
an engine to register a method. Add ENGINE lookups for methods and
|
an engine to register a method. Add ENGINE lookups for methods and
|
||||||
|
@ -61,6 +61,9 @@
|
|||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/evp.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,
|
static int init_keygen_file(BIO *err, EVP_PKEY_CTX **pctx,
|
||||||
const char *file, ENGINE *e);
|
const char *file, ENGINE *e);
|
||||||
@ -85,7 +88,7 @@ int MAIN(int argc, char **argv)
|
|||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
char *pass = NULL;
|
char *pass = NULL;
|
||||||
int badarg = 0;
|
int badarg = 0;
|
||||||
int ret = 1;
|
int ret = 1, rv;
|
||||||
|
|
||||||
int do_param = 0;
|
int do_param = 0;
|
||||||
|
|
||||||
@ -204,7 +207,7 @@ int MAIN(int argc, char **argv)
|
|||||||
#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;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
|
if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
|
||||||
@ -256,25 +259,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);
|
NULL, pass);
|
||||||
else if (outformat == FORMAT_ASN1)
|
else if (outformat == FORMAT_ASN1)
|
||||||
i2d_PrivateKey_bio(out, pkey);
|
rv = i2d_PrivateKey_bio(out, pkey);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rv <= 0)
|
||||||
|
{
|
||||||
|
BIO_puts(bio_err, "Error writing key\n");
|
||||||
|
ERR_print_errors(bio_err);
|
||||||
|
}
|
||||||
|
|
||||||
if (text)
|
if (text)
|
||||||
{
|
{
|
||||||
if (do_param)
|
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;
|
||||||
@ -346,14 +360,16 @@ static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
|
|||||||
{
|
{
|
||||||
EVP_PKEY_CTX *ctx = NULL;
|
EVP_PKEY_CTX *ctx = NULL;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
|
ENGINE *tmpeng = NULL;
|
||||||
int pkey_id;
|
int pkey_id;
|
||||||
|
|
||||||
if (*pctx)
|
if (*pctx)
|
||||||
{
|
{
|
||||||
BIO_puts(err, "Algorithm already set!\n");
|
BIO_puts(err, "Algorithm already set!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
ameth = EVP_PKEY_asn1_find_str(&tmpeng, algname, -1);
|
||||||
|
|
||||||
ameth = EVP_PKEY_asn1_find_str(algname, -1);
|
|
||||||
if (!ameth)
|
if (!ameth)
|
||||||
{
|
{
|
||||||
BIO_printf(bio_err, "Algorithm %s not found\n", algname);
|
BIO_printf(bio_err, "Algorithm %s not found\n", algname);
|
||||||
@ -361,6 +377,10 @@ static int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
ctx = EVP_PKEY_CTX_new_id(pkey_id, e);
|
||||||
|
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
73
apps/req.c
73
apps/req.c
@ -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 req_check_len(int len,int n_min,int n_max);
|
||||||
static int check_end(const char *str, const char *end);
|
static int check_end(const char *str, const char *end);
|
||||||
static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
|
static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
|
||||||
long *pkeylen, const char **palgnam,
|
long *pkeylen, char **palgnam,
|
||||||
ENGINE *e);
|
ENGINE *keygen_engine);
|
||||||
#ifndef MONOLITH
|
#ifndef MONOLITH
|
||||||
static char *default_config_file=NULL;
|
static char *default_config_file=NULL;
|
||||||
#endif
|
#endif
|
||||||
@ -157,19 +157,14 @@ int MAIN(int, char **);
|
|||||||
|
|
||||||
int MAIN(int argc, char **argv)
|
int MAIN(int argc, char **argv)
|
||||||
{
|
{
|
||||||
ENGINE *e = NULL;
|
ENGINE *e = NULL, *gen_eng = NULL;
|
||||||
#ifndef OPENSSL_NO_DSA
|
|
||||||
DSA *dsa_params=NULL;
|
|
||||||
#endif
|
|
||||||
#ifndef OPENSSL_NO_ECDSA
|
|
||||||
EC_KEY *ec_params = NULL;
|
|
||||||
#endif
|
|
||||||
unsigned long nmflag = 0, reqflag = 0;
|
unsigned long nmflag = 0, reqflag = 0;
|
||||||
int ex=1,x509=0,days=30;
|
int ex=1,x509=0,days=30;
|
||||||
X509 *x509ss=NULL;
|
X509 *x509ss=NULL;
|
||||||
X509_REQ *req=NULL;
|
X509_REQ *req=NULL;
|
||||||
EVP_PKEY_CTX *genctx = NULL;
|
EVP_PKEY_CTX *genctx = NULL;
|
||||||
const char *keyalg = NULL, *keyalgstr;
|
const char *keyalg = NULL;
|
||||||
|
char *keyalgstr = NULL;
|
||||||
STACK *pkeyopts = NULL;
|
STACK *pkeyopts = NULL;
|
||||||
EVP_PKEY *pkey=NULL;
|
EVP_PKEY *pkey=NULL;
|
||||||
int i=0,badops=0,newreq=0,verbose=0,pkey_type=EVP_PKEY_RSA;
|
int i=0,badops=0,newreq=0,verbose=0,pkey_type=EVP_PKEY_RSA;
|
||||||
@ -235,6 +230,16 @@ int MAIN(int argc, char **argv)
|
|||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
engine= *(++argv);
|
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
|
#endif
|
||||||
else if (strcmp(*argv,"-key") == 0)
|
else if (strcmp(*argv,"-key") == 0)
|
||||||
{
|
{
|
||||||
@ -634,7 +639,7 @@ bad:
|
|||||||
if (keyalg)
|
if (keyalg)
|
||||||
{
|
{
|
||||||
genctx = set_keygen_ctx(bio_err, keyalg, &newkey,
|
genctx = set_keygen_ctx(bio_err, keyalg, &newkey,
|
||||||
&keyalgstr, e);
|
&keyalgstr, gen_eng);
|
||||||
if (!genctx)
|
if (!genctx)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -655,7 +660,7 @@ bad:
|
|||||||
if (!genctx)
|
if (!genctx)
|
||||||
{
|
{
|
||||||
genctx = set_keygen_ctx(bio_err, NULL, &newkey,
|
genctx = set_keygen_ctx(bio_err, NULL, &newkey,
|
||||||
&keyalgstr, e);
|
&keyalgstr, gen_eng);
|
||||||
if (!genctx)
|
if (!genctx)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@ -1080,18 +1085,18 @@ end:
|
|||||||
EVP_PKEY_CTX_free(genctx);
|
EVP_PKEY_CTX_free(genctx);
|
||||||
if (pkeyopts)
|
if (pkeyopts)
|
||||||
sk_free(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_REQ_free(req);
|
||||||
X509_free(x509ss);
|
X509_free(x509ss);
|
||||||
ASN1_INTEGER_free(serial);
|
ASN1_INTEGER_free(serial);
|
||||||
if(passargin && passin) OPENSSL_free(passin);
|
if(passargin && passin) OPENSSL_free(passin);
|
||||||
if(passargout && passout) OPENSSL_free(passout);
|
if(passargout && passout) OPENSSL_free(passout);
|
||||||
OBJ_cleanup();
|
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();
|
apps_shutdown();
|
||||||
OPENSSL_EXIT(ex);
|
OPENSSL_EXIT(ex);
|
||||||
}
|
}
|
||||||
@ -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,
|
static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
|
||||||
long *pkeylen, const char **palgnam,
|
long *pkeylen, char **palgnam,
|
||||||
ENGINE *e)
|
ENGINE *keygen_engine)
|
||||||
{
|
{
|
||||||
EVP_PKEY_CTX *gctx = NULL;
|
EVP_PKEY_CTX *gctx = NULL;
|
||||||
EVP_PKEY *param = NULL;
|
EVP_PKEY *param = NULL;
|
||||||
@ -1593,14 +1598,18 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
|
|||||||
{
|
{
|
||||||
const char *p = strchr(gstr, ':');
|
const char *p = strchr(gstr, ':');
|
||||||
int len;
|
int len;
|
||||||
|
ENGINE *tmpeng;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
|
|
||||||
if (p)
|
if (p)
|
||||||
len = p - gstr;
|
len = p - gstr;
|
||||||
else
|
else
|
||||||
len = strlen(gstr);
|
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)
|
if (!ameth)
|
||||||
{
|
{
|
||||||
@ -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,
|
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 (pkey_type == EVP_PKEY_RSA)
|
||||||
{
|
{
|
||||||
if (p)
|
if (p)
|
||||||
@ -1666,24 +1679,30 @@ static EVP_PKEY_CTX *set_keygen_ctx(BIO *err, const char *gstr,
|
|||||||
if (palgnam)
|
if (palgnam)
|
||||||
{
|
{
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
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)
|
if (!ameth)
|
||||||
{
|
{
|
||||||
BIO_puts(err, "Internal error: can't find key algorithm\n");
|
BIO_puts(err, "Internal error: can't find key algorithm\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, palgnam,
|
EVP_PKEY_asn1_get0_info(NULL, NULL, NULL, NULL, &anam, ameth);
|
||||||
ameth);
|
*palgnam = BUF_strdup(anam);
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
if (tmpeng)
|
||||||
|
ENGINE_finish(tmpeng);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param)
|
if (param)
|
||||||
{
|
{
|
||||||
gctx = EVP_PKEY_CTX_new(param, e);
|
gctx = EVP_PKEY_CTX_new(param, keygen_engine);
|
||||||
*pkeylen = EVP_PKEY_bits(param);
|
*pkeylen = EVP_PKEY_bits(param);
|
||||||
EVP_PKEY_free(param);
|
EVP_PKEY_free(param);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
gctx = EVP_PKEY_CTX_new_id(pkey_type, e);
|
gctx = EVP_PKEY_CTX_new_id(pkey_type, keygen_engine);
|
||||||
|
|
||||||
if (!gctx)
|
if (!gctx)
|
||||||
{
|
{
|
||||||
|
@ -59,7 +59,9 @@
|
|||||||
#include "cryptlib.h"
|
#include "cryptlib.h"
|
||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/ec.h>
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#endif
|
||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
|
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
|
||||||
@ -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);
|
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;
|
EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret;
|
||||||
tmp.pkey_id = type;
|
tmp.pkey_id = type;
|
||||||
@ -151,17 +153,72 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type)
|
|||||||
(int (*)(const void *, const void *))ameth_cmp);
|
(int (*)(const void *, const void *))ameth_cmp);
|
||||||
if (!ret || !*ret)
|
if (!ret || !*ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
if ((*ret)->pkey_flags & ASN1_PKEY_ALIAS)
|
|
||||||
return EVP_PKEY_asn1_find((*ret)->pkey_base_id);
|
|
||||||
return *ret;
|
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;
|
int i;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
len = strlen(str);
|
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++)
|
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
|
||||||
{
|
{
|
||||||
ameth = EVP_PKEY_asn1_get0(i);
|
ameth = EVP_PKEY_asn1_get0(i);
|
||||||
|
@ -61,6 +61,7 @@
|
|||||||
#include <openssl/bn.h>
|
#include <openssl/bn.h>
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/objects.h>
|
#include <openssl/objects.h>
|
||||||
|
#include <openssl/engine.h>
|
||||||
#include <openssl/asn1.h>
|
#include <openssl/asn1.h>
|
||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
@ -77,25 +78,27 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else ret= *a;
|
else
|
||||||
|
|
||||||
ret->save_type=type;
|
|
||||||
ret->type=EVP_PKEY_type(type);
|
|
||||||
ret->ameth = EVP_PKEY_asn1_find(type);
|
|
||||||
if (ret->ameth)
|
|
||||||
{
|
{
|
||||||
if (!ret->ameth->old_priv_decode ||
|
ret= *a;
|
||||||
!ret->ameth->old_priv_decode(ret, pp, length))
|
if (ret->engine)
|
||||||
{
|
{
|
||||||
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
|
ENGINE_finish(ret->engine);
|
||||||
goto err;
|
ret->engine = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (!EVP_PKEY_set_type(ret, type))
|
||||||
{
|
{
|
||||||
ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
||||||
goto err;
|
goto err;
|
||||||
/* break; */
|
}
|
||||||
|
|
||||||
|
if (!ret->ameth->old_priv_decode ||
|
||||||
|
!ret->ameth->old_priv_decode(ret, pp, length))
|
||||||
|
{
|
||||||
|
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
|
||||||
|
goto err;
|
||||||
}
|
}
|
||||||
if (a != NULL) (*a)=ret;
|
if (a != NULL) (*a)=ret;
|
||||||
return(ret);
|
return(ret);
|
||||||
|
@ -90,19 +90,16 @@ IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
|
|||||||
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
||||||
{
|
{
|
||||||
X509_PUBKEY *pk=NULL;
|
X509_PUBKEY *pk=NULL;
|
||||||
const EVP_PKEY_ASN1_METHOD *meth;
|
|
||||||
|
|
||||||
if (x == NULL) return(0);
|
if (x == NULL) return(0);
|
||||||
|
|
||||||
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
|
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
|
||||||
|
|
||||||
meth = EVP_PKEY_asn1_find(pkey->type);
|
if (pkey->ameth)
|
||||||
|
|
||||||
if (meth)
|
|
||||||
{
|
{
|
||||||
if (meth->pub_encode)
|
if (pkey->ameth->pub_encode)
|
||||||
{
|
{
|
||||||
if (!meth->pub_encode(pk, pkey))
|
if (!pkey->ameth->pub_encode(pk, pkey))
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_SET,
|
X509err(X509_F_X509_PUBKEY_SET,
|
||||||
X509_R_PUBLIC_KEY_ENCODE_ERROR);
|
X509_R_PUBLIC_KEY_ENCODE_ERROR);
|
||||||
@ -136,7 +133,6 @@ error:
|
|||||||
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
||||||
{
|
{
|
||||||
EVP_PKEY *ret=NULL;
|
EVP_PKEY *ret=NULL;
|
||||||
const EVP_PKEY_ASN1_METHOD *meth;
|
|
||||||
|
|
||||||
if (key == NULL) goto error;
|
if (key == NULL) goto error;
|
||||||
|
|
||||||
@ -154,29 +150,24 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
meth = EVP_PKEY_asn1_find(OBJ_obj2nid(key->algor->algorithm));
|
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
|
||||||
|
|
||||||
if (meth)
|
|
||||||
{
|
{
|
||||||
if (meth->pub_decode)
|
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
|
||||||
{
|
goto error;
|
||||||
if (!meth->pub_decode(ret, key))
|
}
|
||||||
{
|
|
||||||
X509err(X509_F_X509_PUBKEY_GET,
|
if (ret->ameth->pub_decode)
|
||||||
X509_R_PUBLIC_KEY_DECODE_ERROR);
|
{
|
||||||
goto error;
|
if (!ret->ameth->pub_decode(ret, key))
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_GET,
|
X509err(X509_F_X509_PUBKEY_GET,
|
||||||
X509_R_METHOD_NOT_SUPPORTED);
|
X509_R_PUBLIC_KEY_DECODE_ERROR);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
|
X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,11 @@ int ENGINE_set_default(ENGINE *e, unsigned int flags)
|
|||||||
#endif
|
#endif
|
||||||
if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
|
if((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e))
|
||||||
return 0;
|
return 0;
|
||||||
if((flags & ENGINE_METHOD_PKEY_METHS) && !ENGINE_set_default_pkey_meths(e))
|
if((flags & ENGINE_METHOD_PKEY_METHS)
|
||||||
|
&& !ENGINE_set_default_pkey_meths(e))
|
||||||
|
return 0;
|
||||||
|
if((flags & ENGINE_METHOD_PKEY_ASN1_METHS)
|
||||||
|
&& !ENGINE_set_default_pkey_asn1_meths(e))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -118,7 +122,12 @@ static int int_def_cb(const char *alg, int len, void *arg)
|
|||||||
else if (!strncmp(alg, "DIGESTS", len))
|
else if (!strncmp(alg, "DIGESTS", len))
|
||||||
*pflags |= ENGINE_METHOD_DIGESTS;
|
*pflags |= ENGINE_METHOD_DIGESTS;
|
||||||
else if (!strncmp(alg, "PKEY", len))
|
else if (!strncmp(alg, "PKEY", len))
|
||||||
|
*pflags |=
|
||||||
|
ENGINE_METHOD_PKEY_METHS|ENGINE_METHOD_PKEY_ASN1_METHS;
|
||||||
|
else if (!strncmp(alg, "PKEY_CRYPTO", len))
|
||||||
*pflags |= ENGINE_METHOD_PKEY_METHS;
|
*pflags |= ENGINE_METHOD_PKEY_METHS;
|
||||||
|
else if (!strncmp(alg, "PKEY_ASN1", len))
|
||||||
|
*pflags |= ENGINE_METHOD_PKEY_ASN1_METHS;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -146,6 +146,7 @@ void engine_set_all_null(ENGINE *e);
|
|||||||
/* Free up dynamically allocated public key methods associated with ENGINE */
|
/* Free up dynamically allocated public key methods associated with ENGINE */
|
||||||
|
|
||||||
void engine_pkey_meths_free(ENGINE *e);
|
void engine_pkey_meths_free(ENGINE *e);
|
||||||
|
void engine_pkey_asn1_meths_free(ENGINE *e);
|
||||||
|
|
||||||
/* This is a structure for storing implementations of various crypto
|
/* This is a structure for storing implementations of various crypto
|
||||||
* algorithms and functions. */
|
* algorithms and functions. */
|
||||||
|
@ -127,6 +127,7 @@ int engine_free_util(ENGINE *e, int locked)
|
|||||||
#endif
|
#endif
|
||||||
/* Free up any dynamically allocated public key methods */
|
/* Free up any dynamically allocated public key methods */
|
||||||
engine_pkey_meths_free(e);
|
engine_pkey_meths_free(e);
|
||||||
|
engine_pkey_asn1_meths_free(e);
|
||||||
/* Give the ENGINE a chance to do any structural cleanup corresponding
|
/* Give the ENGINE a chance to do any structural cleanup corresponding
|
||||||
* to allocation it did in its constructor (eg. unload error strings) */
|
* to allocation it did in its constructor (eg. unload error strings) */
|
||||||
if(e->destroy)
|
if(e->destroy)
|
||||||
|
@ -112,6 +112,7 @@ extern "C" {
|
|||||||
#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
|
#define ENGINE_METHOD_DIGESTS (unsigned int)0x0080
|
||||||
#define ENGINE_METHOD_STORE (unsigned int)0x0100
|
#define ENGINE_METHOD_STORE (unsigned int)0x0100
|
||||||
#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
|
#define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200
|
||||||
|
#define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400
|
||||||
/* Obvious all-or-nothing cases. */
|
/* Obvious all-or-nothing cases. */
|
||||||
#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
|
#define ENGINE_METHOD_ALL (unsigned int)0xFFFF
|
||||||
#define ENGINE_METHOD_NONE (unsigned int)0x0000
|
#define ENGINE_METHOD_NONE (unsigned int)0x0000
|
||||||
@ -510,6 +511,8 @@ const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
|
|||||||
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
|
const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
|
||||||
const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
|
const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid);
|
||||||
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
|
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid);
|
||||||
|
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
|
||||||
|
const char *str, int len);
|
||||||
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
|
const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
|
||||||
int ENGINE_get_flags(const ENGINE *e);
|
int ENGINE_get_flags(const ENGINE *e);
|
||||||
|
|
||||||
@ -558,6 +561,7 @@ ENGINE *ENGINE_get_default_RAND(void);
|
|||||||
ENGINE *ENGINE_get_cipher_engine(int nid);
|
ENGINE *ENGINE_get_cipher_engine(int nid);
|
||||||
ENGINE *ENGINE_get_digest_engine(int nid);
|
ENGINE *ENGINE_get_digest_engine(int nid);
|
||||||
ENGINE *ENGINE_get_pkey_meth_engine(int nid);
|
ENGINE *ENGINE_get_pkey_meth_engine(int nid);
|
||||||
|
ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid);
|
||||||
|
|
||||||
/* This sets a new default ENGINE structure for performing RSA
|
/* This sets a new default ENGINE structure for performing RSA
|
||||||
* operations. If the result is non-zero (success) then the ENGINE
|
* operations. If the result is non-zero (success) then the ENGINE
|
||||||
@ -574,6 +578,7 @@ int ENGINE_set_default_RAND(ENGINE *e);
|
|||||||
int ENGINE_set_default_ciphers(ENGINE *e);
|
int ENGINE_set_default_ciphers(ENGINE *e);
|
||||||
int ENGINE_set_default_digests(ENGINE *e);
|
int ENGINE_set_default_digests(ENGINE *e);
|
||||||
int ENGINE_set_default_pkey_meths(ENGINE *e);
|
int ENGINE_set_default_pkey_meths(ENGINE *e);
|
||||||
|
int ENGINE_set_default_pkey_asn1_meths(ENGINE *e);
|
||||||
|
|
||||||
/* The combination "set" - the flags are bitwise "OR"d from the
|
/* The combination "set" - the flags are bitwise "OR"d from the
|
||||||
* ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
|
* ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
|
||||||
|
@ -53,10 +53,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eng_int.h"
|
#include "eng_int.h"
|
||||||
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the function
|
/* If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the
|
||||||
* that is used by EVP to hook in pkey_asn1_meth code and cache defaults (etc), will
|
* function that is used by EVP to hook in pkey_asn1_meth code and cache
|
||||||
* display brief debugging summaries to stderr with the 'nid'. */
|
* defaults (etc), will display brief debugging summaries to stderr with the
|
||||||
|
* 'nid'. */
|
||||||
/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
|
/* #define ENGINE_PKEY_ASN1_METH_DEBUG */
|
||||||
|
|
||||||
static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
|
static ENGINE_TABLE *pkey_asn1_meth_table = NULL;
|
||||||
@ -164,3 +166,30 @@ void engine_pkey_asn1_meths_free(ENGINE *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find a method based on a string. This does a linear search through
|
||||||
|
* all implemented algorithms. This is OK in practice because only
|
||||||
|
* a small number of algorithms are likely to be implemented in an engine
|
||||||
|
* and it is only used for non speed critical operations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e,
|
||||||
|
const char *str, int len)
|
||||||
|
{
|
||||||
|
int i, nidcount;
|
||||||
|
const int *nids;
|
||||||
|
EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
|
if (!e->pkey_asn1_meths)
|
||||||
|
return NULL;
|
||||||
|
if (len == -1)
|
||||||
|
len = strlen(str);
|
||||||
|
nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0);
|
||||||
|
for (i = 0; i < nidcount; i++)
|
||||||
|
{
|
||||||
|
e->pkey_asn1_meths(e, &ameth, NULL, nids[i]);
|
||||||
|
if (((int)strlen(ameth->pem_str) == len) &&
|
||||||
|
!strncasecmp(ameth->pem_str, str, len))
|
||||||
|
return ameth;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -129,7 +129,7 @@ struct evp_pkey_st
|
|||||||
int save_type;
|
int save_type;
|
||||||
int references;
|
int references;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
const EVP_PKEY_METHOD *pmeth;
|
ENGINE *engine;
|
||||||
union {
|
union {
|
||||||
char *ptr;
|
char *ptr;
|
||||||
#ifndef OPENSSL_NO_RSA
|
#ifndef OPENSSL_NO_RSA
|
||||||
@ -770,6 +770,8 @@ int EVP_PKEY_id(const EVP_PKEY *pkey);
|
|||||||
int EVP_PKEY_base_id(const EVP_PKEY *pkey);
|
int EVP_PKEY_base_id(const EVP_PKEY *pkey);
|
||||||
int EVP_PKEY_bits(EVP_PKEY *pkey);
|
int EVP_PKEY_bits(EVP_PKEY *pkey);
|
||||||
int EVP_PKEY_size(EVP_PKEY *pkey);
|
int EVP_PKEY_size(EVP_PKEY *pkey);
|
||||||
|
int EVP_PKEY_set_type(EVP_PKEY *pkey,int type);
|
||||||
|
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
|
||||||
int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
|
int EVP_PKEY_assign(EVP_PKEY *pkey,int type,void *key);
|
||||||
void * EVP_PKEY_get0(EVP_PKEY *pkey);
|
void * EVP_PKEY_get0(EVP_PKEY *pkey);
|
||||||
|
|
||||||
@ -874,8 +876,9 @@ void EVP_PBE_cleanup(void);
|
|||||||
|
|
||||||
int EVP_PKEY_asn1_get_count(void);
|
int EVP_PKEY_asn1_get_count(void);
|
||||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
|
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
|
||||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type);
|
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type);
|
||||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len);
|
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
|
||||||
|
const char *str, int len);
|
||||||
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
|
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth);
|
||||||
int EVP_PKEY_asn1_add_alias(int to, int from);
|
int EVP_PKEY_asn1_add_alias(int to, int from);
|
||||||
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
|
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, int *ppkey_flags,
|
||||||
@ -1142,6 +1145,7 @@ void ERR_load_EVP_strings(void);
|
|||||||
#define EVP_F_PKCS5_PBE_KEYIVGEN 117
|
#define EVP_F_PKCS5_PBE_KEYIVGEN 117
|
||||||
#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
|
#define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118
|
||||||
#define EVP_F_PKCS8_SET_BROKEN 112
|
#define EVP_F_PKCS8_SET_BROKEN 112
|
||||||
|
#define EVP_F_PKEY_SET_TYPE 158
|
||||||
#define EVP_F_RC2_MAGIC_TO_METH 109
|
#define EVP_F_RC2_MAGIC_TO_METH 109
|
||||||
#define EVP_F_RC5_CTRL 125
|
#define EVP_F_RC5_CTRL 125
|
||||||
|
|
||||||
@ -1193,6 +1197,7 @@ void ERR_load_EVP_strings(void);
|
|||||||
#define EVP_R_PUBLIC_KEY_NOT_RSA 106
|
#define EVP_R_PUBLIC_KEY_NOT_RSA 106
|
||||||
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
|
#define EVP_R_UNKNOWN_PBE_ALGORITHM 121
|
||||||
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
|
#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135
|
||||||
|
#define EVP_R_UNSUPPORTED_ALGORITHM 156
|
||||||
#define EVP_R_UNSUPPORTED_CIPHER 107
|
#define EVP_R_UNSUPPORTED_CIPHER 107
|
||||||
#define EVP_R_UNSUPPORTED_KEYLENGTH 123
|
#define EVP_R_UNSUPPORTED_KEYLENGTH 123
|
||||||
#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124
|
#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124
|
||||||
|
@ -125,6 +125,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
|
|||||||
{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
|
{ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"},
|
||||||
{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
|
{ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"},
|
||||||
{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
|
{ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"},
|
||||||
|
{ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"},
|
||||||
{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
|
{ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"},
|
||||||
{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
|
{ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"},
|
||||||
{0,NULL}
|
{0,NULL}
|
||||||
@ -179,6 +180,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
|||||||
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
|
{ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
|
||||||
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
|
{ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM) ,"unknown pbe algorithm"},
|
||||||
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
|
{ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS),"unsuported number of rounds"},
|
||||||
|
{ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM) ,"unsupported algorithm"},
|
||||||
{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
|
{ERR_REASON(EVP_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
|
||||||
{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
|
{ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH) ,"unsupported keylength"},
|
||||||
{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
|
{ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION),"unsupported key derivation function"},
|
||||||
|
@ -69,7 +69,6 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
|
|||||||
{
|
{
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
ASN1_OBJECT *algoid;
|
ASN1_OBJECT *algoid;
|
||||||
const EVP_PKEY_ASN1_METHOD *meth;
|
|
||||||
char obj_tmp[80];
|
char obj_tmp[80];
|
||||||
|
|
||||||
if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
|
if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8))
|
||||||
@ -80,33 +79,29 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
meth = EVP_PKEY_asn1_find(OBJ_obj2nid(algoid));
|
if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid)))
|
||||||
|
|
||||||
if (meth)
|
|
||||||
{
|
|
||||||
if (meth->priv_decode)
|
|
||||||
{
|
|
||||||
if (!meth->priv_decode(pkey, p8))
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
|
||||||
EVP_R_PRIVATE_KEY_DECODE_ERROR);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
|
||||||
EVP_R_METHOD_NOT_SUPPORTED);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
|
||||||
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
|
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
|
||||||
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
ERR_add_error_data(2, "TYPE=", obj_tmp);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pkey->ameth->priv_decode)
|
||||||
|
{
|
||||||
|
if (!pkey->ameth->priv_decode(pkey, p8))
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_EVP_PKCS82PKEY,
|
||||||
|
EVP_R_PRIVATE_KEY_DECODE_ERROR);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
return pkey;
|
return pkey;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -124,7 +119,6 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey)
|
|||||||
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
|
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
|
||||||
{
|
{
|
||||||
PKCS8_PRIV_KEY_INFO *p8;
|
PKCS8_PRIV_KEY_INFO *p8;
|
||||||
const EVP_PKEY_ASN1_METHOD *meth;
|
|
||||||
|
|
||||||
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
|
if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) {
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,ERR_R_MALLOC_FAILURE);
|
||||||
@ -132,13 +126,11 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken)
|
|||||||
}
|
}
|
||||||
p8->broken = broken;
|
p8->broken = broken;
|
||||||
|
|
||||||
meth = EVP_PKEY_asn1_find(pkey->type);
|
if (pkey->ameth)
|
||||||
|
|
||||||
if (meth)
|
|
||||||
{
|
{
|
||||||
if (meth->priv_encode)
|
if (pkey->ameth->priv_encode)
|
||||||
{
|
{
|
||||||
if (!meth->priv_encode(p8, pkey))
|
if (!pkey->ameth->priv_encode(p8, pkey))
|
||||||
{
|
{
|
||||||
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
|
EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN,
|
||||||
EVP_R_PRIVATE_KEY_ENCODE_ERROR);
|
EVP_R_PRIVATE_KEY_ENCODE_ERROR);
|
||||||
|
@ -74,6 +74,10 @@
|
|||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
static void EVP_PKEY_free_it(EVP_PKEY *x);
|
static void EVP_PKEY_free_it(EVP_PKEY *x);
|
||||||
@ -177,26 +181,79 @@ EVP_PKEY *EVP_PKEY_new(void)
|
|||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
ret->type=EVP_PKEY_NONE;
|
ret->type=EVP_PKEY_NONE;
|
||||||
|
ret->save_type=EVP_PKEY_NONE;
|
||||||
ret->references=1;
|
ret->references=1;
|
||||||
ret->ameth=NULL;
|
ret->ameth=NULL;
|
||||||
|
ret->engine=NULL;
|
||||||
ret->pkey.ptr=NULL;
|
ret->pkey.ptr=NULL;
|
||||||
ret->attributes=NULL;
|
ret->attributes=NULL;
|
||||||
ret->save_parameters=1;
|
ret->save_parameters=1;
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
|
/* Setup a public key ASN1 method and ENGINE from a NID or a string.
|
||||||
|
* If pkey is NULL just return 1 or 0 if the algorithm exists.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len)
|
||||||
{
|
{
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
if (pkey == NULL) return(0);
|
ENGINE *e = NULL;
|
||||||
if (pkey->pkey.ptr != NULL)
|
if (pkey)
|
||||||
EVP_PKEY_free_it(pkey);
|
{
|
||||||
ameth = EVP_PKEY_asn1_find(type);
|
if (pkey->pkey.ptr)
|
||||||
pkey->ameth = ameth;
|
EVP_PKEY_free_it(pkey);
|
||||||
pkey->type = ameth->pkey_id;
|
/* If key type matches and a method exists then this
|
||||||
pkey->save_type=type;
|
* lookup has succeeded once so just indicate success.
|
||||||
|
*/
|
||||||
|
if ((type == pkey->save_type) && pkey->ameth)
|
||||||
|
return 1;
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
/* If we have an ENGINE release it */
|
||||||
|
if (pkey->engine)
|
||||||
|
ENGINE_finish(pkey->engine);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (str)
|
||||||
|
ameth = EVP_PKEY_asn1_find_str(&e, str, len);
|
||||||
|
else
|
||||||
|
ameth = EVP_PKEY_asn1_find(&e, type);
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
if (!pkey && e)
|
||||||
|
ENGINE_finish(e);
|
||||||
|
#endif
|
||||||
|
if (!ameth)
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (pkey)
|
||||||
|
{
|
||||||
|
pkey->ameth = ameth;
|
||||||
|
pkey->engine = e;
|
||||||
|
|
||||||
|
pkey->type = pkey->ameth->pkey_id;
|
||||||
|
pkey->save_type=type;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_PKEY_set_type(EVP_PKEY *pkey, int type)
|
||||||
|
{
|
||||||
|
return pkey_set_type(pkey, type, NULL, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len)
|
||||||
|
{
|
||||||
|
return pkey_set_type(pkey, EVP_PKEY_NONE, str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key)
|
||||||
|
{
|
||||||
|
if (!EVP_PKEY_set_type(pkey, type))
|
||||||
|
return 0;
|
||||||
pkey->pkey.ptr=key;
|
pkey->pkey.ptr=key;
|
||||||
return(key != NULL);
|
return (key != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *EVP_PKEY_get0(EVP_PKEY *pkey)
|
void *EVP_PKEY_get0(EVP_PKEY *pkey)
|
||||||
@ -290,11 +347,19 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
|
|||||||
|
|
||||||
int EVP_PKEY_type(int type)
|
int EVP_PKEY_type(int type)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
ameth = EVP_PKEY_asn1_find(type);
|
ENGINE *e;
|
||||||
|
ameth = EVP_PKEY_asn1_find(&e, type);
|
||||||
if (ameth)
|
if (ameth)
|
||||||
return ameth->pkey_id;
|
ret = ameth->pkey_id;
|
||||||
return NID_undef;
|
else
|
||||||
|
ret = NID_undef;
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
if (e)
|
||||||
|
ENGINE_finish(e);
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int EVP_PKEY_id(const EVP_PKEY *pkey)
|
int EVP_PKEY_id(const EVP_PKEY *pkey)
|
||||||
@ -335,14 +400,21 @@ static void EVP_PKEY_free_it(EVP_PKEY *x)
|
|||||||
{
|
{
|
||||||
if (x->ameth && x->ameth->pkey_free)
|
if (x->ameth && x->ameth->pkey_free)
|
||||||
x->ameth->pkey_free(x);
|
x->ameth->pkey_free(x);
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
if (x->engine)
|
||||||
|
{
|
||||||
|
ENGINE_finish(x->engine);
|
||||||
|
x->engine = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
|
static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||||
const char *kstr)
|
const char *kstr)
|
||||||
{
|
{
|
||||||
BIO_indent(out, indent, 128);
|
BIO_indent(out, indent, 128);
|
||||||
BIO_printf(out, "%s %s, algorithm, unsupported\n",
|
BIO_printf(out, "%s algorithm \"%s\" unsupported\n",
|
||||||
OBJ_nid2ln(pkey->type), kstr);
|
kstr, OBJ_nid2ln(pkey->type));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,10 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
|
|||||||
pmeth = EVP_PKEY_meth_find(id);
|
pmeth = EVP_PKEY_meth_find(id);
|
||||||
|
|
||||||
if (pmeth == NULL)
|
if (pmeth == NULL)
|
||||||
|
{
|
||||||
|
EVPerr(EVP_F_INT_CTX_NEW,EVP_R_UNSUPPORTED_ALGORITHM);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
|
ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
@ -70,6 +70,9 @@
|
|||||||
#ifndef OPENSSL_NO_DES
|
#ifndef OPENSSL_NO_DES
|
||||||
#include <openssl/des.h>
|
#include <openssl/des.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
|
const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
|
||||||
|
|
||||||
@ -197,7 +200,11 @@ static int check_pem(const char *nm, const char *name)
|
|||||||
slen = pem_check_suffix(nm, "PRIVATE KEY");
|
slen = pem_check_suffix(nm, "PRIVATE KEY");
|
||||||
if (slen > 0)
|
if (slen > 0)
|
||||||
{
|
{
|
||||||
ameth = EVP_PKEY_asn1_find_str(nm, slen);
|
/* NB: ENGINE implementations wont contain
|
||||||
|
* a deprecated old private key decode function
|
||||||
|
* so don't look for them.
|
||||||
|
*/
|
||||||
|
ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
|
||||||
if (ameth && ameth->old_priv_decode)
|
if (ameth && ameth->old_priv_decode)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -211,9 +218,21 @@ static int check_pem(const char *nm, const char *name)
|
|||||||
slen = pem_check_suffix(nm, "PARAMETERS");
|
slen = pem_check_suffix(nm, "PARAMETERS");
|
||||||
if (slen > 0)
|
if (slen > 0)
|
||||||
{
|
{
|
||||||
ameth = EVP_PKEY_asn1_find_str(nm, slen);
|
ENGINE *e;
|
||||||
if (ameth && ameth->param_decode)
|
ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
|
||||||
return 1;
|
if (ameth)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
if (ameth->param_decode)
|
||||||
|
r = 1;
|
||||||
|
else
|
||||||
|
r = 0;
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
if (e)
|
||||||
|
ENGINE_finish(e);
|
||||||
|
#endif
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -65,6 +65,9 @@
|
|||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pkcs12.h>
|
#include <openssl/pkcs12.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
|
#include <openssl/engine.h>
|
||||||
|
#endif
|
||||||
#include "asn1_locl.h"
|
#include "asn1_locl.h"
|
||||||
|
|
||||||
int pem_check_suffix(const char *pem_str, const char *suffix);
|
int pem_check_suffix(const char *pem_str, const char *suffix);
|
||||||
@ -119,7 +122,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
|
|||||||
} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
|
} else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
|
||||||
{
|
{
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||||
ameth = EVP_PKEY_asn1_find_str(nm, slen);
|
ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
|
||||||
if (!ameth || !ameth->old_priv_decode)
|
if (!ameth || !ameth->old_priv_decode)
|
||||||
goto p8err;
|
goto p8err;
|
||||||
ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
|
ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
|
||||||
@ -164,14 +167,12 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
|
|||||||
|
|
||||||
if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
|
if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0)
|
||||||
{
|
{
|
||||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
|
||||||
ameth = EVP_PKEY_asn1_find_str(nm, slen);
|
|
||||||
if (!ameth || !ameth->param_decode)
|
|
||||||
goto err;
|
|
||||||
ret = EVP_PKEY_new();
|
ret = EVP_PKEY_new();
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto err;
|
goto err;
|
||||||
if (!ameth->param_decode(ret, &p, len))
|
if (!EVP_PKEY_set_type_str(ret, nm, slen)
|
||||||
|
|| !ret->ameth->param_decode
|
||||||
|
|| !ret->ameth->param_decode(ret, &p, len))
|
||||||
{
|
{
|
||||||
EVP_PKEY_free(ret);
|
EVP_PKEY_free(ret);
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user