Add PKCS#8 utility functions and add PBE options.
This commit is contained in:
parent
78baa17ad0
commit
525f51f6c9
12 changed files with 303 additions and 39 deletions
6
CHANGES
6
CHANGES
|
@ -4,6 +4,12 @@
|
|||
|
||||
Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
|
||||
|
||||
*) Add a bunch of DER and PEM functions to handle PKCS#8 format private
|
||||
keys. Add some short names for PKCS#8 PBE algorithms and allow them
|
||||
to be specified on the command line for the pkcs8 and pkcs12 utilities.
|
||||
Update documentation.
|
||||
[Steve Henson]
|
||||
|
||||
*) Support for ASN1 "NULL" type. This could be handled before by using
|
||||
ASN1_TYPE but there wasn't any function that would try to read a NULL
|
||||
and produce an error if it couldn't. For compatibility we also have
|
||||
|
|
|
@ -104,6 +104,7 @@ int MAIN(int argc, char **argv)
|
|||
int twopass = 0;
|
||||
int keytype = 0;
|
||||
int cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
|
||||
int key_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
|
||||
int ret = 1;
|
||||
int macver = 1;
|
||||
int noprompt = 0;
|
||||
|
@ -143,7 +144,27 @@ int MAIN(int argc, char **argv)
|
|||
else if (!strcmp (*args, "-maciter"))
|
||||
maciter = PKCS12_DEFAULT_ITER;
|
||||
else if (!strcmp (*args, "-nodes")) enc=NULL;
|
||||
else if (!strcmp (*args, "-inkey")) {
|
||||
else if (!strcmp (*args, "-certpbe")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
cert_pbe=OBJ_txt2nid(*args);
|
||||
if(cert_pbe == NID_undef) {
|
||||
BIO_printf(bio_err,
|
||||
"Unknown PBE algorithm %s\n", *args);
|
||||
badarg = 1;
|
||||
}
|
||||
} else badarg = 1;
|
||||
} else if (!strcmp (*args, "-keypbe")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
key_pbe=OBJ_txt2nid(*args);
|
||||
if(key_pbe == NID_undef) {
|
||||
BIO_printf(bio_err,
|
||||
"Unknown PBE algorithm %s\n", *args);
|
||||
badarg = 1;
|
||||
}
|
||||
} else badarg = 1;
|
||||
} else if (!strcmp (*args, "-inkey")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
keyname = *args;
|
||||
|
@ -224,6 +245,8 @@ int MAIN(int argc, char **argv)
|
|||
BIO_printf (bio_err, "-maciter use MAC iteration\n");
|
||||
BIO_printf (bio_err, "-twopass separate MAC, encryption passwords\n");
|
||||
BIO_printf (bio_err, "-descert encrypt PKCS#12 certificates with triple DES (default RC2-40)\n");
|
||||
BIO_printf (bio_err, "-certpbe alg specify certificate PBE algorithm (default RC2-40)\n");
|
||||
BIO_printf (bio_err, "-keypbe alg specify private key PBE algorithm (default 3DES)\n");
|
||||
BIO_printf (bio_err, "-keyex set MS key exchange type\n");
|
||||
BIO_printf (bio_err, "-keysig set MS key signature type\n");
|
||||
BIO_printf (bio_err, "-password p set import/export password (NOT RECOMMENDED)\n");
|
||||
|
@ -391,8 +414,7 @@ int MAIN(int argc, char **argv)
|
|||
p8 = EVP_PKEY2PKCS8 (key);
|
||||
EVP_PKEY_free(key);
|
||||
if(keytype) PKCS8_add_keyusage(p8, keytype);
|
||||
bag = PKCS12_MAKE_SHKEYBAG(NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
|
||||
cpass, -1, NULL, 0, iter, p8);
|
||||
bag = PKCS12_MAKE_SHKEYBAG(key_pbe, cpass, -1, NULL, 0, iter, p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
if (name) PKCS12_add_friendlyname (bag, name, -1);
|
||||
PKCS12_add_localkeyid (bag, keyid, keyidlen);
|
||||
|
|
11
apps/pkcs8.c
11
apps/pkcs8.c
|
@ -99,6 +99,16 @@ int MAIN(int argc, char **argv)
|
|||
badarg = 1;
|
||||
}
|
||||
} else badarg = 1;
|
||||
} else if (!strcmp(*args,"-v1")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
pbe_nid=OBJ_txt2nid(*args);
|
||||
if(pbe_nid == NID_undef) {
|
||||
BIO_printf(bio_err,
|
||||
"Unknown PBE algorithm %s\n", *args);
|
||||
badarg = 1;
|
||||
}
|
||||
} else badarg = 1;
|
||||
} else if (!strcmp(*args,"-inform")) {
|
||||
if (args[1]) {
|
||||
args++;
|
||||
|
@ -139,6 +149,7 @@ int MAIN(int argc, char **argv)
|
|||
BIO_printf (bio_err, "-noiter use 1 as iteration count\n");
|
||||
BIO_printf (bio_err, "-nocrypt use or expect unencrypted private key\n");
|
||||
BIO_printf (bio_err, "-v2 alg use PKCS#5 v2.0 and cipher \"alg\"\n");
|
||||
BIO_printf (bio_err, "-v1 obj use PKCS#5 v1.5 and cipher \"alg\"\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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,15 +784,43 @@ 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;
|
||||
|
@ -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
|
||||
|
|
|
@ -16,6 +16,7 @@ B<openssl> B<pkcs8>
|
|||
[B<-nocrypt>]
|
||||
[B<-nooct>]
|
||||
[B<-v2 alg>]
|
||||
[B<-v1 alg>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
@ -89,6 +90,11 @@ private keys with OpenSSL then this doesn't matter.
|
|||
The B<alg> argument is the encryption algorithm to use, valid values include
|
||||
B<des>, B<des3> and B<rc2>. It is recommended that B<des3> is used.
|
||||
|
||||
=item B<-v1 alg>
|
||||
|
||||
This option specifies a PKCS#5 v1.5 or PKCS#12 algorithm to use. A complete
|
||||
list of possible algorithms is included below.
|
||||
|
||||
=back
|
||||
|
||||
=head1 NOTES
|
||||
|
@ -120,6 +126,33 @@ It is possible to write out DER encoded encrypted private keys in
|
|||
PKCS#8 format because the encryption details are included at an ASN1
|
||||
level whereas the traditional format includes them at a PEM level.
|
||||
|
||||
=head1 PKCS#5 v1.5 and PKCS#12 algorithms.
|
||||
|
||||
Various algorithms can be used with the B<-v1> command line option,
|
||||
including PKCS#5 v1.5 and PKCS#12. These are described in more detail
|
||||
below.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<PBE-MD2-DES PBE-MD5-DES>
|
||||
|
||||
These algorithms were included in the original PKCS#5 v1.5 specification.
|
||||
They only offer 56 bits of protection since they both use DES.
|
||||
|
||||
=item B<PBE-SHA1-RC2-64 PBE-MD2-RC2-64 PBE-MD5-RC2-64 PBE-SHA1-DES>
|
||||
|
||||
These algorithms are not mentioned in the original PKCS#5 v1.5 specification
|
||||
but they use the same key derivation algorithm and are supported by some
|
||||
software. They are mentioned in PKCS#5 v1.5. They use either 64 bit RC2 or
|
||||
56 bit DES.
|
||||
|
||||
=item B<PBE-SHA1-RC4-128 PBE-SHA1-RC4-40 PBE-SHA1-3DES PBE-SHA1-2DES PBE-SHA1-RC2-128 PBE-SHA1-RC2-40>
|
||||
|
||||
These algorithms use the PKCS#12 password based encryption algorithm and
|
||||
allow strong encryption algorithms like triple DES or 128 bit RC2 to be used.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
Convert a private from traditional to PKCS#5 v2.0 format using triple
|
||||
|
@ -132,6 +165,11 @@ Convert a private key to PKCS#8 using a PKCS#5 1.5 compatible algorithm
|
|||
|
||||
openssl pkcs8 -in key.pem -topk8 -out enckey.pem
|
||||
|
||||
Convert a private key to PKCS#8 using a PKCS#12 compatible algorithm
|
||||
(3DES):
|
||||
|
||||
openssl pkcs8 -in key.pem -topk8 -out enckey.pem -v1 PBE-SHA1-3DES
|
||||
|
||||
Read a DER unencrypted PKCS#8 format private key:
|
||||
|
||||
openssl pkcs8 -inform DER -nocrypt -in key.der -out key.pem
|
||||
|
@ -150,9 +188,6 @@ reasonably accurate at least as far as these algorithms are concerned.
|
|||
|
||||
=head1 BUGS
|
||||
|
||||
It isn't possible to produce keys encrypted using PKCS#5 v1.5 algorithms
|
||||
other than B<pbeWithMD5AndDES-CBC> using this utility.
|
||||
|
||||
There should be an option that prints out the encryption algorithm
|
||||
in use and other details such as the iteration count.
|
||||
|
||||
|
|
|
@ -2137,3 +2137,15 @@ CRYPTO_set_mem_debug_functions 2161
|
|||
CRYPTO_pop_info 2162
|
||||
CRYPTO_push_info_ 2163
|
||||
CRYPTO_set_mem_debug_options 2164
|
||||
PEM_write_PKCS8PrivateKey_nid 2165
|
||||
PEM_write_bio_PKCS8PrivateKey_nid 2166
|
||||
d2i_PKCS8PrivateKey_bio 2167
|
||||
ASN1_NULL_free 2168
|
||||
d2i_ASN1_NULL 2169
|
||||
ASN1_NULL_new 2170
|
||||
i2d_PKCS8PrivateKey_bio 2171
|
||||
i2d_PKCS8PrivateKey_fp 2172
|
||||
i2d_ASN1_NULL 2173
|
||||
i2d_PKCS8PrivateKey_nid_fp 2174
|
||||
d2i_PKCS8PrivateKey_fp 2175
|
||||
i2d_PKCS8PrivateKey_nid_bio 2176
|
||||
|
|
|
@ -450,7 +450,7 @@ void ERR_load_${lib}_strings(void)
|
|||
#ifdef ${lib}_LIB_NAME
|
||||
${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code,0,0);
|
||||
ERR_load_strings(0,${lib}_lib_name);
|
||||
#endif;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue