Index: openssl/crypto/pem/pem_pkey.c |
=================================================================== |
--- openssl/crypto/pem/pem_pkey.c (revision 105093) |
+++ openssl/crypto/pem/pem_pkey.c (working copy) |
@@ -65,7 +65,12 @@ |
#include <openssl/x509.h> |
#include <openssl/pkcs12.h> |
#include <openssl/pem.h> |
+#ifndef OPENSSL_NO_ENGINE |
+#include <openssl/engine.h> |
+#endif |
+#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,19 +78,14 @@ |
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); |
- else if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { |
+ if (strcmp(nm,PEM_STRING_PKCS8INF) == 0) { |
PKCS8_PRIV_KEY_INFO *p8inf; |
p8inf=d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); |
if(!p8inf) goto p8err; |
@@ -119,7 +119,14 @@ |
*x = ret; |
} |
PKCS8_PRIV_KEY_INFO_free(p8inf); |
- } |
+ } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) |
+ { |
+ const EVP_PKEY_ASN1_METHOD *ameth; |
+ ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); |
+ if (!ameth || !ameth->old_priv_decode) |
+ goto p8err; |
+ ret=d2i_PrivateKey(ameth->pkey_id,x,&p,len); |
+ } |
p8err: |
if (ret == NULL) |
PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY,ERR_R_ASN1_LIB); |
@@ -130,6 +137,74 @@ |
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->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 *)i2d_PrivateKey, |
+ pem_str,bp,x,enc,kstr,klen,cb,u); |
+ } |
+ |
+EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) |
+ { |
+ char *nm=NULL; |
+ 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_PARAMETERS, |
+ bp, 0, NULL)) |
+ return NULL; |
+ p = data; |
+ |
+ if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) |
+ { |
+ ret = EVP_PKEY_new(); |
+ if (!ret) |
+ goto err; |
+ if (!EVP_PKEY_set_type_str(ret, nm, slen) |
+ || !ret->ameth->param_decode |
+ || !ret->ameth->param_decode(ret, &p, len)) |
+ { |
+ EVP_PKEY_free(ret); |
+ ret = NULL; |
+ goto err; |
+ } |
+ if(x) |
+ { |
+ if(*x) EVP_PKEY_free((EVP_PKEY *)*x); |
+ *x = ret; |
+ } |
+ } |
+err: |
+ if (ret == NULL) |
+ PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS,ERR_R_ASN1_LIB); |
+ OPENSSL_free(nm); |
+ OPENSSL_free(data); |
+ return(ret); |
+ } |
+ |
+int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) |
+ { |
+ char pem_str[80]; |
+ if (!x->ameth || !x->ameth->param_encode) |
+ return 0; |
+ |
+ BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); |
+ return PEM_ASN1_write_bio( |
+ (i2d_of_void *)x->ameth->param_encode, |
+ pem_str,bp,x,NULL,NULL,0,0,NULL); |
+ } |
+ |
#ifndef OPENSSL_NO_FP_API |
EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u) |
{ |
@@ -146,4 +221,22 @@ |
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 |