155714Skris/* p12_kiss.c */
2280304Sjkim/*
3280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4280304Sjkim * 1999.
555714Skris */
655714Skris/* ====================================================================
755714Skris * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
855714Skris *
955714Skris * Redistribution and use in source and binary forms, with or without
1055714Skris * modification, are permitted provided that the following conditions
1155714Skris * are met:
1255714Skris *
1355714Skris * 1. Redistributions of source code must retain the above copyright
14280304Sjkim *    notice, this list of conditions and the following disclaimer.
1555714Skris *
1655714Skris * 2. Redistributions in binary form must reproduce the above copyright
1755714Skris *    notice, this list of conditions and the following disclaimer in
1855714Skris *    the documentation and/or other materials provided with the
1955714Skris *    distribution.
2055714Skris *
2155714Skris * 3. All advertising materials mentioning features or use of this
2255714Skris *    software must display the following acknowledgment:
2355714Skris *    "This product includes software developed by the OpenSSL Project
2455714Skris *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2555714Skris *
2655714Skris * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2755714Skris *    endorse or promote products derived from this software without
2855714Skris *    prior written permission. For written permission, please contact
2955714Skris *    licensing@OpenSSL.org.
3055714Skris *
3155714Skris * 5. Products derived from this software may not be called "OpenSSL"
3255714Skris *    nor may "OpenSSL" appear in their names without prior written
3355714Skris *    permission of the OpenSSL Project.
3455714Skris *
3555714Skris * 6. Redistributions of any form whatsoever must retain the following
3655714Skris *    acknowledgment:
3755714Skris *    "This product includes software developed by the OpenSSL Project
3855714Skris *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3955714Skris *
4055714Skris * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4155714Skris * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4255714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4355714Skris * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4455714Skris * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4555714Skris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4655714Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4755714Skris * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4955714Skris * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5055714Skris * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5155714Skris * OF THE POSSIBILITY OF SUCH DAMAGE.
5255714Skris * ====================================================================
5355714Skris *
5455714Skris * This product includes cryptographic software written by Eric Young
5555714Skris * (eay@cryptsoft.com).  This product includes software written by Tim
5655714Skris * Hudson (tjh@cryptsoft.com).
5755714Skris *
5855714Skris */
5955714Skris
6055714Skris#include <stdio.h>
6155714Skris#include "cryptlib.h"
6255714Skris#include <openssl/pkcs12.h>
6355714Skris
6455714Skris/* Simplified PKCS#12 routines */
6555714Skris
66280304Sjkimstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
67280304Sjkim                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
6859191Skris
69280304Sjkimstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
70280304Sjkim                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
7159191Skris
72280304Sjkimstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
73280304Sjkim                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
7459191Skris
75280304Sjkim/*
76280304Sjkim * Parse and decrypt a PKCS#12 structure returning user key, user cert and
77280304Sjkim * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
78280304Sjkim * should point to a valid STACK structure. pkey and cert can be passed
79280304Sjkim * unitialised.
8055714Skris */
8155714Skris
82160814Ssimonint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
83280304Sjkim                 STACK_OF(X509) **ca)
8455714Skris{
85280304Sjkim    STACK_OF(X509) *ocerts = NULL;
86280304Sjkim    X509 *x = NULL;
87280304Sjkim    /* Check for NULL PKCS12 structure */
8855714Skris
89280304Sjkim    if (!p12) {
90280304Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE,
91280304Sjkim                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
92280304Sjkim        return 0;
93280304Sjkim    }
9455714Skris
95280304Sjkim    if (pkey)
96280304Sjkim        *pkey = NULL;
97280304Sjkim    if (cert)
98280304Sjkim        *cert = NULL;
9955714Skris
100280304Sjkim    /* Check the mac */
10155714Skris
102280304Sjkim    /*
103280304Sjkim     * If password is zero length or NULL then try verifying both cases to
104280304Sjkim     * determine which password is correct. The reason for this is that under
105280304Sjkim     * PKCS#12 password based encryption no password and a zero length
106280304Sjkim     * password are two different things...
107280304Sjkim     */
10868651Skris
109280304Sjkim    if (!pass || !*pass) {
110280304Sjkim        if (PKCS12_verify_mac(p12, NULL, 0))
111280304Sjkim            pass = NULL;
112280304Sjkim        else if (PKCS12_verify_mac(p12, "", 0))
113280304Sjkim            pass = "";
114280304Sjkim        else {
115280304Sjkim            PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
116280304Sjkim            goto err;
117280304Sjkim        }
118280304Sjkim    } else if (!PKCS12_verify_mac(p12, pass, -1)) {
119280304Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
120280304Sjkim        goto err;
121280304Sjkim    }
12255714Skris
123280304Sjkim    /* Allocate stack for other certificates */
124280304Sjkim    ocerts = sk_X509_new_null();
125238405Sjkim
126280304Sjkim    if (!ocerts) {
127280304Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
128280304Sjkim        return 0;
129280304Sjkim    }
130238405Sjkim
131280304Sjkim    if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
132280304Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
133280304Sjkim        goto err;
134280304Sjkim    }
13555714Skris
136280304Sjkim    while ((x = sk_X509_pop(ocerts))) {
137280304Sjkim        if (pkey && *pkey && cert && !*cert) {
138285330Sjkim            ERR_set_mark();
139280304Sjkim            if (X509_check_private_key(x, *pkey)) {
140280304Sjkim                *cert = x;
141280304Sjkim                x = NULL;
142280304Sjkim            }
143285330Sjkim            ERR_pop_to_mark();
144280304Sjkim        }
145238405Sjkim
146280304Sjkim        if (ca && x) {
147280304Sjkim            if (!*ca)
148280304Sjkim                *ca = sk_X509_new_null();
149280304Sjkim            if (!*ca)
150280304Sjkim                goto err;
151280304Sjkim            if (!sk_X509_push(*ca, x))
152280304Sjkim                goto err;
153280304Sjkim            x = NULL;
154280304Sjkim        }
155280304Sjkim        if (x)
156280304Sjkim            X509_free(x);
157280304Sjkim    }
158238405Sjkim
159280304Sjkim    if (ocerts)
160280304Sjkim        sk_X509_pop_free(ocerts, X509_free);
161238405Sjkim
162280304Sjkim    return 1;
16355714Skris
16459191Skris err:
16555714Skris
166280304Sjkim    if (pkey && *pkey)
167280304Sjkim        EVP_PKEY_free(*pkey);
168280304Sjkim    if (cert && *cert)
169280304Sjkim        X509_free(*cert);
170280304Sjkim    if (x)
171280304Sjkim        X509_free(x);
172280304Sjkim    if (ocerts)
173280304Sjkim        sk_X509_pop_free(ocerts, X509_free);
174280304Sjkim    return 0;
17559191Skris
17655714Skris}
17755714Skris
17855714Skris/* Parse the outer PKCS#12 structure */
17955714Skris
180160814Ssimonstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
181280304Sjkim                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
18255714Skris{
183280304Sjkim    STACK_OF(PKCS7) *asafes;
184280304Sjkim    STACK_OF(PKCS12_SAFEBAG) *bags;
185280304Sjkim    int i, bagnid;
186280304Sjkim    PKCS7 *p7;
18768651Skris
188280304Sjkim    if (!(asafes = PKCS12_unpack_authsafes(p12)))
189280304Sjkim        return 0;
190280304Sjkim    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
191280304Sjkim        p7 = sk_PKCS7_value(asafes, i);
192280304Sjkim        bagnid = OBJ_obj2nid(p7->type);
193280304Sjkim        if (bagnid == NID_pkcs7_data) {
194280304Sjkim            bags = PKCS12_unpack_p7data(p7);
195280304Sjkim        } else if (bagnid == NID_pkcs7_encrypted) {
196280304Sjkim            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
197280304Sjkim        } else
198280304Sjkim            continue;
199280304Sjkim        if (!bags) {
200280304Sjkim            sk_PKCS7_pop_free(asafes, PKCS7_free);
201280304Sjkim            return 0;
202280304Sjkim        }
203280304Sjkim        if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
204280304Sjkim            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
205280304Sjkim            sk_PKCS7_pop_free(asafes, PKCS7_free);
206280304Sjkim            return 0;
207280304Sjkim        }
208280304Sjkim        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
209280304Sjkim    }
210280304Sjkim    sk_PKCS7_pop_free(asafes, PKCS7_free);
211280304Sjkim    return 1;
21255714Skris}
21355714Skris
214160814Ssimonstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
215280304Sjkim                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
21655714Skris{
217280304Sjkim    int i;
218280304Sjkim    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
219280304Sjkim        if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
220280304Sjkim                       pass, passlen, pkey, ocerts))
221280304Sjkim            return 0;
222280304Sjkim    }
223280304Sjkim    return 1;
22455714Skris}
22555714Skris
22659191Skrisstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
227280304Sjkim                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
22855714Skris{
229280304Sjkim    PKCS8_PRIV_KEY_INFO *p8;
230280304Sjkim    X509 *x509;
231280304Sjkim    ASN1_TYPE *attrib;
232280304Sjkim    ASN1_BMPSTRING *fname = NULL;
233280304Sjkim    ASN1_OCTET_STRING *lkid = NULL;
23455714Skris
235280304Sjkim    if ((attrib = PKCS12_get_attr(bag, NID_friendlyName)))
236280304Sjkim        fname = attrib->value.bmpstring;
23755714Skris
238280304Sjkim    if ((attrib = PKCS12_get_attr(bag, NID_localKeyID)))
239280304Sjkim        lkid = attrib->value.octet_string;
24055714Skris
241280304Sjkim    switch (M_PKCS12_bag_type(bag)) {
242280304Sjkim    case NID_keyBag:
243280304Sjkim        if (!pkey || *pkey)
244280304Sjkim            return 1;
245280304Sjkim        if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
246280304Sjkim            return 0;
247280304Sjkim        break;
24855714Skris
249280304Sjkim    case NID_pkcs8ShroudedKeyBag:
250280304Sjkim        if (!pkey || *pkey)
251280304Sjkim            return 1;
252280304Sjkim        if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
253280304Sjkim            return 0;
254280304Sjkim        *pkey = EVP_PKCS82PKEY(p8);
255280304Sjkim        PKCS8_PRIV_KEY_INFO_free(p8);
256280304Sjkim        if (!(*pkey))
257280304Sjkim            return 0;
258280304Sjkim        break;
25955714Skris
260280304Sjkim    case NID_certBag:
261280304Sjkim        if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
262280304Sjkim            return 1;
263280304Sjkim        if (!(x509 = PKCS12_certbag2x509(bag)))
264280304Sjkim            return 0;
265280304Sjkim        if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
266280304Sjkim            X509_free(x509);
267280304Sjkim            return 0;
268280304Sjkim        }
269280304Sjkim        if (fname) {
270280304Sjkim            int len, r;
271280304Sjkim            unsigned char *data;
272280304Sjkim            len = ASN1_STRING_to_UTF8(&data, fname);
273280304Sjkim            if (len >= 0) {
274280304Sjkim                r = X509_alias_set1(x509, data, len);
275280304Sjkim                OPENSSL_free(data);
276280304Sjkim                if (!r) {
277280304Sjkim                    X509_free(x509);
278280304Sjkim                    return 0;
279280304Sjkim                }
280280304Sjkim            }
281280304Sjkim        }
28268651Skris
283280304Sjkim        if (!sk_X509_push(ocerts, x509)) {
284280304Sjkim            X509_free(x509);
285280304Sjkim            return 0;
286280304Sjkim        }
28768651Skris
288280304Sjkim        break;
28955714Skris
290280304Sjkim    case NID_safeContentsBag:
291280304Sjkim        return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
292280304Sjkim        break;
29355714Skris
294280304Sjkim    default:
295280304Sjkim        return 1;
296280304Sjkim        break;
297280304Sjkim    }
298280304Sjkim    return 1;
29955714Skris}
300