Rewrite PKCS#12 code and remove some of the old
authorDr. Stephen Henson <steve@openssl.org>
Sun, 31 Dec 2000 01:13:04 +0000 (01:13 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 31 Dec 2000 01:13:04 +0000 (01:13 +0000)
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).

16 files changed:
CHANGES
apps/pkcs12.c
apps/pkcs8.c
crypto/asn1/asn1.h
crypto/asn1/asn_pack.c
crypto/asn1/tasn_dec.c
crypto/pem/pem_lib.c
crypto/pkcs12/p12_add.c
crypto/pkcs12/p12_asn.c
crypto/pkcs12/p12_crt.c
crypto/pkcs12/p12_decr.c
crypto/pkcs12/p12_kiss.c
crypto/pkcs12/p12_npas.c
crypto/pkcs12/p12_utl.c
crypto/pkcs12/pkcs12.h
crypto/pkcs7/pkcs7.h

diff --git a/CHANGES b/CHANGES
index e183059..667b0f7 100644 (file)
--- 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.
index 365a8ad..46ae93d 100644 (file)
@@ -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);
index bd1697a..3633590 100644 (file)
@@ -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);
        }
 
index 0bc22d7..4646f05 100644 (file)
@@ -63,6 +63,7 @@
 #ifndef NO_BIO
 #include <openssl/bio.h>
 #endif
+#include <openssl/e_os2.h>
 #include <openssl/bn.h>
 #include <openssl/stack.h>
 #include <openssl/safestack.h>
@@ -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);
index e62eed2..e6051db 100644 (file)
@@ -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;
index 940e6af..15ebf26 100644 (file)
@@ -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;
+                       }
                }
        }
                
index a17c3ed..5d10524 100644 (file)
@@ -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);
index b563656..2d275c4 100644 (file)
 
 /* 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);
+}
index cbee733..860a6bb 100644 (file)
@@ -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);
+
index a8f7b48..4c36c64 100644 (file)
@@ -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);
 
index 8cd7e2f..92b95f6 100644 (file)
@@ -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;
 }
 
index 1fbbd6c..62272a2 100644 (file)
@@ -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;
index 84e31a7..a549433 100644 (file)
@@ -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;
index 17f41b4..2c2166e 100644 (file)
@@ -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);
+}
index d58a140..6492a91 100644 (file)
@@ -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,
index 1dfbace..2835d58 100644 (file)
@@ -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)