PKCS#8 support for alternative PRFs.
[openssl.git] / crypto / pkcs12 / p12_npas.c
index eed494a3f39e2f88a99a2a911737c28db6c18674..2f71355150e18c57a3ac008e25d8562498ee0075 100644 (file)
@@ -1,5 +1,5 @@
 /* p12_npas.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
 /* ====================================================================
@@ -77,28 +77,26 @@ static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
 
 int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
 {
+       /* Check for NULL PKCS12 structure */
 
-/* Check for NULL PKCS12 structure */
-
-if(!p12) {
-       PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
-       return 0;
-}
-
-/* Check the mac */
-
-if (!PKCS12_verify_mac(p12, oldpass, -1)) {
-       PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE);
-       return 0;
-}
+       if(!p12) {
+               PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_INVALID_NULL_PKCS12_POINTER);
+               return 0;
+       }
 
-if (!newpass_p12(p12, oldpass, newpass)) {
-       PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR);
-       return 0;
-}
+       /* Check the mac */
+       
+       if (!PKCS12_verify_mac(p12, oldpass, -1)) {
+               PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_MAC_VERIFY_FAILURE);
+               return 0;
+       }
 
-return 1;
+       if (!newpass_p12(p12, oldpass, newpass)) {
+               PKCS12err(PKCS12_F_PKCS12_NEWPASS,PKCS12_R_PARSE_ERROR);
+               return 0;
+       }
 
+       return 1;
 }
 
 /* Parse the outer PKCS#12 structure */
@@ -107,23 +105,28 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
 {
        STACK_OF(PKCS7) *asafes, *newsafes;
        STACK_OF(PKCS12_SAFEBAG) *bags;
-       int i, bagnid, pbe_nid, pbe_iter, pbe_saltlen;
+       int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
        PKCS7 *p7, *p7new;
        ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
        unsigned char mac[EVP_MAX_MD_SIZE];
        unsigned int maclen;
 
-       if (!(asafes = M_PKCS12_unpack_authsafes(p12))) return 0;
-       if(!(newsafes = sk_PKCS7_new(NULL))) 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);
-                       alg_get(p7->d.encrypted->enc_data->algorithm,
-                               &pbe_nid, &pbe_iter, &pbe_saltlen);
+                       bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+                       if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+                               &pbe_nid, &pbe_iter, &pbe_saltlen))
+                               {
+                               sk_PKCS12_SAFEBAG_pop_free(bags,
+                                               PKCS12_SAFEBAG_free);
+                               bags = NULL;
+                               }
                } else continue;
                if (!bags) {
                        sk_PKCS7_pop_free(asafes, PKCS7_free);
@@ -151,7 +154,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,8 +197,10 @@ 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;
-       alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen);
+       if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) return 0;
+       if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter,
+                                                       &p8_saltlen))
+               return 0;
        if(!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
                                                     p8_iter, p8))) return 0;
        X509_SIG_free(bag->value.shkeybag);
@@ -206,12 +211,15 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
 static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
 {
         PBEPARAM *pbe;
-        unsigned char *p;
+        const unsigned char *p;
+
         p = alg->parameter->value.sequence->data;
         pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
+       if (!pbe)
+               return 0;
         *pnid = OBJ_obj2nid(alg->algorithm);
        *piter = ASN1_INTEGER_get(pbe->iter);
        *psaltlen = pbe->salt->length;
         PBEPARAM_free(pbe);
-        return 0;
+        return 1;
 }