summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>1999-12-23 02:02:42 +0000
committerDr. Stephen Henson <steve@openssl.org>1999-12-23 02:02:42 +0000
commit525f51f6c98751de4db3b81789044d32e3686cda (patch)
tree6dd7f1baa5eb540c8e98a6401c5bd57709f1a1e9 /crypto
parent78baa17ad04922f996514f24f3823b9b8d4ec434 (diff)
Add PKCS#8 utility functions and add PBE options.
Diffstat (limited to 'crypto')
-rw-r--r--crypto/asn1/Makefile.ssl7
-rw-r--r--crypto/objects/obj_dat.h52
-rw-r--r--crypto/objects/objects.h12
-rw-r--r--crypto/pem/pem.h27
-rw-r--r--crypto/pem/pem_err.c3
-rw-r--r--crypto/pem/pem_lib.c141
6 files changed, 210 insertions, 32 deletions
diff --git a/crypto/asn1/Makefile.ssl b/crypto/asn1/Makefile.ssl
index f4e9f83cc0..74f057b5e3 100644
--- a/crypto/asn1/Makefile.ssl
+++ b/crypto/asn1/Makefile.ssl
@@ -223,6 +223,13 @@ a_meth.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
a_meth.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
a_meth.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
a_meth.o: ../cryptlib.h
+a_null.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+a_null.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+a_null.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
+a_null.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+a_null.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
+a_null.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h
+a_null.o: ../cryptlib.h
a_object.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
a_object.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
a_object.o: ../../include/openssl/crypto.h ../../include/openssl/e_os.h
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index c45574d218..27e3e5e297 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -62,7 +62,7 @@
*/
#define NUM_NID 181
-#define NUM_SN 128
+#define NUM_SN 140
#define NUM_LN 175
#define NUM_OBJ 152
@@ -233,10 +233,10 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
&(lvalues[47]),0},
{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9,
&(lvalues[56]),0},
-{"pbeWithMD2AndDES-CBC","pbeWithMD2AndDES-CBC",
- NID_pbeWithMD2AndDES_CBC,9,&(lvalues[65]),0},
-{"pbeWithMD5AndDES-CBC","pbeWithMD5AndDES-CBC",
- NID_pbeWithMD5AndDES_CBC,9,&(lvalues[74]),0},
+{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9,
+ &(lvalues[65]),0},
+{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9,
+ &(lvalues[74]),0},
{"X500","X500",NID_X500,1,&(lvalues[83]),0},
{"X509","X509",NID_X509,2,&(lvalues[84]),0},
{"CN","commonName",NID_commonName,3,&(lvalues[86]),0},
@@ -312,8 +312,8 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
&(lvalues[355]),0},
{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[364]),0},
{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[369]),0},
-{"pbeWithSHA1AndRC2-CBC","pbeWithSHA1AndRC2-CBC",
- NID_pbeWithSHA1AndRC2_CBC,9,&(lvalues[374]),0},
+{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC,
+ 9,&(lvalues[374]),0},
{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[383]),0},
{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[392]),0},
{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9,
@@ -417,19 +417,17 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
{"invalidityDate","Invalidity Date",NID_invalidity_date,3,
&(lvalues[733]),0},
{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[736]),0},
-{"pbeWithSHA1And128BitRC4","pbeWithSHA1And128BitRC4",
+{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4",
NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[741]),0},
-{"pbeWithSHA1And40BitRC4","pbeWithSHA1And40BitRC4",
+{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4",
NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[751]),0},
-{"pbeWithSHA1And3-KeyTripleDES-CBC",
- "pbeWithSHA1And3-KeyTripleDES-CBC",
+{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC",
NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[761]),0},
-{"pbeWithSHA1And2-KeyTripleDES-CBC",
- "pbeWithSHA1And2-KeyTripleDES-CBC",
+{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC",
NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[771]),0},
-{"pbeWithSHA1And128BitRC2-CBC","pbeWithSHA1And128BitRC2-CBC",
+{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC",
NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[781]),0},
-{"pbeWithSHA1And40BitRC2-CBC","pbeWithSHA1And40BitRC2-CBC",
+{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC",
NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[791]),0},
{"keyBag","keyBag",NID_keyBag,11,&(lvalues[801]),0},
{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag,
@@ -455,12 +453,12 @@ static ASN1_OBJECT nid_objs[NUM_NID]={
{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL},
{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9,
&(lvalues[957]),0},
-{"pbeWithMD2AndRC2-CBC","pbeWithMD2AndRC2-CBC",
- NID_pbeWithMD2AndRC2_CBC,9,&(lvalues[966]),0},
-{"pbeWithMD5AndRC2-CBC","pbeWithMD5AndRC2-CBC",
- NID_pbeWithMD5AndRC2_CBC,9,&(lvalues[975]),0},
-{"pbeWithSHA1AndDES-CBC","pbeWithSHA1AndDES-CBC",
- NID_pbeWithSHA1AndDES_CBC,9,&(lvalues[984]),0},
+{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9,
+ &(lvalues[966]),0},
+{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9,
+ &(lvalues[975]),0},
+{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9,
+ &(lvalues[984]),0},
{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10,
&(lvalues[993]),0},
{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1003]),0},
@@ -522,6 +520,18 @@ static ASN1_OBJECT *sn_objs[NUM_SN]={
&(nid_objs[17]),/* "O" */
&(nid_objs[178]),/* "OCSP" */
&(nid_objs[18]),/* "OU" */
+&(nid_objs[ 9]),/* "PBE-MD2-DES" */
+&(nid_objs[168]),/* "PBE-MD2-RC2-64" */
+&(nid_objs[10]),/* "PBE-MD5-DES" */
+&(nid_objs[169]),/* "PBE-MD5-RC2-64" */
+&(nid_objs[147]),/* "PBE-SHA1-2DES" */
+&(nid_objs[146]),/* "PBE-SHA1-3DES" */
+&(nid_objs[170]),/* "PBE-SHA1-DES" */
+&(nid_objs[148]),/* "PBE-SHA1-RC2-128" */
+&(nid_objs[149]),/* "PBE-SHA1-RC2-40" */
+&(nid_objs[68]),/* "PBE-SHA1-RC2-64" */
+&(nid_objs[144]),/* "PBE-SHA1-RC4-128" */
+&(nid_objs[145]),/* "PBE-SHA1-RC4-40" */
&(nid_objs[127]),/* "PKIX" */
&(nid_objs[98]),/* "RC2-40-CBC" */
&(nid_objs[166]),/* "RC2-64-CBC" */
diff --git a/crypto/objects/objects.h b/crypto/objects/objects.h
index 325128813d..644716b16e 100644
--- a/crypto/objects/objects.h
+++ b/crypto/objects/objects.h
@@ -110,10 +110,12 @@ extern "C" {
#define NID_md5WithRSAEncryption 8
#define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L
+#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES"
#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC"
#define NID_pbeWithMD2AndDES_CBC 9
#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L
+#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES"
#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC"
#define NID_pbeWithMD5AndDES_CBC 10
#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L
@@ -380,6 +382,7 @@ extern "C" {
#define OBJ_dsa_2 OBJ_algorithm,12L
/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64"
#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC"
#define NID_pbeWithSHA1AndRC2_CBC 68
#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L
@@ -767,26 +770,32 @@ extern "C" {
#define OBJ_pkcs12 OBJ_pkcs,12L
#define OBJ_pkcs12_pbeids OBJ_pkcs12, 1
+#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128"
#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4"
#define NID_pbe_WithSHA1And128BitRC4 144
#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L
+#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40"
#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4"
#define NID_pbe_WithSHA1And40BitRC4 145
#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES"
#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC"
#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146
#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES"
#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC"
#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147
#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L
+#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128"
#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC"
#define NID_pbe_WithSHA1And128BitRC2_CBC 148
#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L
+#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40"
#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC"
#define NID_pbe_WithSHA1And40BitRC2_CBC 149
#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L
@@ -878,14 +887,17 @@ extern "C" {
#define NID_SMIMECapabilities 167
#define OBJ_SMIMECapabilities OBJ_pkcs9,15L
+#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64"
#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC"
#define NID_pbeWithMD2AndRC2_CBC 168
#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L
+#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64"
#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC"
#define NID_pbeWithMD5AndRC2_CBC 169
#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L
+#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES"
#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC"
#define NID_pbeWithSHA1AndDES_CBC 170
#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L
diff --git a/crypto/pem/pem.h b/crypto/pem/pem.h
index 8ae1e9acc7..26c313b2ef 100644
--- a/crypto/pem/pem.h
+++ b/crypto/pem/pem.h
@@ -574,10 +574,34 @@ DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
char *kstr,int klen, pem_password_cb *cd, void *u);
+
#endif /* SSLEAY_MACROS */
@@ -589,6 +613,8 @@ int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
/* Error codes for the PEM functions. */
/* Function codes. */
+#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120
+#define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121
#define PEM_F_DEF_CALLBACK 100
#define PEM_F_LOAD_IV 101
#define PEM_F_PEM_ASN1_READ 102
@@ -596,6 +622,7 @@ int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
#define PEM_F_PEM_ASN1_WRITE 104
#define PEM_F_PEM_ASN1_WRITE_BIO 105
#define PEM_F_PEM_DO_HEADER 106
+#define PEM_F_PEM_F_DO_PK8KEY_FP 122
#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118
#define PEM_F_PEM_GET_EVP_CIPHER_INFO 107
#define PEM_F_PEM_READ 108
diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c
index fa70f60998..642129da20 100644
--- a/crypto/pem/pem_err.c
+++ b/crypto/pem/pem_err.c
@@ -65,6 +65,8 @@
#ifndef NO_ERR
static ERR_STRING_DATA PEM_str_functs[]=
{
+{ERR_PACK(0,PEM_F_D2I_PKCS8PRIVATEKEY_BIO,0), "d2i_PKCS8PrivateKey_bio"},
+{ERR_PACK(0,PEM_F_D2I_PKCS8PRIVATEKEY_FP,0), "d2i_PKCS8PrivateKey_fp"},
{ERR_PACK(0,PEM_F_DEF_CALLBACK,0), "DEF_CALLBACK"},
{ERR_PACK(0,PEM_F_LOAD_IV,0), "LOAD_IV"},
{ERR_PACK(0,PEM_F_PEM_ASN1_READ,0), "PEM_ASN1_read"},
@@ -72,6 +74,7 @@ static ERR_STRING_DATA PEM_str_functs[]=
{ERR_PACK(0,PEM_F_PEM_ASN1_WRITE,0), "PEM_ASN1_write"},
{ERR_PACK(0,PEM_F_PEM_ASN1_WRITE_BIO,0), "PEM_ASN1_write_bio"},
{ERR_PACK(0,PEM_F_PEM_DO_HEADER,0), "PEM_do_header"},
+{ERR_PACK(0,PEM_F_PEM_F_DO_PK8KEY_FP,0), "PEM_F_DO_PK8KEY_FP"},
{ERR_PACK(0,PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY,0), "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
{ERR_PACK(0,PEM_F_PEM_GET_EVP_CIPHER_INFO,0), "PEM_get_EVP_CIPHER_INFO"},
{ERR_PACK(0,PEM_F_PEM_READ,0), "PEM_read"},
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
index 0bc1752482..2bafb5e735 100644
--- a/crypto/pem/pem_lib.c
+++ b/crypto/pem/pem_lib.c
@@ -76,6 +76,14 @@ const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT;
static int def_callback(char *buf, int num, int w, void *userdata);
static int load_iv(unsigned char **fromp,unsigned char *to, int num);
static int check_pem(const char *nm, const char *name);
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder,
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
+static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder,
+ int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u);
static int def_callback(char *buf, int num, int w, void *userdata)
{
@@ -247,7 +255,7 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
X509_SIG *p8;
int klen;
char psbuf[PEM_BUFSIZE];
- p8 = d2i_X509_SIG((X509_SIG **)x, &p, len);
+ p8 = d2i_X509_SIG(NULL, &p, len);
if(!p8) goto p8err;
if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
else klen=def_callback(psbuf,PEM_BUFSIZE,0,u);
@@ -260,6 +268,10 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x,
X509_SIG_free(p8);
if(!p8inf) goto p8err;
ret = (char *)EVP_PKCS82PKEY(p8inf);
+ if(x) {
+ if(*x) EVP_PKEY_free((EVP_PKEY *)*x);
+ *x = ret;
+ }
PKCS8_PRIV_KEY_INFO_free(p8inf);
}
} else ret=d2i(x,&p,len);
@@ -772,16 +784,44 @@ err:
return(0);
}
-/* This function writes a private key in PKCS#8 format: it is a "drop in"
- * replacement for PEM_write_bio_PrivateKey(). As usual if 'enc' is NULL then
- * it uses the unencrypted private key form. It uses PKCS#5 v2.0 password based
- * encryption algorithms.
+/* These functions write a private key in PKCS#8 format: it is a "drop in"
+ * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc'
+ * is NULL then it uses the unencrypted private key form. The 'nid' versions
+ * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0.
*/
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
char *kstr, int klen,
pem_password_cb *cb, void *u)
{
+ return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
X509_SIG *p8;
PKCS8_PRIV_KEY_INFO *p8inf;
char buf[PEM_BUFSIZE];
@@ -791,7 +831,7 @@ int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
return 0;
}
- if(enc) {
+ if(enc || (nid != -1)) {
if(!kstr) {
if(!cb) klen = def_callback(buf, PEM_BUFSIZE, 1, u);
else klen = cb(buf, PEM_BUFSIZE, 1, u);
@@ -804,30 +844,109 @@ int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
kstr = buf;
}
- p8 = PKCS8_encrypt(-1, enc, kstr, klen, NULL, 0, 0, p8inf);
+ p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf);
if(kstr == buf) memset(buf, 0, klen);
PKCS8_PRIV_KEY_INFO_free(p8inf);
- ret = PEM_write_bio_PKCS8(bp, p8);
+ if(isder) ret = i2d_PKCS8_bio(bp, p8);
+ else ret = PEM_write_bio_PKCS8(bp, p8);
X509_SIG_free(p8);
return ret;
} else {
- ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
+ if(isder) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf);
+ else ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return ret;
}
}
+
+/* Finally the DER version to read PKCS#8 encrypted private keys. It has to be
+ * here to access the default callback.
+ */
+
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ X509_SIG *p8 = NULL;
+ int klen;
+ EVP_PKEY *ret;
+ char psbuf[PEM_BUFSIZE];
+ p8 = d2i_PKCS8_bio(bp, NULL);
+ if(!p8) return NULL;
+ if (cb) klen=cb(psbuf,PEM_BUFSIZE,0,u);
+ else klen=def_callback(psbuf,PEM_BUFSIZE,0,u);
+ if (klen <= 0) {
+ PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ);
+ X509_SIG_free(p8);
+ return NULL;
+ }
+ p8inf = M_PKCS8_decrypt(p8, psbuf, klen);
+ X509_SIG_free(p8);
+ if(!p8inf) return NULL;
+ ret = EVP_PKCS82PKEY(p8inf);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if(!ret) return NULL;
+ if(x) {
+ if(*x) EVP_PKEY_free(*x);
+ *x = ret;
+ }
+ return ret;
+}
+
#ifndef NO_FP_API
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u);
+}
+
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u);
+}
+
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
+ return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u);
+}
+
int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
char *kstr, int klen, pem_password_cb *cb, void *u)
{
+ return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u);
+}
+
+static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER *enc,
+ char *kstr, int klen,
+ pem_password_cb *cb, void *u)
+{
BIO *bp;
int ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- PEMerr(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY,ERR_R_BUF_LIB);
+ PEMerr(PEM_F_PEM_F_DO_PK8KEY_FP,ERR_R_BUF_LIB);
return(0);
}
- ret = PEM_write_bio_PKCS8PrivateKey(bp, x, enc, kstr, klen, cb, u);
+ ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
BIO_free(bp);
return ret;
}
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u)
+{
+ BIO *bp;
+ EVP_PKEY *ret;
+ if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
+ PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP,ERR_R_BUF_LIB);
+ return NULL;
+ }
+ ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
+ BIO_free(bp);
+ return ret;
+}
+
#endif