summaryrefslogtreecommitdiffstats
path: root/crypto/pem
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2006-03-23 18:02:23 +0000
committerDr. Stephen Henson <steve@openssl.org>2006-03-23 18:02:23 +0000
commite42633140e98c7c07a5bc013127e1e6a251995ed (patch)
tree512218e4d8b50fb52630ce69ee534a485e3fbb76 /crypto/pem
parentbd50e31325516bcdd45627f5d76f96c38be89eba (diff)
Add support for legacy PEM format private keys in EVP_PKEY_ASN1_METHOD.
Diffstat (limited to 'crypto/pem')
-rw-r--r--crypto/pem/pem.h1
-rw-r--r--crypto/pem/pem_all.c11
-rw-r--r--crypto/pem/pem_err.c9
-rw-r--r--crypto/pem/pem_lib.c41
-rw-r--r--crypto/pem/pem_pkey.c51
5 files changed, 75 insertions, 38 deletions
diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h
index 6ccb14e3b6..f2c5f329ad 100644
--- a/crypto/pem/pem.h
+++ b/crypto/pem/pem.h
@@ -731,6 +731,7 @@ void ERR_load_PEM_strings(void);
#define PEM_F_PEM_SIGNFINAL 112
#define PEM_F_PEM_WRITE 113
#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_BIO 116
#define PEM_F_PEM_X509_INFO_WRITE_BIO 117
diff --git a/crypto/pem/pem_all.c b/crypto/pem/pem_all.c
index d696f15b87..713cd172b2 100644
--- a/crypto/pem/pem_all.c
+++ b/crypto/pem/pem_all.c
@@ -294,15 +294,4 @@ IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams)
#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)
-
diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c
index c63195c0c5..c43585564b 100644
--- a/crypto/pem/pem_err.c
+++ b/crypto/pem/pem_err.c
@@ -71,7 +71,7 @@
static ERR_STRING_DATA PEM_str_functs[]=
{
{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_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"},
{ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"},
@@ -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_HEADER), "DO_PVK_HEADER"},
{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_PEM_ASN1_READ), "PEM_ASN1_read"},
{ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
@@ -105,8 +105,9 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
{ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
{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_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"},
+{ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"},
+{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"},
{0,NULL}
};
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index beb40d7f32..22793fada0 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -66,6 +66,7 @@
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
+#include "asn1_locl.h"
#ifndef OPENSSL_NO_DES
#include <openssl/des.h>
#endif
@@ -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 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)
{
@@ -184,20 +186,24 @@ static int check_pem(const char *nm, const char *name)
/* Make PEM_STRING_EVP_PKEY match any private key */
- if(!strcmp(nm,PEM_STRING_PKCS8) &&
- !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
-
- if(!strcmp(nm,PEM_STRING_PKCS8INF) &&
- !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
-
- if(!strcmp(nm,PEM_STRING_RSA) &&
- !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
-
- if(!strcmp(nm,PEM_STRING_DSA) &&
- !strcmp(name,PEM_STRING_EVP_PKEY)) return 1;
+ if(!strcmp(name,PEM_STRING_EVP_PKEY))
+ {
+ int slen;
+ const EVP_PKEY_ASN1_METHOD *ameth;
+ if(!strcmp(nm,PEM_STRING_PKCS8))
+ return 1;
+ if(!strcmp(nm,PEM_STRING_PKCS8INF))
+ return 1;
+ slen = pem_check_suffix(nm, "PRIVATE KEY");
+ if (slen > 0)
+ {
+ 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 */
if(!strcmp(nm,PEM_STRING_X509_OLD) &&
@@ -783,16 +789,17 @@ err:
* 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 suffix_len = strlen(suffix);
- char *p;
+ const char *p;
if (suffix_len + 1 >= pem_len)
return 0;
- if (strcmp(pem_str - suffix_len, suffix))
+ p = pem_str + pem_len - suffix_len;
+ if (strcmp(p, suffix))
return 0;
- p = pem_str - suffix_len - 1;
+ p--;
if (*p != ' ')
return 0;
return p - pem_str;
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