提交 e4263314 编写于 作者: D Dr. Stephen Henson

Add support for legacy PEM format private keys in EVP_PKEY_ASN1_METHOD.

上级 bd50e313
...@@ -105,6 +105,25 @@ static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a, ...@@ -105,6 +105,25 @@ static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
return ((*a)->pkey_id - (*b)->pkey_id); return ((*a)->pkey_id - (*b)->pkey_id);
} }
int EVP_PKEY_asn1_get_count(void)
{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (app_methods)
num += sk_num(app_methods);
return num;
}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
{
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
if (idx < 0)
return NULL;
if (idx < num)
return standard_methods[idx];
idx -= num;
return (const EVP_PKEY_ASN1_METHOD *)sk_value(app_methods, idx);
}
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type) const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type)
{ {
EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret; EVP_PKEY_ASN1_METHOD tmp, *t = &tmp, **ret;
...@@ -129,6 +148,22 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type) ...@@ -129,6 +148,22 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type)
return *ret; return *ret;
} }
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len)
{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
{
ameth = EVP_PKEY_asn1_get0(i);
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
continue;
if ((strlen(ameth->pem_str) == len) &&
!strncasecmp(ameth->pem_str, str, len))
return ameth;
}
return NULL;
}
int EVP_PKEY_asn1_add(const EVP_PKEY_ASN1_METHOD *ameth) int EVP_PKEY_asn1_add(const EVP_PKEY_ASN1_METHOD *ameth)
{ {
if (app_methods == NULL) if (app_methods == NULL)
......
...@@ -107,4 +107,11 @@ struct evp_pkey_asn1_method_st ...@@ -107,4 +107,11 @@ struct evp_pkey_asn1_method_st
void (*pkey_free)(EVP_PKEY *pkey); void (*pkey_free)(EVP_PKEY *pkey);
void (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); void (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
/* Legacy functions for old PEM */
int (*old_priv_decode)(EVP_PKEY *pkey,
const unsigned char **pder, int derlen);
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
} /* EVP_PKEY_ASN1_METHOD */; } /* EVP_PKEY_ASN1_METHOD */;
...@@ -62,15 +62,7 @@ ...@@ -62,15 +62,7 @@
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/objects.h> #include <openssl/objects.h>
#include <openssl/asn1.h> #include <openssl/asn1.h>
#ifndef OPENSSL_NO_RSA #include "asn1_locl.h"
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
long length) long length)
...@@ -90,39 +82,17 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, ...@@ -90,39 +82,17 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
ret->save_type=type; ret->save_type=type;
ret->type=EVP_PKEY_type(type); ret->type=EVP_PKEY_type(type);
ret->ameth = EVP_PKEY_asn1_find(type); ret->ameth = EVP_PKEY_asn1_find(type);
switch (ret->type) if (ret->ameth)
{ {
#ifndef OPENSSL_NO_RSA if (!ret->ameth->old_priv_decode ||
case EVP_PKEY_RSA: !ret->ameth->old_priv_decode(ret, pp, length))
if ((ret->pkey.rsa=d2i_RSAPrivateKey(NULL,
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
{ {
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB); ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
goto err; goto err;
} }
break; }
#endif else
#ifndef OPENSSL_NO_DSA {
case EVP_PKEY_DSA:
if ((ret->pkey.dsa=d2i_DSAPrivateKey(NULL,
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
{
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if ((ret->pkey.ec = d2i_ECPrivateKey(NULL,
(const unsigned char **)pp, length)) == NULL)
{
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
default:
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; */ /* break; */
......
...@@ -58,41 +58,15 @@ ...@@ -58,41 +58,15 @@
#include <stdio.h> #include <stdio.h>
#include "cryptlib.h" #include "cryptlib.h"
#include <openssl/bn.h>
#include <openssl/evp.h> #include <openssl/evp.h>
#include <openssl/objects.h> #include "asn1_locl.h"
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{ {
#ifndef OPENSSL_NO_RSA if (a->ameth && a->ameth->old_priv_encode)
if (a->type == EVP_PKEY_RSA)
{ {
return(i2d_RSAPrivateKey(a->pkey.rsa,pp)); return a->ameth->old_priv_encode(a, pp);
} }
else
#endif
#ifndef OPENSSL_NO_DSA
if (a->type == EVP_PKEY_DSA)
{
return(i2d_DSAPrivateKey(a->pkey.dsa,pp));
}
#endif
#ifndef OPENSSL_NO_EC
if (a->type == EVP_PKEY_EC)
{
return(i2d_ECPrivateKey(a->pkey.ec, pp));
}
#endif
ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return(-1); return(-1);
} }
......
...@@ -493,6 +493,24 @@ static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ...@@ -493,6 +493,24 @@ static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
} }
static int old_dsa_priv_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
DSA *dsa;
if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
{
DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
return 1;
}
static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
}
/* NB these are sorted in pkey_id order, lowest first */ /* NB these are sorted in pkey_id order, lowest first */
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
...@@ -527,7 +545,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = ...@@ -527,7 +545,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
EVP_PKEY_DSA, EVP_PKEY_DSA,
0, 0,
"dsa", "DSA",
"OpenSSL DSA method", "OpenSSL DSA method",
dsa_pub_decode, dsa_pub_decode,
...@@ -549,7 +567,9 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = ...@@ -549,7 +567,9 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
dsa_param_print, dsa_param_print,
int_dsa_free, int_dsa_free,
0 0,
old_dsa_priv_decode,
old_dsa_priv_encode
} }
}; };
...@@ -534,12 +534,30 @@ static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, ...@@ -534,12 +534,30 @@ static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
} }
static int old_ec_priv_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{
EC_KEY *ec;
if (!(ec = d2i_ECPrivateKey (NULL, pder, derlen)))
{
ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, ec);
return 1;
}
static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
return i2d_ECPrivateKey(pkey->pkey.ec, pder);
}
EVP_PKEY_ASN1_METHOD eckey_asn1_meth = EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
{ {
EVP_PKEY_EC, EVP_PKEY_EC,
EVP_PKEY_EC, EVP_PKEY_EC,
0, 0,
"ec", "EC",
"OpenSSL EC algorithm", "OpenSSL EC algorithm",
eckey_pub_decode, eckey_pub_decode,
...@@ -561,5 +579,7 @@ EVP_PKEY_ASN1_METHOD eckey_asn1_meth = ...@@ -561,5 +579,7 @@ EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
eckey_param_print, eckey_param_print,
int_ec_free, int_ec_free,
0 0,
old_ec_priv_decode,
old_ec_priv_encode
}; };
...@@ -855,7 +855,10 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, ...@@ -855,7 +855,10 @@ int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
EVP_PBE_KEYGEN *keygen); EVP_PBE_KEYGEN *keygen);
void EVP_PBE_cleanup(void); void EVP_PBE_cleanup(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_find(int type); const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type);
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(const char *str, int len);
int EVP_PKEY_asn1_add(const EVP_PKEY_ASN1_METHOD *ameth); int EVP_PKEY_asn1_add(const EVP_PKEY_ASN1_METHOD *ameth);
EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id,
const char *pem_str, const char *info); const char *pem_str, const char *info);
......
...@@ -731,6 +731,7 @@ void ERR_load_PEM_strings(void); ...@@ -731,6 +731,7 @@ void ERR_load_PEM_strings(void);
#define PEM_F_PEM_SIGNFINAL 112 #define PEM_F_PEM_SIGNFINAL 112
#define PEM_F_PEM_WRITE 113 #define PEM_F_PEM_WRITE 113
#define PEM_F_PEM_WRITE_BIO 114 #define PEM_F_PEM_WRITE_BIO 114
#define PEM_F_PEM_WRITE_PRIVATEKEY 139
#define PEM_F_PEM_X509_INFO_READ 115 #define PEM_F_PEM_X509_INFO_READ 115
#define PEM_F_PEM_X509_INFO_READ_BIO 116 #define PEM_F_PEM_X509_INFO_READ_BIO 116
#define PEM_F_PEM_X509_INFO_WRITE_BIO 117 #define PEM_F_PEM_X509_INFO_WRITE_BIO 117
......
...@@ -294,15 +294,4 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) ...@@ -294,15 +294,4 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
#endif #endif
/* The PrivateKey case is not that straightforward.
* IMPLEMENT_PEM_rw_cb(PrivateKey, EVP_PKEY, PEM_STRING_EVP_PKEY, PrivateKey)
* does not work, RSA and DSA keys have specific strings.
* (When reading, parameter PEM_STRING_EVP_PKEY is a wildcard for anything
* appropriate.)
*/
IMPLEMENT_PEM_write_cb(PrivateKey, EVP_PKEY, ((x->type == EVP_PKEY_DSA)?PEM_STRING_DSA:\
(x->type == EVP_PKEY_RSA)?PEM_STRING_RSA:PEM_STRING_ECPRIVATEKEY), PrivateKey)
IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY)
...@@ -71,7 +71,7 @@ ...@@ -71,7 +71,7 @@
static ERR_STRING_DATA PEM_str_functs[]= static ERR_STRING_DATA PEM_str_functs[]=
{ {
{ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"}, {ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"},
{ERR_FUNC(PEM_F_B2I_PVK_BIO), "B2I_PVK_BIO"}, {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"},
{ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"}, {ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"},
{ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"}, {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"},
{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"}, {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"},
...@@ -85,7 +85,7 @@ static ERR_STRING_DATA PEM_str_functs[]= ...@@ -85,7 +85,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"}, {ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"},
{ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"}, {ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"},
{ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"}, {ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"},
{ERR_FUNC(PEM_F_I2B_PVK_BIO), "I2B_PVK_BIO"}, {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"},
{ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"},
{ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"},
{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
...@@ -105,8 +105,9 @@ static ERR_STRING_DATA PEM_str_functs[]= ...@@ -105,8 +105,9 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
{ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
{ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"},
{ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"},
{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_READ"},
{ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_READ_BIO"},
{ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"},
{0,NULL} {0,NULL}
}; };
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/pkcs12.h> #include <openssl/pkcs12.h>
#include "asn1_locl.h"
#ifndef OPENSSL_NO_DES #ifndef OPENSSL_NO_DES
#include <openssl/des.h> #include <openssl/des.h>
#endif #endif
...@@ -76,6 +77,7 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT; ...@@ -76,6 +77,7 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
static int load_iv(char **fromp,unsigned char *to, int num); static int load_iv(char **fromp,unsigned char *to, int num);
static int check_pem(const char *nm, const char *name); static int check_pem(const char *nm, const char *name);
int pem_check_suffix(const char *pem_str, const char *suffix);
int PEM_def_callback(char *buf, int num, int w, void *key) int PEM_def_callback(char *buf, int num, int w, void *key)
{ {
...@@ -184,20 +186,24 @@ static int check_pem(const char *nm, const char *name) ...@@ -184,20 +186,24 @@ static int check_pem(const char *nm, const char *name)
/* Make PEM_STRING_EVP_PKEY match any private key */ /* Make PEM_STRING_EVP_PKEY match any private key */
if(!strcmp(nm,PEM_STRING_PKCS8) && if(!strcmp(name,PEM_STRING_EVP_PKEY))
!strcmp(name,PEM_STRING_EVP_PKEY)) return 1; {
int slen;
if(!strcmp(nm,PEM_STRING_PKCS8INF) && const EVP_PKEY_ASN1_METHOD *ameth;
!strcmp(name,PEM_STRING_EVP_PKEY)) return 1; if(!strcmp(nm,PEM_STRING_PKCS8))
return 1;
if(!strcmp(nm,PEM_STRING_RSA) && if(!strcmp(nm,PEM_STRING_PKCS8INF))
!strcmp(name,PEM_STRING_EVP_PKEY)) return 1; return 1;
slen = pem_check_suffix(nm, "PRIVATE KEY");
if(!strcmp(nm,PEM_STRING_DSA) && if (slen > 0)
!strcmp(name,PEM_STRING_EVP_PKEY)) return 1; {
ameth = EVP_PKEY_asn1_find_str(nm, slen);
if (ameth && ameth->old_priv_decode)
return 1;
}
return 0;
}
if(!strcmp(nm,PEM_STRING_ECPRIVATEKEY) &&
!strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
/* Permit older strings */ /* Permit older strings */
if(!strcmp(nm,PEM_STRING_X509_OLD) && if(!strcmp(nm,PEM_STRING_X509_OLD) &&
...@@ -783,16 +789,17 @@ err: ...@@ -783,16 +789,17 @@ err:
* the return value is 3 for the string "RSA". * the return value is 3 for the string "RSA".
*/ */
int pem_check_suffix(char *pem_str, char *suffix) int pem_check_suffix(const char *pem_str, const char *suffix)
{ {
int pem_len = strlen(pem_str); int pem_len = strlen(pem_str);
int suffix_len = strlen(suffix); int suffix_len = strlen(suffix);
char *p; const char *p;
if (suffix_len + 1 >= pem_len) if (suffix_len + 1 >= pem_len)
return 0; return 0;
if (strcmp(pem_str - suffix_len, suffix)) p = pem_str + pem_len - suffix_len;
if (strcmp(p, suffix))
return 0; return 0;
p = pem_str - suffix_len - 1; p--;
if (*p != ' ') if (*p != ' ')
return 0; return 0;
return p - pem_str; return p - pem_str;
......
...@@ -65,7 +65,9 @@ ...@@ -65,7 +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>
#include "asn1_locl.h"
int pem_check_suffix(const char *pem_str, const char *suffix);
EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u) EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
{ {
...@@ -73,18 +75,21 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo ...@@ -73,18 +75,21 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
const unsigned char *p=NULL; const unsigned char *p=NULL;
unsigned char *data=NULL; unsigned char *data=NULL;
long len; long len;
int slen;
EVP_PKEY *ret=NULL; EVP_PKEY *ret=NULL;
if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u))
return NULL; return NULL;
p = data; p = data;
if (strcmp(nm,PEM_STRING_RSA) == 0) if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0)
ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); {
else if (strcmp(nm,PEM_STRING_DSA) == 0) const EVP_PKEY_ASN1_METHOD *ameth;
ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); ameth = EVP_PKEY_asn1_find_str(nm, slen);
else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0) if (!ameth || !ameth->old_priv_decode)
ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len); goto p8err;
ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len);
}
else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) {
PKCS8_PRIV_KEY_INFO *p8inf; PKCS8_PRIV_KEY_INFO *p8inf;
p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len);
...@@ -129,6 +134,22 @@ err: ...@@ -129,6 +134,22 @@ err:
return(ret); return(ret);
} }
int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
char pem_str[80];
if (!x->ameth || !x->ameth->old_priv_encode)
return PEM_write_bio_PKCS8PrivateKey(bp, x, enc,
(char *)kstr, klen,
cb, u);
BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str);
return PEM_ASN1_write_bio((i2d_of_void *)openssl_fcast(i2d_PrivateKey),
pem_str,bp,(char *)x,enc,kstr,klen,cb,u);
}
#ifndef OPENSSL_NO_FP_API #ifndef OPENSSL_NO_FP_API
EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
{ {
...@@ -145,4 +166,22 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void ...@@ -145,4 +166,22 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void
BIO_free(b); BIO_free(b);
return(ret); return(ret);
} }
int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
unsigned char *kstr, int klen,
pem_password_cb *cb, void *u)
{
BIO *b;
int ret;
if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
{
PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY,ERR_R_BUF_LIB);
return 0;
}
ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
BIO_free(b);
return ret;
}
#endif #endif
...@@ -101,22 +101,24 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) ...@@ -101,22 +101,24 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return 1; return 1;
} }
static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) static int old_rsa_priv_decode(EVP_PKEY *pkey,
const unsigned char **pder, int derlen)
{ {
const unsigned char *p; RSA *rsa;
int pklen; if (!(rsa = d2i_RSAPrivateKey (NULL, pder, derlen)))
RSA *rsa = NULL;
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
return 0;
if (!(rsa = d2i_RSAPrivateKey (NULL, &p, pklen)))
{ {
RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB); RSAerr(RSA_F_RSA_PRIV_DECODE, ERR_R_RSA_LIB);
return 0; return 0;
} }
EVP_PKEY_assign_RSA (pkey, rsa); EVP_PKEY_assign_RSA(pkey, rsa);
return 1; return 1;
} }
static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
{
return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
}
static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{ {
unsigned char *rk = NULL; unsigned char *rk = NULL;
...@@ -139,6 +141,15 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) ...@@ -139,6 +141,15 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
return 1; return 1;
} }
static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
{
const unsigned char *p;
int pklen;
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8))
return 0;
return old_rsa_priv_decode(pkey, &p, pklen);
}
static int int_rsa_size(const EVP_PKEY *pkey) static int int_rsa_size(const EVP_PKEY *pkey)
{ {
return RSA_size(pkey->pkey.rsa); return RSA_size(pkey->pkey.rsa);
...@@ -256,7 +267,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = ...@@ -256,7 +267,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
EVP_PKEY_RSA, EVP_PKEY_RSA,
0, 0,
"rsa", "RSA",
"OpenSSL RSA method", "OpenSSL RSA method",
rsa_pub_decode, rsa_pub_decode,
...@@ -274,7 +285,9 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = ...@@ -274,7 +285,9 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
0,0,0,0,0,0, 0,0,0,0,0,0,
int_rsa_free, int_rsa_free,
0 0,
old_rsa_priv_decode,
old_rsa_priv_encode
}, },
{ {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册