From ecbe07817ab8fff2aca97eeb69fabdd5c54b4bda Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 31 Dec 2000 01:13:04 +0000 Subject: [PATCH] Rewrite PKCS#12 code and remove some of the old horrible macros. Fix two evil ASN1 bugs. Attempt to use 'ctx' when NULL if input is indefinite length constructed in asn1_check_tlen() and invalid pointer to ASN1_TYPE when reusing existing structure (this took *ages* to find because the new PKCS#12 code triggered it). --- CHANGES | 8 ++++ apps/pkcs12.c | 20 ++++----- apps/pkcs8.c | 2 +- crypto/asn1/asn1.h | 13 ++++-- crypto/asn1/asn_pack.c | 4 +- crypto/asn1/tasn_dec.c | 18 ++++---- crypto/pem/pem_lib.c | 4 +- crypto/pkcs12/p12_add.c | 75 +++++++++++++++++++++++++-------- crypto/pkcs12/p12_asn.c | 11 +++++ crypto/pkcs12/p12_crt.c | 6 +-- crypto/pkcs12/p12_decr.c | 51 ++++++++--------------- crypto/pkcs12/p12_kiss.c | 10 ++--- crypto/pkcs12/p12_npas.c | 10 ++--- crypto/pkcs12/p12_utl.c | 36 +++++++++++++--- crypto/pkcs12/pkcs12.h | 89 +++++++++++++++++----------------------- crypto/pkcs7/pkcs7.h | 1 + 16 files changed, 209 insertions(+), 149 deletions(-) diff --git a/CHANGES b/CHANGES index e183059251..667b0f74a6 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,14 @@ files to get correct declarations of the ASN.1 item variables. [Richard Levitte] + *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many + PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs: + asn1_check_tlen() would sometimes attempt to use 'ctx' when it was + NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i(). + New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant + ASN1_ITEM and no wrapper functions. + [Steve Henson] + *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These replace the old function pointer based I/O routines. Change most of the *_d2i_bio() and *_d2i_fp() functions to use these. diff --git a/apps/pkcs12.c b/apps/pkcs12.c index 365a8ada93..46ae93d4da 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -521,7 +521,7 @@ int MAIN(int argc, char **argv) for(i = 0; i < sk_X509_num(certs); i++) { X509 *cert = NULL; cert = sk_X509_value(certs, i); - bag = M_PKCS12_x5092certbag(cert); + bag = PKCS12_x5092certbag(cert); /* If it matches private key set id */ if(cert == ucert) { if(name) PKCS12_add_friendlyname(bag, name, -1); @@ -592,9 +592,9 @@ int MAIN(int argc, char **argv) CRYPTO_push_info("building pkcs12"); #endif - p12 = PKCS12_init (NID_pkcs7_data); + p12 = PKCS12_init(NID_pkcs7_data); - M_PKCS12_pack_authsafes (p12, safes); + PKCS12_pack_authsafes(p12, safes); sk_PKCS7_pop_free(safes, PKCS7_free); safes = NULL; @@ -702,20 +702,20 @@ int dump_certs_keys_p12 (BIO *out, PKCS12 *p12, char *pass, int i, bagnid; PKCS7 *p7; - if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; + if (!( asafes = PKCS12_unpack_authsafes(p12))) return 0; for (i = 0; i < sk_PKCS7_num (asafes); i++) { p7 = sk_PKCS7_value (asafes, i); bagnid = OBJ_obj2nid (p7->type); if (bagnid == NID_pkcs7_data) { - bags = M_PKCS12_unpack_p7data (p7); + bags = PKCS12_unpack_p7data(p7); if (options & INFO) BIO_printf (bio_err, "PKCS7 Data\n"); } else if (bagnid == NID_pkcs7_encrypted) { if (options & INFO) { - BIO_printf (bio_err, "PKCS7 Encrypted data: "); - alg_print (bio_err, + BIO_printf(bio_err, "PKCS7 Encrypted data: "); + alg_print(bio_err, p7->d.encrypted->enc_data->algorithm); } - bags = M_PKCS12_unpack_p7encdata (p7, pass, passlen); + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); } else continue; if (!bags) return 0; if (!dump_certs_pkeys_bags (out, bags, pass, passlen, @@ -770,7 +770,7 @@ int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass, } if (options & NOKEYS) return 1; print_attribs (out, bag->attrib, "Bag Attributes"); - if (!(p8 = M_PKCS12_decrypt_skey (bag, pass, passlen))) + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) return 0; if (!(pkey = EVP_PKCS82PKEY (p8))) return 0; print_attribs (out, p8->attributes, "Key Attributes"); @@ -788,7 +788,7 @@ int dump_certs_pkeys_bag (BIO *out, PKCS12_SAFEBAG *bag, char *pass, print_attribs (out, bag->attrib, "Bag Attributes"); if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) return 1; - if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; + if (!(x509 = PKCS12_certbag2x509(bag))) return 0; dump_cert_text (out, x509); PEM_write_bio_X509 (out, x509); X509_free(x509); diff --git a/apps/pkcs8.c b/apps/pkcs8.c index bd1697a325..3633590874 100644 --- a/apps/pkcs8.c +++ b/apps/pkcs8.c @@ -325,7 +325,7 @@ int MAIN(int argc, char **argv) p8pass = pass; EVP_read_pw_string(pass, 50, "Enter Password:", 0); } - p8inf = M_PKCS8_decrypt(p8, p8pass, strlen(p8pass)); + p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass)); X509_SIG_free(p8); } diff --git a/crypto/asn1/asn1.h b/crypto/asn1/asn1.h index 0bc22d7064..4646f05da5 100644 --- a/crypto/asn1/asn1.h +++ b/crypto/asn1/asn1.h @@ -63,6 +63,7 @@ #ifndef NO_BIO #include #endif +#include #include #include #include @@ -307,17 +308,21 @@ typedef struct ASN1_VALUE_st ASN1_VALUE; #define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ type *d2i_##name(type **a, unsigned char **in, long len); \ int i2d_##name(type *a, unsigned char **out); \ - OPENSSL_EXTERN const ASN1_ITEM itname##_it; + DECLARE_ASN1_ITEM(itname) #define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ type *d2i_##name(type **a, const unsigned char **in, long len); \ int i2d_##name(const type *a, unsigned char **out); \ - OPENSSL_EXTERN const ASN1_ITEM name##_it; + DECLARE_ASN1_ITEM(name) #define DECLARE_ASN1_FUNCTIONS_const(name) \ name *name##_new(void); \ void name##_free(name *a); +#define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + + /* Parameters used by ASN1_STRING_print_ex() */ /* These determine which characters to escape: @@ -863,9 +868,9 @@ STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(), unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf, int *len ); void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)()); -void *ASN1_unpack_item(ASN1_STRING *oct, const ASN1_ITEM *it); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct); -ASN1_STRING *ASN1_pack_item(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); void ASN1_STRING_set_default_mask(unsigned long mask); int ASN1_STRING_set_default_mask_asc(char *p); diff --git a/crypto/asn1/asn_pack.c b/crypto/asn1/asn_pack.c index e62eed2afa..e6051db2dc 100644 --- a/crypto/asn1/asn_pack.c +++ b/crypto/asn1/asn_pack.c @@ -149,7 +149,7 @@ ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_STRING **oct) /* ASN1_ITEM versions of the above */ -ASN1_STRING *ASN1_pack_item(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) { ASN1_STRING *octmp; @@ -179,7 +179,7 @@ ASN1_STRING *ASN1_pack_item(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) /* Extract an ASN1 object from an ASN1_STRING */ -void *ASN1_unpack_item(ASN1_STRING *oct, const ASN1_ITEM *it) +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it) { unsigned char *p; void *ret; diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 940e6af6b3..15ebf267f2 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -658,7 +658,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, unsigned char *cont, int len, int utype, char if(!*pval) { typ = ASN1_TYPE_new(); *pval = (ASN1_VALUE *)typ; - } else typ = (ASN1_TYPE *)pval; + } else typ = (ASN1_TYPE *)*pval; if(utype != typ->type) ASN1_TYPE_set(typ, utype, NULL); pval = (ASN1_VALUE **)&typ->value.ptr; } @@ -865,14 +865,14 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *i ctx->ptag = ptag; ctx->hdrlen = p - q; ctx->valid = 1; - } - /* If definite length, length + header can't exceed total - * amount of data available. - */ - if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); - asn1_tlc_clear(ctx); - return 0; + /* If definite length, length + header can't exceed total + * amount of data available. + */ + if(!(i & 1) && ((plen + ctx->hdrlen) > len)) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } } } diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index a17c3ed57f..5d105242ac 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -274,7 +274,7 @@ char *PEM_ASN1_read_bio(char *(*d2i)(), const char *name, BIO *bp, char **x, PEM_R_BAD_PASSWORD_READ); goto err; } - p8inf = M_PKCS8_decrypt(p8, psbuf, klen); + p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if(!p8inf) goto p8err; ret = (char *)EVP_PKCS82PKEY(p8inf); @@ -890,7 +890,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo X509_SIG_free(p8); return NULL; } - p8inf = M_PKCS8_decrypt(p8, psbuf, klen); + p8inf = PKCS8_decrypt(p8, psbuf, klen); X509_SIG_free(p8); if(!p8inf) return NULL; ret = EVP_PKCS82PKEY(p8inf); diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c index b563656895..2d275c4c2c 100644 --- a/crypto/pkcs12/p12_add.c +++ b/crypto/pkcs12/p12_add.c @@ -62,21 +62,21 @@ /* Pack an object into an OCTET STRING and turn into a safebag */ -PKCS12_SAFEBAG *PKCS12_pack_safebag (char *obj, int (*i2d)(), int nid1, +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1, int nid2) { PKCS12_BAGS *bag; PKCS12_SAFEBAG *safebag; - if (!(bag = PKCS12_BAGS_new ())) { + if (!(bag = PKCS12_BAGS_new())) { PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); return NULL; } bag->type = OBJ_nid2obj(nid1); - if (!ASN1_pack_string(obj, i2d, &bag->value.octet)) { + if (!ASN1_item_pack(obj, it, &bag->value.octet)) { PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); return NULL; } - if (!(safebag = PKCS12_SAFEBAG_new ())) { + if (!(safebag = PKCS12_SAFEBAG_new())) { PKCS12err(PKCS12_F_PKCS12_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); return NULL; } @@ -87,7 +87,7 @@ PKCS12_SAFEBAG *PKCS12_pack_safebag (char *obj, int (*i2d)(), int nid1, /* Turn PKCS8 object into a keybag */ -PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG (PKCS8_PRIV_KEY_INFO *p8) +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) { PKCS12_SAFEBAG *bag; if (!(bag = PKCS12_SAFEBAG_new())) { @@ -101,14 +101,14 @@ PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG (PKCS8_PRIV_KEY_INFO *p8) /* Turn PKCS8 object into a shrouded keybag */ -PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG (int pbe_nid, const char *pass, +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8) { PKCS12_SAFEBAG *bag; /* Set up the safe bag */ - if (!(bag = PKCS12_SAFEBAG_new ())) { + if (!(bag = PKCS12_SAFEBAG_new())) { PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); return NULL; } @@ -125,7 +125,7 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG (int pbe_nid, const char *pass, } /* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ -PKCS7 *PKCS12_pack_p7data (STACK_OF(PKCS12_SAFEBAG) *sk) +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) { PKCS7 *p7; if (!(p7 = PKCS7_new())) { @@ -138,18 +138,23 @@ PKCS7 *PKCS12_pack_p7data (STACK_OF(PKCS12_SAFEBAG) *sk) return NULL; } - if (!ASN1_seq_pack_PKCS12_SAFEBAG(sk, i2d_PKCS12_SAFEBAG, - &p7->d.data->data, - &p7->d.data->length)) { + if (!ASN1_item_pack(sk, &PKCS12_SAFEBAGS_it, &p7->d.data)) { PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); return NULL; } return p7; } +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) +{ + if(!PKCS7_type_is_data(p7)) return NULL; + return ASN1_item_unpack(p7->d.data, &PKCS12_SAFEBAGS_it); +} + /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ -PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen, +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags) { @@ -164,7 +169,7 @@ PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); return NULL; } - if (!(pbe = PKCS5_pbe_set (pbe_nid, iter, salt, saltlen))) { + if (!(pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen))) { PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); return NULL; } @@ -172,8 +177,8 @@ PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen, p7->d.encrypted->enc_data->algorithm = pbe; M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); if (!(p7->d.encrypted->enc_data->enc_data = - PKCS12_i2d_encrypt (pbe, i2d_PKCS12_SAFEBAG, pass, passlen, - (char *)bags, 1))) { + PKCS12_item_i2d_encrypt(pbe, &PKCS12_SAFEBAGS_it, pass, passlen, + bags, 1))) { PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); return NULL; } @@ -181,6 +186,15 @@ PKCS7 *PKCS12_pack_p7encdata (int pbe_nid, const char *pass, int passlen, return p7; } +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen) +{ + if(!PKCS7_type_is_encrypted(p7)) return NULL; + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + &PKCS12_SAFEBAGS_it, + pass, passlen, + p7->d.encrypted->enc_data->enc_data, 1); +} + X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, @@ -203,9 +217,9 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, X509_ALGOR_free(p8->algor); p8->algor = pbe; M_ASN1_OCTET_STRING_free(p8->digest); - if (!(p8->digest = - PKCS12_i2d_encrypt (pbe, i2d_PKCS8_PRIV_KEY_INFO, pass, passlen, - (char *)p8inf, 0))) { + p8->digest = PKCS12_item_i2d_encrypt(pbe, &PKCS8_PRIV_KEY_INFO_it, + pass, passlen, p8inf, 1); + if(!p8->digest) { PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); goto err; } @@ -216,3 +230,28 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, X509_SIG_free(p8); return NULL; } + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen) +{ + return PKCS12_item_decrypt_d2i(p8->algor, &PKCS8_PRIV_KEY_INFO_it, pass, + passlen, p8->digest, 1); +} + +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass, + int passlen) +{ + return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); +} + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) +{ + if(ASN1_item_pack(safes, &PKCS12_AUTHSAFES_it, + &p12->authsafes->d.data)) + return 1; + return 0; +} + +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) +{ + return ASN1_item_unpack(p12->authsafes->d.data, &PKCS12_AUTHSAFES_it); +} diff --git a/crypto/pkcs12/p12_asn.c b/crypto/pkcs12/p12_asn.c index cbee7336d9..860a6bb921 100644 --- a/crypto/pkcs12/p12_asn.c +++ b/crypto/pkcs12/p12_asn.c @@ -112,3 +112,14 @@ ASN1_SEQUENCE(PKCS12_SAFEBAG) = { } ASN1_SEQUENCE_END(PKCS12_SAFEBAG); IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG) + +/* SEQUENCE OF SafeBag */ +ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG) +ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS); + +/* Authsafes: SEQUENCE OF PKCS7 */ +ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7) +ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES); + diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index a8f7b48882..4c36c643ce 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -94,7 +94,7 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, } /* Add user certificate */ - if(!(bag = M_PKCS12_x5092certbag(cert))) return NULL; + if(!(bag = PKCS12_x5092certbag(cert))) return NULL; if(name && !PKCS12_add_friendlyname(bag, name, -1)) return NULL; X509_digest(cert, EVP_sha1(), keyid, &keyidlen); if(!PKCS12_add_localkeyid(bag, keyid, keyidlen)) return NULL; @@ -108,7 +108,7 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, if(ca) { for(i = 0; i < sk_X509_num(ca); i++) { tcert = sk_X509_value(ca, i); - if(!(bag = M_PKCS12_x5092certbag(tcert))) return NULL; + if(!(bag = PKCS12_x5092certbag(tcert))) return NULL; if(!sk_PKCS12_SAFEBAG_push(bags, bag)) { PKCS12err(PKCS12_F_PKCS12_CREATE,ERR_R_MALLOC_FAILURE); return NULL; @@ -152,7 +152,7 @@ PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, if(!(p12 = PKCS12_init (NID_pkcs7_data))) return NULL; - if(!M_PKCS12_pack_authsafes (p12, safes)) return NULL; + if(!PKCS12_pack_authsafes (p12, safes)) return NULL; sk_PKCS7_pop_free(safes, PKCS7_free); diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c index 8cd7e2f414..92b95f6829 100644 --- a/crypto/pkcs12/p12_decr.c +++ b/crypto/pkcs12/p12_decr.c @@ -68,7 +68,7 @@ * OPENSSL_malloc'ed buffer */ -unsigned char * PKCS12_pbe_crypt (X509_ALGOR *algor, const char *pass, +unsigned char * PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, int passlen, unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de) { @@ -103,20 +103,17 @@ unsigned char * PKCS12_pbe_crypt (X509_ALGOR *algor, const char *pass, } /* Decrypt an OCTET STRING and decode ASN1 structure - * if seq & 1 'obj' is a stack of structures to be encoded - * if seq & 2 zero buffer after use - * as a sequence. + * if zbuf set zero buffer after use. */ -char * PKCS12_decrypt_d2i (X509_ALGOR *algor, char * (*d2i)(), - void (*free_func)(void *), const char *pass, int passlen, - ASN1_OCTET_STRING *oct, int seq) +void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf) { unsigned char *out, *p; - char *ret; + void *ret; int outlen; - if (!PKCS12_pbe_crypt (algor, pass, passlen, oct->data, oct->length, + if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, &out, &outlen, 0)) { PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_PKCS12_PBE_CRYPT_ERROR); return NULL; @@ -134,53 +131,41 @@ char * PKCS12_decrypt_d2i (X509_ALGOR *algor, char * (*d2i)(), fclose(op); } #endif - if (seq & 1) ret = (char *) d2i_ASN1_SET(NULL, &p, outlen, d2i, - free_func, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); - else ret = d2i(NULL, &p, outlen); - if (seq & 2) memset(out, 0, outlen); + ret = ASN1_item_d2i(NULL, &p, outlen, it); + if (zbuf) memset(out, 0, outlen); if(!ret) PKCS12err(PKCS12_F_PKCS12_DECRYPT_D2I,PKCS12_R_DECODE_ERROR); - OPENSSL_free (out); + OPENSSL_free(out); return ret; } /* Encode ASN1 structure and encrypt, return OCTET STRING - * if 'seq' is non-zero 'obj' is a stack of structures to be encoded - * as a sequence + * if zbuf set zero encoding. */ -ASN1_OCTET_STRING *PKCS12_i2d_encrypt (X509_ALGOR *algor, int (*i2d)(), +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it, const char *pass, int passlen, - char *obj, int seq) + void *obj, int zbuf) { ASN1_OCTET_STRING *oct; - unsigned char *in, *p; + unsigned char *in = NULL; int inlen; if (!(oct = M_ASN1_OCTET_STRING_new ())) { PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); return NULL; } - if (seq) inlen = i2d_ASN1_SET((STACK *)obj, NULL, i2d, V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE); - else inlen = i2d (obj, NULL); - if (!inlen) { + inlen = ASN1_item_i2d(obj, &in, it); + if (!in) { PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCODE_ERROR); return NULL; } - if (!(in = OPENSSL_malloc (inlen))) { - PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,ERR_R_MALLOC_FAILURE); - return NULL; - } - p = in; - if (seq) i2d_ASN1_SET((STACK *)obj, &p, i2d, V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE); - else i2d (obj, &p); - if (!PKCS12_pbe_crypt (algor, pass, passlen, in, inlen, &oct->data, + if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, &oct->length, 1)) { PKCS12err(PKCS12_F_PKCS12_I2D_ENCRYPT,PKCS12_R_ENCRYPT_ERROR); OPENSSL_free(in); return NULL; } - OPENSSL_free (in); + if (zbuf) memset(in, 0, inlen); + OPENSSL_free(in); return oct; } diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c index 1fbbd6c99f..62272a2d18 100644 --- a/crypto/pkcs12/p12_kiss.c +++ b/crypto/pkcs12/p12_kiss.c @@ -151,14 +151,14 @@ static int parse_pk12 (PKCS12 *p12, const char *pass, int passlen, ASN1_OCTET_STRING *keyid = NULL; char keymatch = 0; - if (!( asafes = M_PKCS12_unpack_authsafes (p12))) return 0; + if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; for (i = 0; i < sk_PKCS7_num (asafes); i++) { p7 = sk_PKCS7_value (asafes, i); bagnid = OBJ_obj2nid (p7->type); if (bagnid == NID_pkcs7_data) { - bags = M_PKCS12_unpack_p7data(p7); + bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { - bags = M_PKCS12_unpack_p7encdata(p7, pass, passlen); + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); } else continue; if (!bags) { sk_PKCS7_pop_free(asafes, PKCS7_free); @@ -237,7 +237,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, case NID_pkcs8ShroudedKeyBag: if (!lkey || !pkey) return 1; - if (!(p8 = M_PKCS12_decrypt_skey(bag, pass, passlen))) + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) return 0; *pkey = EVP_PKCS82PKEY(p8); PKCS8_PRIV_KEY_INFO_free(p8); @@ -248,7 +248,7 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, case NID_certBag: if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) return 1; - if (!(x509 = M_PKCS12_certbag2x509(bag))) return 0; + if (!(x509 = PKCS12_certbag2x509(bag))) return 0; if(ckid) X509_keyid_set1(x509, ckid->data, ckid->length); if(fname) { int len; diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c index 84e31a7f21..a549433eeb 100644 --- a/crypto/pkcs12/p12_npas.c +++ b/crypto/pkcs12/p12_npas.c @@ -113,15 +113,15 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) unsigned char mac[EVP_MAX_MD_SIZE]; unsigned int maclen; - if (!(asafes = M_PKCS12_unpack_authsafes(p12))) return 0; + if (!(asafes = PKCS12_unpack_authsafes(p12))) return 0; if(!(newsafes = sk_PKCS7_new_null())) return 0; for (i = 0; i < sk_PKCS7_num (asafes); i++) { p7 = sk_PKCS7_value(asafes, i); bagnid = OBJ_obj2nid(p7->type); if (bagnid == NID_pkcs7_data) { - bags = M_PKCS12_unpack_p7data(p7); + bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { - bags = M_PKCS12_unpack_p7encdata(p7, oldpass, -1); + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); alg_get(p7->d.encrypted->enc_data->algorithm, &pbe_nid, &pbe_iter, &pbe_saltlen); } else continue; @@ -151,7 +151,7 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) p12_data_tmp = p12->authsafes->d.data; if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr; - if(!M_PKCS12_pack_authsafes(p12, newsafes)) goto saferr; + if(!PKCS12_pack_authsafes(p12, newsafes)) goto saferr; if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr; if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr; @@ -194,7 +194,7 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) if(M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) return 1; - if (!(p8 = M_PKCS12_decrypt_skey(bag, oldpass, -1))) return 0; + if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0; alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen); if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, p8_iter, p8))) return 0; diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c index 17f41b4549..2c2166e8d7 100644 --- a/crypto/pkcs12/p12_utl.c +++ b/crypto/pkcs12/p12_utl.c @@ -93,26 +93,50 @@ char *uni2asc (unsigned char *uni, int unilen) int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) { - return ASN1_i2d_bio((int(*)())i2d_PKCS12, bp, (unsigned char *)p12); + return ASN1_item_i2d_bio(&PKCS12_it, bp, p12); } #ifndef NO_FP_API int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) { - return ASN1_i2d_fp((int(*)())i2d_PKCS12, fp, (unsigned char *)p12); + return ASN1_item_i2d_fp(&PKCS12_it, fp, p12); } #endif PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) { - return (PKCS12 *)ASN1_d2i_bio((char *(*)())PKCS12_new, - (char *(*)())d2i_PKCS12, bp, (unsigned char **)p12); + return ASN1_item_d2i_bio(&PKCS12_it, bp, p12); } #ifndef NO_FP_API PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) { - return (PKCS12 *)ASN1_d2i_fp((char *(*)())PKCS12_new, - (char *(*)())d2i_PKCS12, fp, (unsigned char **)(p12)); + return ASN1_item_d2i_fp(&PKCS12_it, fp, p12); } #endif +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509) +{ + return PKCS12_item_pack_safebag(x509, &X509_it, + NID_x509Certificate, NID_certBag); +} + +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl) +{ + return PKCS12_item_pack_safebag(crl, &X509_CRL_it, + NID_x509Crl, NID_crlBag); +} + +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag) +{ + if(M_PKCS12_bag_type(bag) != NID_certBag) return NULL; + if(M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, &X509_it); +} + +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag) +{ + if(M_PKCS12_bag_type(bag) != NID_crlBag) return NULL; + if(M_PKCS12_cert_bag_type(bag) != NID_x509Crl) return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, + &X509_CRL_it); +} diff --git a/crypto/pkcs12/pkcs12.h b/crypto/pkcs12/pkcs12.h index d58a140017..6492a910e2 100644 --- a/crypto/pkcs12/pkcs12.h +++ b/crypto/pkcs12/pkcs12.h @@ -140,55 +140,25 @@ union { #define PKCS12_ERROR 0 #define PKCS12_OK 1 -#define M_PKCS12_bag_type(bag) OBJ_obj2nid(bag->type) -#define M_PKCS12_cert_bag_type(bag) OBJ_obj2nid(bag->value.bag->type) -#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type - -#define M_PKCS12_x5092certbag(x509) \ -PKCS12_pack_safebag((char *)(x509), i2d_X509, NID_x509Certificate, NID_certBag) - -#define M_PKCS12_x509crl2certbag(crl) \ -PKCS12_pack_safebag((char *)(crl), i2d_X509CRL, NID_x509Crl, NID_crlBag) - -#define M_PKCS12_certbag2x509(bg) \ -(X509 *) ASN1_unpack_string((bg)->value.bag->value.octet, \ -(char *(*)())d2i_X509) - -#define M_PKCS12_certbag2x509crl(bg) \ -(X509CRL *) ASN1_unpack_string((bg)->value.bag->value.octet, \ -(char *(*)())d2i_X509CRL) - -/*#define M_PKCS12_pkcs82rsa(p8) \ -(RSA *) ASN1_unpack_string((p8)->pkey, (char *(*)())d2i_RSAPrivateKey)*/ +/* Compatibility macros */ -#define M_PKCS12_unpack_p7data(p7) \ -ASN1_seq_unpack_PKCS12_SAFEBAG((p7)->d.data->data, p7->d.data->length, \ - d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free) +#define M_PKCS12_x5092certbag PKCS12_x5092certbag +#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag -#define M_PKCS12_pack_authsafes(p12, safes) \ -ASN1_seq_pack_PKCS7((safes), i2d_PKCS7,\ - &(p12)->authsafes->d.data->data, &(p12)->authsafes->d.data->length) +#define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl -#define M_PKCS12_unpack_authsafes(p12) \ -ASN1_seq_unpack_PKCS7((p12)->authsafes->d.data->data, \ - (p12)->authsafes->d.data->length, d2i_PKCS7, PKCS7_free) +#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata -#define M_PKCS12_unpack_p7encdata(p7, pass, passlen) \ -PKCS12_decrypt_d2i_PKCS12_SAFEBAG((p7)->d.encrypted->enc_data->algorithm,\ - d2i_PKCS12_SAFEBAG, PKCS12_SAFEBAG_free, \ - (pass), (passlen), \ - (p7)->d.encrypted->enc_data->enc_data, 3) +#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +#define M_PKCS8_decrypt PKCS8_decrypt -#define M_PKCS12_decrypt_skey(bag, pass, passlen) \ -(PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i((bag)->value.shkeybag->algor, \ -(char *(*)())d2i_PKCS8_PRIV_KEY_INFO, (void (*)(void *))PKCS8_PRIV_KEY_INFO_free, \ - (pass), (passlen), \ - (bag)->value.shkeybag->digest, 2) - -#define M_PKCS8_decrypt(p8, pass, passlen) \ -(PKCS8_PRIV_KEY_INFO *) PKCS12_decrypt_d2i((p8)->algor, \ -(char *(*)())d2i_PKCS8_PRIV_KEY_INFO, (void (*)(void *))PKCS8_PRIV_KEY_INFO_free,\ - (pass), (passlen), (p8)->digest, 2) +#define M_PKCS12_bag_type(bag) OBJ_obj2nid(bag->type) +#define M_PKCS12_cert_bag_type(bag) OBJ_obj2nid(bag->value.bag->type) +#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type #define PKCS12_get_attr(bag, attr_nid) \ PKCS12_get_attr_gen(bag->attrib, attr_nid) @@ -199,8 +169,17 @@ PKCS12_decrypt_d2i_PKCS12_SAFEBAG((p7)->d.encrypted->enc_data->algorithm,\ #define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) -PKCS12_SAFEBAG *PKCS12_pack_safebag(char *obj, int (*i2d)(), int nid1, int nid2); +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1, + int nid2); PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass, + int passlen); X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, @@ -210,9 +189,15 @@ PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); + int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen); int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen); @@ -224,12 +209,11 @@ char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, int passlen, unsigned char *in, int inlen, unsigned char **data, int *datalen, int en_de); -char *PKCS12_decrypt_d2i(X509_ALGOR *algor, char *(*d2i)(), - void (*free_func)(void *), const char *pass, int passlen, - ASN1_STRING *oct, int seq); -ASN1_STRING *PKCS12_i2d_encrypt(X509_ALGOR *algor, int (*i2d)(), - const char *pass, int passlen, char *obj, - int seq); +void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); PKCS12 *PKCS12_init(int mode); int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, @@ -254,6 +238,9 @@ DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + void ERR_load_PKCS12_strings(void); void PKCS12_PBE_add(void); int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h index 1dfbace15b..2835d58a58 100644 --- a/crypto/pkcs7/pkcs7.h +++ b/crypto/pkcs7/pkcs7.h @@ -225,6 +225,7 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_get_attributes(si) ((si)->unauth_attr) #define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) #define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) #define PKCS7_type_is_signedAndEnveloped(a) \ (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) -- 2.25.1