diff options
Diffstat (limited to 'src/lib/libcrypto/pkcs12/p12_npas.c')
-rw-r--r-- | src/lib/libcrypto/pkcs12/p12_npas.c | 244 |
1 files changed, 0 insertions, 244 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_npas.c b/src/lib/libcrypto/pkcs12/p12_npas.c deleted file mode 100644 index b9dea51b85..0000000000 --- a/src/lib/libcrypto/pkcs12/p12_npas.c +++ /dev/null | |||
@@ -1,244 +0,0 @@ | |||
1 | /* $OpenBSD: p12_npas.c,v 1.10 2015/02/14 14:18:58 miod Exp $ */ | ||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | ||
3 | * project 1999. | ||
4 | */ | ||
5 | /* ==================================================================== | ||
6 | * Copyright (c) 1999 The OpenSSL Project. All rights reserved. | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in | ||
17 | * the documentation and/or other materials provided with the | ||
18 | * distribution. | ||
19 | * | ||
20 | * 3. All advertising materials mentioning features or use of this | ||
21 | * software must display the following acknowledgment: | ||
22 | * "This product includes software developed by the OpenSSL Project | ||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | ||
24 | * | ||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | ||
26 | * endorse or promote products derived from this software without | ||
27 | * prior written permission. For written permission, please contact | ||
28 | * licensing@OpenSSL.org. | ||
29 | * | ||
30 | * 5. Products derived from this software may not be called "OpenSSL" | ||
31 | * nor may "OpenSSL" appear in their names without prior written | ||
32 | * permission of the OpenSSL Project. | ||
33 | * | ||
34 | * 6. Redistributions of any form whatsoever must retain the following | ||
35 | * acknowledgment: | ||
36 | * "This product includes software developed by the OpenSSL Project | ||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | ||
38 | * | ||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | ||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | ||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | ||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | ||
51 | * ==================================================================== | ||
52 | * | ||
53 | * This product includes cryptographic software written by Eric Young | ||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | ||
55 | * Hudson (tjh@cryptsoft.com). | ||
56 | * | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include <string.h> | ||
62 | #include <openssl/pem.h> | ||
63 | #include <openssl/err.h> | ||
64 | #include <openssl/pkcs12.h> | ||
65 | |||
66 | /* PKCS#12 password change routine */ | ||
67 | |||
68 | static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass); | ||
69 | static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, | ||
70 | char *newpass); | ||
71 | static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass); | ||
72 | static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); | ||
73 | |||
74 | /* | ||
75 | * Change the password on a PKCS#12 structure. | ||
76 | */ | ||
77 | |||
78 | int | ||
79 | PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) | ||
80 | { | ||
81 | /* Check for NULL PKCS12 structure */ | ||
82 | |||
83 | if (!p12) { | ||
84 | PKCS12err(PKCS12_F_PKCS12_NEWPASS, | ||
85 | PKCS12_R_INVALID_NULL_PKCS12_POINTER); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* Check the mac */ | ||
90 | |||
91 | if (!PKCS12_verify_mac(p12, oldpass, -1)) { | ||
92 | PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | if (!newpass_p12(p12, oldpass, newpass)) { | ||
97 | PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | return 1; | ||
102 | } | ||
103 | |||
104 | /* Parse the outer PKCS#12 structure */ | ||
105 | |||
106 | static int | ||
107 | newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) | ||
108 | { | ||
109 | STACK_OF(PKCS7) *asafes, *newsafes; | ||
110 | STACK_OF(PKCS12_SAFEBAG) *bags; | ||
111 | int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; | ||
112 | PKCS7 *p7, *p7new; | ||
113 | ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; | ||
114 | unsigned char mac[EVP_MAX_MD_SIZE]; | ||
115 | unsigned int maclen; | ||
116 | |||
117 | if (!(asafes = PKCS12_unpack_authsafes(p12))) | ||
118 | return 0; | ||
119 | if (!(newsafes = sk_PKCS7_new_null())) | ||
120 | return 0; | ||
121 | for (i = 0; i < sk_PKCS7_num(asafes); i++) { | ||
122 | p7 = sk_PKCS7_value(asafes, i); | ||
123 | bagnid = OBJ_obj2nid(p7->type); | ||
124 | if (bagnid == NID_pkcs7_data) { | ||
125 | bags = PKCS12_unpack_p7data(p7); | ||
126 | } else if (bagnid == NID_pkcs7_encrypted) { | ||
127 | bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); | ||
128 | if (!alg_get(p7->d.encrypted->enc_data->algorithm, | ||
129 | &pbe_nid, &pbe_iter, &pbe_saltlen)) { | ||
130 | sk_PKCS12_SAFEBAG_pop_free(bags, | ||
131 | PKCS12_SAFEBAG_free); | ||
132 | bags = NULL; | ||
133 | } | ||
134 | } else | ||
135 | continue; | ||
136 | if (bags == NULL) | ||
137 | goto err; | ||
138 | if (!newpass_bags(bags, oldpass, newpass)) { | ||
139 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); | ||
140 | goto err; | ||
141 | } | ||
142 | /* Repack bag in same form with new password */ | ||
143 | if (bagnid == NID_pkcs7_data) | ||
144 | p7new = PKCS12_pack_p7data(bags); | ||
145 | else | ||
146 | p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, | ||
147 | NULL, pbe_saltlen, pbe_iter, bags); | ||
148 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); | ||
149 | if (p7new == NULL) | ||
150 | goto err; | ||
151 | if (sk_PKCS7_push(newsafes, p7new) == 0) | ||
152 | goto err; | ||
153 | } | ||
154 | sk_PKCS7_pop_free(asafes, PKCS7_free); | ||
155 | |||
156 | /* Repack safe: save old safe in case of error */ | ||
157 | |||
158 | p12_data_tmp = p12->authsafes->d.data; | ||
159 | if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) { | ||
160 | p12->authsafes->d.data = p12_data_tmp; | ||
161 | goto err; | ||
162 | } | ||
163 | if (!PKCS12_pack_authsafes(p12, newsafes)) | ||
164 | goto saferr; | ||
165 | |||
166 | if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) | ||
167 | goto saferr; | ||
168 | if (!(macnew = ASN1_OCTET_STRING_new())) | ||
169 | goto saferr; | ||
170 | if (!ASN1_OCTET_STRING_set(macnew, mac, maclen)) | ||
171 | goto saferr; | ||
172 | ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); | ||
173 | p12->mac->dinfo->digest = macnew; | ||
174 | ASN1_OCTET_STRING_free(p12_data_tmp); | ||
175 | |||
176 | return 1; | ||
177 | |||
178 | saferr: | ||
179 | /* Restore old safe */ | ||
180 | ASN1_OCTET_STRING_free(p12->authsafes->d.data); | ||
181 | ASN1_OCTET_STRING_free(macnew); | ||
182 | p12->authsafes->d.data = p12_data_tmp; | ||
183 | return 0; | ||
184 | |||
185 | err: | ||
186 | sk_PKCS7_pop_free(asafes, PKCS7_free); | ||
187 | sk_PKCS7_pop_free(newsafes, PKCS7_free); | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | |||
192 | static int | ||
193 | newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, char *newpass) | ||
194 | { | ||
195 | int i; | ||
196 | |||
197 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { | ||
198 | if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), | ||
199 | oldpass, newpass)) | ||
200 | return 0; | ||
201 | } | ||
202 | return 1; | ||
203 | } | ||
204 | |||
205 | /* Change password of safebag: only needs handle shrouded keybags */ | ||
206 | |||
207 | static int | ||
208 | newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) | ||
209 | { | ||
210 | PKCS8_PRIV_KEY_INFO *p8; | ||
211 | X509_SIG *p8new; | ||
212 | int p8_nid, p8_saltlen, p8_iter; | ||
213 | |||
214 | if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) | ||
215 | return 1; | ||
216 | |||
217 | if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) | ||
218 | return 0; | ||
219 | if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, | ||
220 | &p8_saltlen)) | ||
221 | return 0; | ||
222 | if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, | ||
223 | p8_iter, p8))) return 0; | ||
224 | X509_SIG_free(bag->value.shkeybag); | ||
225 | bag->value.shkeybag = p8new; | ||
226 | return 1; | ||
227 | } | ||
228 | |||
229 | static int | ||
230 | alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) | ||
231 | { | ||
232 | PBEPARAM *pbe; | ||
233 | const unsigned char *p; | ||
234 | |||
235 | p = alg->parameter->value.sequence->data; | ||
236 | pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); | ||
237 | if (!pbe) | ||
238 | return 0; | ||
239 | *pnid = OBJ_obj2nid(alg->algorithm); | ||
240 | *piter = ASN1_INTEGER_get(pbe->iter); | ||
241 | *psaltlen = pbe->salt->length; | ||
242 | PBEPARAM_free(pbe); | ||
243 | return 1; | ||
244 | } | ||