cd1842789f037da5e841132868dda2dfbe446a26
[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     /* 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     /*
103      * If password is zero length or NULL then try verifying both cases to
104      * determine which password is correct. The reason for this is that under
105      * PKCS#12 password based encryption no password and a zero length
106      * password are two different things...
107      */
108
109     if (!pass || !*pass) {
110         if (PKCS12_verify_mac(p12, NULL, 0))
111             pass = NULL;
112         else if (PKCS12_verify_mac(p12, "", 0))
113             pass = "";
114         else {
115             PKCS12err(PKCS12_F_PKCS12_PARSE, 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
126     if (!ocerts) {
127         PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
128         return 0;
129     }
130
131     if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
132         PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
133         goto err;
134     }
135
136     while ((x = sk_X509_pop(ocerts))) {
137         if (pkey && *pkey && cert && !*cert) {
138             if (X509_check_private_key(x, *pkey)) {
139                 *cert = x;
140                 x = NULL;
141             }
142         }
143
144         if (ca && x) {
145             if (!*ca)
146                 *ca = sk_X509_new_null();
147             if (!*ca)
148                 goto err;
149             if (!sk_X509_push(*ca, x))
150                 goto err;
151             x = NULL;
152         }
153         X509_free(x);
154     }
155
156     sk_X509_pop_free(ocerts, X509_free);
157
158     return 1;
159
160  err:
161
162     if (pkey)
163         EVP_PKEY_free(*pkey);
164     if (cert)
165         X509_free(*cert);
166     X509_free(x);
167     sk_X509_pop_free(ocerts, X509_free);
168     return 0;
169
170 }
171
172 /* Parse the outer PKCS#12 structure */
173
174 static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
175                       EVP_PKEY **pkey, 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 parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
209                       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
210 {
211     int i;
212     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
213         if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
214                        pass, passlen, pkey, ocerts))
215             return 0;
216     }
217     return 1;
218 }
219
220 static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
221                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
222 {
223     PKCS8_PRIV_KEY_INFO *p8;
224     X509 *x509;
225     ASN1_TYPE *attrib;
226     ASN1_BMPSTRING *fname = NULL;
227     ASN1_OCTET_STRING *lkid = NULL;
228
229     if ((attrib = PKCS12_get_attr(bag, NID_friendlyName)))
230         fname = attrib->value.bmpstring;
231
232     if ((attrib = PKCS12_get_attr(bag, NID_localKeyID)))
233         lkid = attrib->value.octet_string;
234
235     switch (M_PKCS12_bag_type(bag)) {
236     case NID_keyBag:
237         if (!pkey || *pkey)
238             return 1;
239         if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
240             return 0;
241         break;
242
243     case NID_pkcs8ShroudedKeyBag:
244         if (!pkey || *pkey)
245             return 1;
246         if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
247             return 0;
248         *pkey = EVP_PKCS82PKEY(p8);
249         PKCS8_PRIV_KEY_INFO_free(p8);
250         if (!(*pkey))
251             return 0;
252         break;
253
254     case NID_certBag:
255         if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
256             return 1;
257         if (!(x509 = PKCS12_certbag2x509(bag)))
258             return 0;
259         if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
260             X509_free(x509);
261             return 0;
262         }
263         if (fname) {
264             int len, r;
265             unsigned char *data;
266             len = ASN1_STRING_to_UTF8(&data, fname);
267             if (len >= 0) {
268                 r = X509_alias_set1(x509, data, len);
269                 OPENSSL_free(data);
270                 if (!r) {
271                     X509_free(x509);
272                     return 0;
273                 }
274             }
275         }
276
277         if (!sk_X509_push(ocerts, x509)) {
278             X509_free(x509);
279             return 0;
280         }
281
282         break;
283
284     case NID_safeContentsBag:
285         return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
286
287     default:
288         return 1;
289     }
290     return 1;
291 }