diff options
author | tb <> | 2024-01-25 09:40:09 +0000 |
---|---|---|
committer | tb <> | 2024-01-25 09:40:09 +0000 |
commit | 194233cb74b81e0be44fef744914b91369d9912f (patch) | |
tree | ada68b77d53ac3d554e92e0ae3d98066fbce5dbd | |
parent | f33f863f9b989e14a92b65e7d8c585533a3b70d6 (diff) | |
download | openbsd-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.c | 107 |
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 | } |
106 | LCRYPTO_ALIAS(PKCS12_newpass); | 106 | LCRYPTO_ALIAS(PKCS12_newpass); |
107 | 107 | ||
108 | /* Parse the outer PKCS#12 structure */ | 108 | static int |
109 | pkcs7_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 | |||
135 | static int | ||
136 | pkcs7_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 | ||
110 | static int | 167 | static int |
111 | newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) | 168 | newpass_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; |