Clear outputs in PKCS12_parse error handling.
[openssl.git] / crypto / pkcs12 / p12_kiss.c
1 /* p12_kiss.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4  * 1999.
5  */
6 /* ====================================================================
7  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This product includes cryptographic software written by Eric Young
55  * (eay@cryptsoft.com).  This product includes software written by Tim
56  * Hudson (tjh@cryptsoft.com).
57  *
58  */
59
60 #include <stdio.h>
61 #include "cryptlib.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 /*
76  * Parse and decrypt a PKCS#12 structure returning user key, user cert and
77  * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
78  * should point to a valid STACK structure. pkey and cert can be passed
79  * unitialised.
80  */
81
82 int 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
88     if (pkey)
89         *pkey = NULL;
90     if (cert)
91         *cert = NULL;
92
93     /* Check for NULL PKCS12 structure */
94
95     if (!p12) {
96         PKCS12err(PKCS12_F_PKCS12_PARSE,
97                   PKCS12_R_INVALID_NULL_PKCS12_POINTER);
98         return 0;
99     }
100
101     /* Check the mac */
102
103     /*
104      * If password is zero length or NULL then try verifying both cases to
105      * determine which password is correct. The reason for this is that under
106      * PKCS#12 password based encryption no password and a zero length
107      * password are two different things...
108      */
109
110     if (!pass || !*pass) {
111         if (PKCS12_verify_mac(p12, NULL, 0))
112             pass = NULL;
113         else if (PKCS12_verify_mac(p12, "", 0))
114             pass = "";
115         else {
116             PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
117             goto err;
118         }
119     } else if (!PKCS12_verify_mac(p12, pass, -1)) {
120         PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
121         goto err;
122     }
123
124     /* Allocate stack for other certificates */
125     ocerts = sk_X509_new_null();
126
127     if (!ocerts) {
128         PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
129         goto err;
130     }
131
132     if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
133         PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
134         goto err;
135     }
136
137     while ((x = sk_X509_pop(ocerts))) {
138         if (pkey && *pkey && cert && !*cert) {
139             ERR_set_mark();
140             if (X509_check_private_key(x, *pkey)) {
141                 *cert = x;
142                 x = NULL;
143             }
144             ERR_pop_to_mark();
145         }
146
147         if (ca && x) {
148             if (!*ca)
149                 *ca = sk_X509_new_null();
150             if (!*ca)
151                 goto err;
152             if (!sk_X509_push(*ca, x))
153                 goto err;
154             x = NULL;
155         }
156         if (x)
157             X509_free(x);
158     }
159
160     if (ocerts)
161         sk_X509_pop_free(ocerts, X509_free);
162
163     return 1;
164
165  err:
166
167     if (pkey) {
168         EVP_PKEY_free(*pkey);
169         *pkey = NULL;
170     }
171     if (cert) {
172         X509_free(*cert);
173         *cert = NULL;
174     }
175     if (x)
176         X509_free(x);
177     if (ocerts)
178         sk_X509_pop_free(ocerts, X509_free);
179     return 0;
180
181 }
182
183 /* Parse the outer PKCS#12 structure */
184
185 static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
186                       EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
187 {
188     STACK_OF(PKCS7) *asafes;
189     STACK_OF(PKCS12_SAFEBAG) *bags;
190     int i, bagnid;
191     PKCS7 *p7;
192
193     if (!(asafes = PKCS12_unpack_authsafes(p12)))
194         return 0;
195     for (i = 0; i < sk_PKCS7_num(asafes); i++) {
196         p7 = sk_PKCS7_value(asafes, i);
197         bagnid = OBJ_obj2nid(p7->type);
198         if (bagnid == NID_pkcs7_data) {
199             bags = PKCS12_unpack_p7data(p7);
200         } else if (bagnid == NID_pkcs7_encrypted) {
201             bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
202         } else
203             continue;
204         if (!bags) {
205             sk_PKCS7_pop_free(asafes, PKCS7_free);
206             return 0;
207         }
208         if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
209             sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
210             sk_PKCS7_pop_free(asafes, PKCS7_free);
211             return 0;
212         }
213         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
214     }
215     sk_PKCS7_pop_free(asafes, PKCS7_free);
216     return 1;
217 }
218
219 static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
220                       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
221 {
222     int i;
223     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
224         if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
225                        pass, passlen, pkey, ocerts))
226             return 0;
227     }
228     return 1;
229 }
230
231 static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
232                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
233 {
234     PKCS8_PRIV_KEY_INFO *p8;
235     X509 *x509;
236     ASN1_TYPE *attrib;
237     ASN1_BMPSTRING *fname = NULL;
238     ASN1_OCTET_STRING *lkid = NULL;
239
240     if ((attrib = PKCS12_get_attr(bag, NID_friendlyName)))
241         fname = attrib->value.bmpstring;
242
243     if ((attrib = PKCS12_get_attr(bag, NID_localKeyID)))
244         lkid = attrib->value.octet_string;
245
246     switch (M_PKCS12_bag_type(bag)) {
247     case NID_keyBag:
248         if (!pkey || *pkey)
249             return 1;
250         if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
251             return 0;
252         break;
253
254     case NID_pkcs8ShroudedKeyBag:
255         if (!pkey || *pkey)
256             return 1;
257         if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
258             return 0;
259         *pkey = EVP_PKCS82PKEY(p8);
260         PKCS8_PRIV_KEY_INFO_free(p8);
261         if (!(*pkey))
262             return 0;
263         break;
264
265     case NID_certBag:
266         if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
267             return 1;
268         if (!(x509 = PKCS12_certbag2x509(bag)))
269             return 0;
270         if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
271             X509_free(x509);
272             return 0;
273         }
274         if (fname) {
275             int len, r;
276             unsigned char *data;
277             len = ASN1_STRING_to_UTF8(&data, fname);
278             if (len >= 0) {
279                 r = X509_alias_set1(x509, data, len);
280                 OPENSSL_free(data);
281                 if (!r) {
282                     X509_free(x509);
283                     return 0;
284                 }
285             }
286         }
287
288         if (!sk_X509_push(ocerts, x509)) {
289             X509_free(x509);
290             return 0;
291         }
292
293         break;
294
295     case NID_safeContentsBag:
296         return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
297         break;
298
299     default:
300         return 1;
301         break;
302     }
303     return 1;
304 }