diff options
-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; |