diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2006-03-23 18:02:23 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2006-03-23 18:02:23 +0000 |
commit | e42633140e98c7c07a5bc013127e1e6a251995ed (patch) | |
tree | 512218e4d8b50fb52630ce69ee534a485e3fbb76 /crypto/pem/pem_pkey.c | |
parent | bd50e31325516bcdd45627f5d76f96c38be89eba (diff) |
Add support for legacy PEM format private keys in EVP_PKEY_ASN1_METHOD.
Diffstat (limited to 'crypto/pem/pem_pkey.c')
-rw-r--r-- | crypto/pem/pem_pkey.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index 2162a45323..aea826e04e 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -65,7 +65,9 @@ #include <openssl/x509.h> #include <openssl/pkcs12.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) { @@ -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; unsigned char *data=NULL; long len; + int slen; EVP_PKEY *ret=NULL; if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) return NULL; p = data; - if (strcmp(nm,PEM_STRING_RSA) == 0) - ret=d2i_PrivateKey(EVP_PKEY_RSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_DSA) == 0) - ret=d2i_PrivateKey(EVP_PKEY_DSA,x,&p,len); - else if (strcmp(nm,PEM_STRING_ECPRIVATEKEY) == 0) - ret=d2i_PrivateKey(EVP_PKEY_EC,x,&p,len); + if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) + { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_find_str(nm, slen); + if (!ameth || !ameth->old_priv_decode) + goto p8err; + ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len); + } else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { PKCS8_PRIV_KEY_INFO *p8inf; p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); @@ -129,6 +134,22 @@ err: 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 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 BIO_free(b); 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 |