summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2024-01-25 09:40:09 +0000
committertb <>2024-01-25 09:40:09 +0000
commit194233cb74b81e0be44fef744914b91369d9912f (patch)
treeada68b77d53ac3d554e92e0ae3d98066fbce5dbd
parentf33f863f9b989e14a92b65e7d8c585533a3b70d6 (diff)
downloadopenbsd-194233cb74b81e0be44fef744914b91369d9912f.tar.gz
openbsd-194233cb74b81e0be44fef744914b91369d9912f.tar.bz2
openbsd-194233cb74b81e0be44fef744914b91369d9912f.zip
newpass_p12(): factor for loop body into helpers
Since newpass_bags() and sk_PKCS7_push() could be shared between two otherwise entirely unrelated code paths, it was decided to dedup the code in about the ugliest possible way. Untangle the spaghetti and split the code paths into helper functions, so we can easily error check and avoid a bunch of leaks. ok jsing
-rw-r--r--src/lib/libcrypto/pkcs12/p12_npas.c107
1 files changed, 72 insertions, 35 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c
index 7c1ba85a1f..557457b0f3 100644
--- a/src/lib/libcrypto/pkcs12/p12_npas.c
+++ b/src/lib/libcrypto/pkcs12/p12_npas.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: p12_npas.c,v 1.19 2024/01/25 08:10:14 tb Exp $ */ 1/* $OpenBSD: p12_npas.c,v 1.20 2024/01/25 09:40:09 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -105,55 +105,92 @@ PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
105} 105}
106LCRYPTO_ALIAS(PKCS12_newpass); 106LCRYPTO_ALIAS(PKCS12_newpass);
107 107
108/* Parse the outer PKCS#12 structure */ 108static int
109pkcs7_repack_data(PKCS7 *pkcs7, STACK_OF(PKCS7) *newsafes, const char *oldpass,
110 const char *newpass)
111{
112 STACK_OF(PKCS12_SAFEBAG) *bags;
113 PKCS7 *newdata = NULL;
114 int ret = 0;
115
116 if ((bags = PKCS12_unpack_p7data(pkcs7)) == NULL)
117 goto err;
118 if (!newpass_bags(bags, oldpass, newpass))
119 goto err;
120 if ((newdata = PKCS12_pack_p7data(bags)) == NULL)
121 goto err;
122 if (sk_PKCS7_push(newsafes, newdata) == 0)
123 goto err;
124 newdata = NULL;
125
126 ret = 1;
127
128 err:
129 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
130 PKCS7_free(newdata);
131
132 return ret;
133}
134
135static int
136pkcs7_repack_encdata(PKCS7 *pkcs7, STACK_OF(PKCS7) *newsafes, const char *oldpass,
137 const char *newpass)
138{
139 STACK_OF(PKCS12_SAFEBAG) *bags;
140 int pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
141 PKCS7 *newencdata = NULL;
142 int ret = 0;
143
144 if ((bags = PKCS12_unpack_p7encdata(pkcs7, oldpass, -1)) == NULL)
145 goto err;
146 if (!alg_get(pkcs7->d.encrypted->enc_data->algorithm, &pbe_nid,
147 &pbe_iter, &pbe_saltlen))
148 goto err;
149 if (!newpass_bags(bags, oldpass, newpass))
150 goto err;
151 if ((newencdata = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
152 pbe_saltlen, pbe_iter, bags)) == NULL)
153 goto err;
154 if (!sk_PKCS7_push(newsafes, newencdata))
155 goto err;
156 newencdata = NULL;
157
158 ret = 1;
159
160 err:
161 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
162 PKCS7_free(newencdata);
163
164 return ret;
165}
109 166
110static int 167static int
111newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) 168newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
112{ 169{
113 STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL; 170 STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL;
114 STACK_OF(PKCS12_SAFEBAG) *bags;
115 int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
116 PKCS7 *p7, *p7new;
117 ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; 171 ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
118 unsigned char mac[EVP_MAX_MD_SIZE]; 172 unsigned char mac[EVP_MAX_MD_SIZE];
119 unsigned int maclen; 173 unsigned int maclen;
174 int i;
120 175
121 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) 176 if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
122 goto err; 177 goto err;
123 if ((newsafes = sk_PKCS7_new_null()) == NULL) 178 if ((newsafes = sk_PKCS7_new_null()) == NULL)
124 goto err; 179 goto err;
180
125 for (i = 0; i < sk_PKCS7_num(asafes); i++) { 181 for (i = 0; i < sk_PKCS7_num(asafes); i++) {
126 p7 = sk_PKCS7_value(asafes, i); 182 PKCS7 *pkcs7 = sk_PKCS7_value(asafes, i);
127 bagnid = OBJ_obj2nid(p7->type); 183
128 if (bagnid == NID_pkcs7_data) { 184 switch (OBJ_obj2nid(pkcs7->type)) {
129 bags = PKCS12_unpack_p7data(p7); 185 case NID_pkcs7_data:
130 } else if (bagnid == NID_pkcs7_encrypted) { 186 if (pkcs7_repack_data(pkcs7, newsafes, oldpass, newpass))
131 bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); 187 goto err;
132 if (!alg_get(p7->d.encrypted->enc_data->algorithm, 188 break;
133 &pbe_nid, &pbe_iter, &pbe_saltlen)) { 189 case NID_pkcs7_encrypted:
134 sk_PKCS12_SAFEBAG_pop_free(bags, 190 if (pkcs7_repack_encdata(pkcs7, newsafes, oldpass, newpass))
135 PKCS12_SAFEBAG_free); 191 goto err;
136 bags = NULL; 192 break;
137 }
138 } else
139 continue;
140 if (bags == NULL)
141 goto err;
142 if (!newpass_bags(bags, oldpass, newpass)) {
143 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
144 goto err;
145 } 193 }
146 /* Repack bag in same form with new password */
147 if (bagnid == NID_pkcs7_data)
148 p7new = PKCS12_pack_p7data(bags);
149 else
150 p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1,
151 NULL, pbe_saltlen, pbe_iter, bags);
152 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
153 if (p7new == NULL)
154 goto err;
155 if (sk_PKCS7_push(newsafes, p7new) == 0)
156 goto err;
157 } 194 }
158 sk_PKCS7_pop_free(asafes, PKCS7_free); 195 sk_PKCS7_pop_free(asafes, PKCS7_free);
159 asafes = NULL; 196 asafes = NULL;