1 /* $OpenBSD: p12_kiss.c,v 1.16 2014/07/11 08:44:49 jsing 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 
61 #include <openssl/err.h>
62 #include <openssl/pkcs12.h>
63 
64 /* Simplified PKCS#12 routines */
65 
66 static int parse_pk12( PKCS12 *p12, const char *pass, int passlen,
67     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
68 
69 static int parse_bags( STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
70     int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
71 
72 static int parse_bag( PKCS12_SAFEBAG *bag, const char *pass, int passlen,
73     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
74 
75 /* Parse and decrypt a PKCS#12 structure returning user key, user cert
76  * and other (CA) certs. Note either ca should be NULL, *ca should be NULL,
77  * or it should point to a valid STACK structure. pkey and cert can be
78  * passed unitialised.
79  */
80 
81 int
82 PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
83     STACK_OF(X509) **ca)
84 {
85 	STACK_OF(X509) *ocerts = NULL;
86 	X509 *x = NULL;
87 	/* Check for NULL PKCS12 structure */
88 
89 	if (!p12) {
90 		PKCS12err(PKCS12_F_PKCS12_PARSE,
91 		    PKCS12_R_INVALID_NULL_PKCS12_POINTER);
92 		return 0;
93 	}
94 
95 	if (pkey)
96 		*pkey = NULL;
97 	if (cert)
98 		*cert = NULL;
99 
100 	/* Check the mac */
101 
102 	/* If password is zero length or NULL then try verifying both cases
103 	 * to determine which password is correct. The reason for this is that
104 	 * under PKCS#12 password based encryption no password and a zero length
105 	 * password are two different things...
106 	 */
107 
108 	if (!pass || !*pass) {
109 		if (PKCS12_verify_mac(p12, NULL, 0))
110 			pass = NULL;
111 		else if (PKCS12_verify_mac(p12, "", 0))
112 			pass = "";
113 		else {
114 			PKCS12err(PKCS12_F_PKCS12_PARSE,
115 			    PKCS12_R_MAC_VERIFY_FAILURE);
116 			goto err;
117 		}
118 	} else if (!PKCS12_verify_mac(p12, pass, -1)) {
119 		PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
120 		goto err;
121 	}
122 
123 	/* Allocate stack for other certificates */
124 	ocerts = sk_X509_new_null();
125 	if (!ocerts) {
126 		PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
127 		return 0;
128 	}
129 
130 	if (!parse_pk12 (p12, pass, -1, pkey, ocerts)) {
131 		PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
132 		goto err;
133 	}
134 
135 	while ((x = sk_X509_pop(ocerts))) {
136 		if (pkey && *pkey && cert && !*cert) {
137 			if (X509_check_private_key(x, *pkey)) {
138 				*cert = x;
139 				x = NULL;
140 			}
141 		}
142 
143 		if (ca && x) {
144 			if (!*ca)
145 				*ca = sk_X509_new_null();
146 			if (!*ca)
147 				goto err;
148 			if (!sk_X509_push(*ca, x))
149 				goto err;
150 			x = NULL;
151 		}
152 		X509_free(x);
153 	}
154 
155 	if (ocerts)
156 		sk_X509_pop_free(ocerts, X509_free);
157 
158 	return 1;
159 
160 err:
161 	if (pkey && *pkey)
162 		EVP_PKEY_free(*pkey);
163 	if (cert)
164 		X509_free(*cert);
165 	X509_free(x);
166 	if (ocerts)
167 		sk_X509_pop_free(ocerts, X509_free);
168 	return 0;
169 }
170 
171 /* Parse the outer PKCS#12 structure */
172 
173 static int
174 parse_pk12(PKCS12 *p12, const char *pass, int passlen, EVP_PKEY **pkey,
175     STACK_OF(X509) *ocerts)
176 {
177 	STACK_OF(PKCS7) *asafes;
178 	STACK_OF(PKCS12_SAFEBAG) *bags;
179 	int i, bagnid;
180 	PKCS7 *p7;
181 
182 	if (!(asafes = PKCS12_unpack_authsafes (p12)))
183 		return 0;
184 	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
185 		p7 = sk_PKCS7_value (asafes, i);
186 		bagnid = OBJ_obj2nid (p7->type);
187 		if (bagnid == NID_pkcs7_data) {
188 			bags = PKCS12_unpack_p7data(p7);
189 		} else if (bagnid == NID_pkcs7_encrypted) {
190 			bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
191 		} else
192 			continue;
193 		if (!bags) {
194 			sk_PKCS7_pop_free(asafes, PKCS7_free);
195 			return 0;
196 		}
197 		if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
198 			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
199 			sk_PKCS7_pop_free(asafes, PKCS7_free);
200 			return 0;
201 		}
202 		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
203 	}
204 	sk_PKCS7_pop_free(asafes, PKCS7_free);
205 	return 1;
206 }
207 
208 static int
209 parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, int passlen,
210     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
211 {
212 	int i;
213 
214 	for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
215 		if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), pass, passlen,
216 		    pkey, ocerts))
217 			return 0;
218 	}
219 	return 1;
220 }
221 
222 static int
223 parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, EVP_PKEY **pkey,
224     STACK_OF(X509) *ocerts)
225 {
226 	PKCS8_PRIV_KEY_INFO *p8;
227 	X509 *x509;
228 	ASN1_TYPE *attrib;
229 	ASN1_BMPSTRING *fname = NULL;
230 	ASN1_OCTET_STRING *lkid = NULL;
231 
232 	if ((attrib = PKCS12_get_attr (bag, NID_friendlyName)))
233 		fname = attrib->value.bmpstring;
234 
235 	if ((attrib = PKCS12_get_attr (bag, NID_localKeyID)))
236 		lkid = attrib->value.octet_string;
237 
238 	switch (M_PKCS12_bag_type(bag)) {
239 	case NID_keyBag:
240 		if (!pkey || *pkey)
241 			return 1;
242 		if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
243 			return 0;
244 		break;
245 
246 	case NID_pkcs8ShroudedKeyBag:
247 		if (!pkey || *pkey)
248 			return 1;
249 		if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
250 			return 0;
251 		*pkey = EVP_PKCS82PKEY(p8);
252 		PKCS8_PRIV_KEY_INFO_free(p8);
253 		if (!(*pkey))
254 			return 0;
255 		break;
256 
257 	case NID_certBag:
258 		if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate )
259 			return 1;
260 		if (!(x509 = PKCS12_certbag2x509(bag)))
261 			return 0;
262 		if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
263 			X509_free(x509);
264 			return 0;
265 		}
266 		if (fname) {
267 			int len, r;
268 			unsigned char *data;
269 			len = ASN1_STRING_to_UTF8(&data, fname);
270 			if (len >= 0) {
271 				r = X509_alias_set1(x509, data, len);
272 				free(data);
273 				if (!r) {
274 					X509_free(x509);
275 					return 0;
276 				}
277 			}
278 		}
279 
280 		if (!sk_X509_push(ocerts, x509)) {
281 			X509_free(x509);
282 			return 0;
283 		}
284 
285 		break;
286 
287 	case NID_safeContentsBag:
288 		return parse_bags(bag->value.safes, pass, passlen,
289 		    pkey, ocerts);
290 		break;
291 
292 	default:
293 		return 1;
294 		break;
295 	}
296 	return 1;
297 }
298