PACKETise ServerHello processing
[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 "internal/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             ERR_set_mark();
139             if (X509_check_private_key(x, *pkey)) {
140                 *cert = x;
141                 x = NULL;
142             }
143             ERR_pop_to_mark();
144         }
145
146         if (ca && x) {
147             if (!*ca)
148                 *ca = sk_X509_new_null();
149             if (!*ca)
150                 goto err;
151             if (!sk_X509_push(*ca, x))
152                 goto err;
153             x = NULL;
154         }
155         X509_free(x);
156     }
157
158     sk_X509_pop_free(ocerts, X509_free);
159
160     return 1;
161
162  err:
163
164     if (pkey)
165         EVP_PKEY_free(*pkey);
166     if (cert)
167         X509_free(*cert);
168     X509_free(x);
169     sk_X509_pop_free(ocerts, X509_free);
170     return 0;
171
172 }
173
174 /* Parse the outer PKCS#12 structure */
175
176 static int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
177                       EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
178 {
179     STACK_OF(PKCS7) *asafes;
180     STACK_OF(PKCS12_SAFEBAG) *bags;
181     int i, bagnid;
182     PKCS7 *p7;
183
184     if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
185         return 0;
186     for (i = 0; i < sk_PKCS7_num(asafes); i++) {
187         p7 = sk_PKCS7_value(asafes, i);
188         bagnid = OBJ_obj2nid(p7->type);
189         if (bagnid == NID_pkcs7_data) {
190             bags = PKCS12_unpack_p7data(p7);
191         } else if (bagnid == NID_pkcs7_encrypted) {
192             bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
193         } else
194             continue;
195         if (!bags) {
196             sk_PKCS7_pop_free(asafes, PKCS7_free);
197             return 0;
198         }
199         if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
200             sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
201             sk_PKCS7_pop_free(asafes, PKCS7_free);
202             return 0;
203         }
204         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
205     }
206     sk_PKCS7_pop_free(asafes, PKCS7_free);
207     return 1;
208 }
209
210 static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
211                       int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
212 {
213     int i;
214     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
215         if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
216                        pass, passlen, pkey, ocerts))
217             return 0;
218     }
219     return 1;
220 }
221
222 static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
223                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
224 {
225     PKCS8_PRIV_KEY_INFO *p8;
226     X509 *x509;
227     ASN1_TYPE *attrib;
228     ASN1_BMPSTRING *fname = NULL;
229     ASN1_OCTET_STRING *lkid = NULL;
230
231     if ((attrib = PKCS12_get_attr(bag, NID_friendlyName)))
232         fname = attrib->value.bmpstring;
233
234     if ((attrib = PKCS12_get_attr(bag, NID_localKeyID)))
235         lkid = attrib->value.octet_string;
236
237     switch (M_PKCS12_bag_type(bag)) {
238     case NID_keyBag:
239         if (!pkey || *pkey)
240             return 1;
241         if ((*pkey = EVP_PKCS82PKEY(bag->value.keybag)) == NULL)
242             return 0;
243         break;
244
245     case NID_pkcs8ShroudedKeyBag:
246         if (!pkey || *pkey)
247             return 1;
248         if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
249             return 0;
250         *pkey = EVP_PKCS82PKEY(p8);
251         PKCS8_PRIV_KEY_INFO_free(p8);
252         if (!(*pkey))
253             return 0;
254         break;
255
256     case NID_certBag:
257         if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
258             return 1;
259         if ((x509 = PKCS12_certbag2x509(bag)) == NULL)
260             return 0;
261         if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
262             X509_free(x509);
263             return 0;
264         }
265         if (fname) {
266             int len, r;
267             unsigned char *data;
268             len = ASN1_STRING_to_UTF8(&data, fname);
269             if (len >= 0) {
270                 r = X509_alias_set1(x509, data, len);
271                 OPENSSL_free(data);
272                 if (!r) {
273                     X509_free(x509);
274                     return 0;
275                 }
276             }
277         }
278
279         if (!sk_X509_push(ocerts, x509)) {
280             X509_free(x509);
281             return 0;
282         }
283
284         break;
285
286     case NID_safeContentsBag:
287         return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
288
289     default:
290         return 1;
291     }
292     return 1;
293 }