diff options
Diffstat (limited to '')
-rw-r--r-- | src/lib/libcrypto/pkcs12/p12_kiss.c | 150 |
1 files changed, 73 insertions, 77 deletions
diff --git a/src/lib/libcrypto/pkcs12/p12_kiss.c b/src/lib/libcrypto/pkcs12/p12_kiss.c index 0772fa65af..4063ba4b82 100644 --- a/src/lib/libcrypto/pkcs12/p12_kiss.c +++ b/src/lib/libcrypto/pkcs12/p12_kiss.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: p12_kiss.c,v 1.14 2014/06/12 15:49:30 deraadt Exp $ */ | 1 | /* $OpenBSD: p12_kiss.c,v 1.15 2014/07/08 09:24:53 jsing 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 | */ |
@@ -10,7 +10,7 @@ | |||
10 | * are met: | 10 | * are met: |
11 | * | 11 | * |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * | 14 | * |
15 | * 2. Redistributions in binary form must reproduce the above copyright | 15 | * 2. Redistributions in binary form must reproduce the above copyright |
16 | * notice, this list of conditions and the following disclaimer in | 16 | * notice, this list of conditions and the following disclaimer in |
@@ -63,13 +63,13 @@ | |||
63 | /* Simplified PKCS#12 routines */ | 63 | /* Simplified PKCS#12 routines */ |
64 | 64 | ||
65 | static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, | 65 | static int parse_pk12( PKCS12 *p12, const char *pass, int passlen, |
66 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts); | 66 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts); |
67 | 67 | ||
68 | static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, | 68 | static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, |
69 | int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); | 69 | int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); |
70 | 70 | ||
71 | static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, | 71 | static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, |
72 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts); | 72 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts); |
73 | 73 | ||
74 | /* Parse and decrypt a PKCS#12 structure returning user key, user cert | 74 | /* Parse and decrypt a PKCS#12 structure returning user key, user cert |
75 | * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, | 75 | * and other (CA) certs. Note either ca should be NULL, *ca should be NULL, |
@@ -77,22 +77,23 @@ static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen, | |||
77 | * passed unitialised. | 77 | * passed unitialised. |
78 | */ | 78 | */ |
79 | 79 | ||
80 | int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | 80 | int |
81 | STACK_OF(X509) **ca) | 81 | PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, |
82 | STACK_OF(X509) **ca) | ||
82 | { | 83 | { |
83 | STACK_OF(X509) *ocerts = NULL; | 84 | STACK_OF(X509) *ocerts = NULL; |
84 | X509 *x = NULL; | 85 | X509 *x = NULL; |
85 | /* Check for NULL PKCS12 structure */ | 86 | /* Check for NULL PKCS12 structure */ |
86 | 87 | ||
87 | if(!p12) | 88 | if (!p12) { |
88 | { | 89 | PKCS12err(PKCS12_F_PKCS12_PARSE, |
89 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_INVALID_NULL_PKCS12_POINTER); | 90 | PKCS12_R_INVALID_NULL_PKCS12_POINTER); |
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | 93 | ||
93 | if(pkey) | 94 | if (pkey) |
94 | *pkey = NULL; | 95 | *pkey = NULL; |
95 | if(cert) | 96 | if (cert) |
96 | *cert = NULL; | 97 | *cert = NULL; |
97 | 98 | ||
98 | /* Check the mac */ | 99 | /* Check the mac */ |
@@ -103,46 +104,42 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
103 | * password are two different things... | 104 | * password are two different things... |
104 | */ | 105 | */ |
105 | 106 | ||
106 | if(!pass || !*pass) { | 107 | if (!pass || !*pass) { |
107 | if(PKCS12_verify_mac(p12, NULL, 0)) pass = NULL; | 108 | if (PKCS12_verify_mac(p12, NULL, 0)) |
108 | else if(PKCS12_verify_mac(p12, "", 0)) pass = ""; | 109 | pass = NULL; |
110 | else if (PKCS12_verify_mac(p12, "", 0)) | ||
111 | pass = ""; | ||
109 | else { | 112 | else { |
110 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); | 113 | PKCS12err(PKCS12_F_PKCS12_PARSE, |
114 | PKCS12_R_MAC_VERIFY_FAILURE); | ||
111 | goto err; | 115 | goto err; |
112 | } | 116 | } |
113 | } else if (!PKCS12_verify_mac(p12, pass, -1)) { | 117 | } else if (!PKCS12_verify_mac(p12, pass, -1)) { |
114 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_MAC_VERIFY_FAILURE); | 118 | PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); |
115 | goto err; | 119 | goto err; |
116 | } | 120 | } |
117 | 121 | ||
118 | /* Allocate stack for other certificates */ | 122 | /* Allocate stack for other certificates */ |
119 | ocerts = sk_X509_new_null(); | 123 | ocerts = sk_X509_new_null(); |
120 | 124 | if (!ocerts) { | |
121 | if (!ocerts) | 125 | PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); |
122 | { | ||
123 | PKCS12err(PKCS12_F_PKCS12_PARSE,ERR_R_MALLOC_FAILURE); | ||
124 | return 0; | 126 | return 0; |
125 | } | 127 | } |
126 | 128 | ||
127 | if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) | 129 | if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) { |
128 | { | 130 | PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); |
129 | PKCS12err(PKCS12_F_PKCS12_PARSE,PKCS12_R_PARSE_ERROR); | ||
130 | goto err; | 131 | goto err; |
131 | } | 132 | } |
132 | 133 | ||
133 | while ((x = sk_X509_pop(ocerts))) | 134 | while ((x = sk_X509_pop(ocerts))) { |
134 | { | 135 | if (pkey && *pkey && cert && !*cert) { |
135 | if (pkey && *pkey && cert && !*cert) | 136 | if (X509_check_private_key(x, *pkey)) { |
136 | { | ||
137 | if (X509_check_private_key(x, *pkey)) | ||
138 | { | ||
139 | *cert = x; | 137 | *cert = x; |
140 | x = NULL; | 138 | x = NULL; |
141 | } | ||
142 | } | 139 | } |
140 | } | ||
143 | 141 | ||
144 | if (ca && x) | 142 | if (ca && x) { |
145 | { | ||
146 | if (!*ca) | 143 | if (!*ca) |
147 | *ca = sk_X509_new_null(); | 144 | *ca = sk_X509_new_null(); |
148 | if (!*ca) | 145 | if (!*ca) |
@@ -150,18 +147,17 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
150 | if (!sk_X509_push(*ca, x)) | 147 | if (!sk_X509_push(*ca, x)) |
151 | goto err; | 148 | goto err; |
152 | x = NULL; | 149 | x = NULL; |
153 | } | 150 | } |
154 | if (x) | 151 | if (x) |
155 | X509_free(x); | 152 | X509_free(x); |
156 | } | 153 | } |
157 | 154 | ||
158 | if (ocerts) | 155 | if (ocerts) |
159 | sk_X509_pop_free(ocerts, X509_free); | 156 | sk_X509_pop_free(ocerts, X509_free); |
160 | 157 | ||
161 | return 1; | 158 | return 1; |
162 | 159 | ||
163 | err: | 160 | err: |
164 | |||
165 | if (pkey && *pkey) | 161 | if (pkey && *pkey) |
166 | EVP_PKEY_free(*pkey); | 162 | EVP_PKEY_free(*pkey); |
167 | if (cert && *cert) | 163 | if (cert && *cert) |
@@ -171,20 +167,21 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, | |||
171 | if (ocerts) | 167 | if (ocerts) |
172 | sk_X509_pop_free(ocerts, X509_free); | 168 | sk_X509_pop_free(ocerts, X509_free); |
173 | return 0; | 169 | return 0; |
174 | |||
175 | } | 170 | } |
176 | 171 | ||
177 | /* Parse the outer PKCS#12 structure */ | 172 | /* Parse the outer PKCS#12 structure */ |
178 | 173 | ||
179 | static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, | 174 | static int |
180 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts) | 175 | parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey, |
176 | STACK_OF(X509) *ocerts) | ||
181 | { | 177 | { |
182 | STACK_OF(PKCS7) *asafes; | 178 | STACK_OF(PKCS7) *asafes; |
183 | STACK_OF(PKCS12_SAFEBAG) *bags; | 179 | STACK_OF(PKCS12_SAFEBAG) *bags; |
184 | int i, bagnid; | 180 | int i, bagnid; |
185 | PKCS7 *p7; | 181 | PKCS7 *p7; |
186 | 182 | ||
187 | if (!(asafes = PKCS12_unpack_authsafes (p12))) return 0; | 183 | if (!(asafes = PKCS12_unpack_authsafes (p12))) |
184 | return 0; | ||
188 | for (i = 0; i < sk_PKCS7_num (asafes); i++) { | 185 | for (i = 0; i < sk_PKCS7_num (asafes); i++) { |
189 | p7 = sk_PKCS7_value (asafes, i); | 186 | p7 = sk_PKCS7_value (asafes, i); |
190 | bagnid = OBJ_obj2nid (p7->type); | 187 | bagnid = OBJ_obj2nid (p7->type); |
@@ -192,12 +189,13 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, | |||
192 | bags = PKCS12_unpack_p7data(p7); | 189 | bags = PKCS12_unpack_p7data(p7); |
193 | } else if (bagnid == NID_pkcs7_encrypted) { | 190 | } else if (bagnid == NID_pkcs7_encrypted) { |
194 | bags = PKCS12_unpack_p7encdata(p7, pass, passlen); | 191 | bags = PKCS12_unpack_p7encdata(p7, pass, passlen); |
195 | } else continue; | 192 | } else |
193 | continue; | ||
196 | if (!bags) { | 194 | if (!bags) { |
197 | sk_PKCS7_pop_free(asafes, PKCS7_free); | 195 | sk_PKCS7_pop_free(asafes, PKCS7_free); |
198 | return 0; | 196 | return 0; |
199 | } | 197 | } |
200 | if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { | 198 | if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { |
201 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); | 199 | sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); |
202 | sk_PKCS7_pop_free(asafes, PKCS7_free); | 200 | sk_PKCS7_pop_free(asafes, PKCS7_free); |
203 | return 0; | 201 | return 0; |
@@ -208,21 +206,23 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, | |||
208 | return 1; | 206 | return 1; |
209 | } | 207 | } |
210 | 208 | ||
211 | 209 | static int | |
212 | static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, | 210 | parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen, |
213 | int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) | 211 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts) |
214 | { | 212 | { |
215 | int i; | 213 | int i; |
214 | |||
216 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { | 215 | for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { |
217 | if (!parse_bag(sk_PKCS12_SAFEBAG_value (bags, i), | 216 | if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), pass, passlen, |
218 | pass, passlen, pkey, ocerts)) | 217 | pkey, ocerts)) |
219 | return 0; | 218 | return 0; |
220 | } | 219 | } |
221 | return 1; | 220 | return 1; |
222 | } | 221 | } |
223 | 222 | ||
224 | static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, | 223 | static int |
225 | EVP_PKEY **pkey, STACK_OF(X509) *ocerts) | 224 | parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey, |
225 | STACK_OF(X509) *ocerts) | ||
226 | { | 226 | { |
227 | PKCS8_PRIV_KEY_INFO *p8; | 227 | PKCS8_PRIV_KEY_INFO *p8; |
228 | X509 *x509; | 228 | X509 *x509; |
@@ -236,67 +236,63 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, | |||
236 | if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) | 236 | if ((attrib = PKCS12_get_attr (bag, NID_localKeyID))) |
237 | lkid = attrib->value.octet_string; | 237 | lkid = attrib->value.octet_string; |
238 | 238 | ||
239 | switch (M_PKCS12_bag_type(bag)) | 239 | switch (M_PKCS12_bag_type(bag)) { |
240 | { | ||
241 | case NID_keyBag: | 240 | case NID_keyBag: |
242 | if (!pkey || *pkey) | 241 | if (!pkey || *pkey) |
243 | return 1; | 242 | return 1; |
244 | if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) | 243 | if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) |
245 | return 0; | 244 | return 0; |
246 | break; | 245 | break; |
247 | 246 | ||
248 | case NID_pkcs8ShroudedKeyBag: | 247 | case NID_pkcs8ShroudedKeyBag: |
249 | if (!pkey || *pkey) | 248 | if (!pkey || *pkey) |
250 | return 1; | 249 | return 1; |
251 | if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) | 250 | if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) |
252 | return 0; | 251 | return 0; |
253 | *pkey = EVP_PKCS82PKEY(p8); | 252 | *pkey = EVP_PKCS82PKEY(p8); |
254 | PKCS8_PRIV_KEY_INFO_free(p8); | 253 | PKCS8_PRIV_KEY_INFO_free(p8); |
255 | if (!(*pkey)) return 0; | 254 | if (!(*pkey)) |
256 | break; | 255 | return 0; |
256 | break; | ||
257 | 257 | ||
258 | case NID_certBag: | 258 | case NID_certBag: |
259 | if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) | 259 | if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate ) |
260 | return 1; | 260 | return 1; |
261 | if (!(x509 = PKCS12_certbag2x509(bag))) | 261 | if (!(x509 = PKCS12_certbag2x509(bag))) |
262 | return 0; | 262 | return 0; |
263 | if(lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) | 263 | if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { |
264 | { | ||
265 | X509_free(x509); | 264 | X509_free(x509); |
266 | return 0; | 265 | return 0; |
267 | } | 266 | } |
268 | if(fname) { | 267 | if (fname) { |
269 | int len, r; | 268 | int len, r; |
270 | unsigned char *data; | 269 | unsigned char *data; |
271 | len = ASN1_STRING_to_UTF8(&data, fname); | 270 | len = ASN1_STRING_to_UTF8(&data, fname); |
272 | if(len >= 0) { | 271 | if (len >= 0) { |
273 | r = X509_alias_set1(x509, data, len); | 272 | r = X509_alias_set1(x509, data, len); |
274 | free(data); | 273 | free(data); |
275 | if (!r) | 274 | if (!r) { |
276 | { | ||
277 | X509_free(x509); | 275 | X509_free(x509); |
278 | return 0; | 276 | return 0; |
279 | } | 277 | } |
280 | } | 278 | } |
281 | } | 279 | } |
282 | 280 | ||
283 | if(!sk_X509_push(ocerts, x509)) | 281 | if (!sk_X509_push(ocerts, x509)) { |
284 | { | ||
285 | X509_free(x509); | 282 | X509_free(x509); |
286 | return 0; | 283 | return 0; |
287 | } | 284 | } |
288 | 285 | ||
289 | break; | 286 | break; |
290 | 287 | ||
291 | case NID_safeContentsBag: | 288 | case NID_safeContentsBag: |
292 | return parse_bags(bag->value.safes, pass, passlen, | 289 | return parse_bags(bag->value.safes, pass, passlen, |
293 | pkey, ocerts); | 290 | pkey, ocerts); |
294 | break; | 291 | break; |
295 | 292 | ||
296 | default: | 293 | default: |
297 | return 1; | 294 | return 1; |
298 | break; | 295 | break; |
299 | } | 296 | } |
300 | return 1; | 297 | return 1; |
301 | } | 298 | } |
302 | |||