Import LibreSSL v2.4.2 to vendor branch
[dragonfly.git] / crypto / libressl / crypto / pkcs12 / p12_kiss.c
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 }