155714Skris/* p12_kiss.c */
2280297Sjkim/*
3280297Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4280297Sjkim * 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
14280297Sjkim *    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
66280297Sjkimstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
67280297Sjkim                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
6859191Skris
69280297Sjkimstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
70280297Sjkim                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
7159191Skris
72280297Sjkimstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
73280297Sjkim                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
7459191Skris
75280297Sjkim/*
76280297Sjkim * Parse and decrypt a PKCS#12 structure returning user key, user cert and
77280297Sjkim * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
78280297Sjkim * should point to a valid STACK structure. pkey and cert can be passed
79280297Sjkim * unitialised.
8055714Skris */
8155714Skris
82160814Ssimonint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
83280297Sjkim                 STACK_OF(X509) **ca)
8455714Skris{
85280297Sjkim    STACK_OF(X509) *ocerts = NULL;
86280297Sjkim    X509 *x = NULL;
87325337Sjkim
88325337Sjkim    if (pkey)
89325337Sjkim        *pkey = NULL;
90325337Sjkim    if (cert)
91325337Sjkim        *cert = NULL;
92325337Sjkim
93280297Sjkim    /* Check for NULL PKCS12 structure */
9455714Skris
95280297Sjkim    if (!p12) {
96280297Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE,
97280297Sjkim                  PKCS12_R_INVALID_NULL_PKCS12_POINTER);
98280297Sjkim        return 0;
99280297Sjkim    }
10055714Skris
101280297Sjkim    /* Check the mac */
10255714Skris
103280297Sjkim    /*
104280297Sjkim     * If password is zero length or NULL then try verifying both cases to
105280297Sjkim     * determine which password is correct. The reason for this is that under
106280297Sjkim     * PKCS#12 password based encryption no password and a zero length
107280297Sjkim     * password are two different things...
108280297Sjkim     */
10968651Skris
110280297Sjkim    if (!pass || !*pass) {
111280297Sjkim        if (PKCS12_verify_mac(p12, NULL, 0))
112280297Sjkim            pass = NULL;
113280297Sjkim        else if (PKCS12_verify_mac(p12, "", 0))
114280297Sjkim            pass = "";
115280297Sjkim        else {
116280297Sjkim            PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
117280297Sjkim            goto err;
118280297Sjkim        }
119280297Sjkim    } else if (!PKCS12_verify_mac(p12, pass, -1)) {
120280297Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE);
121280297Sjkim        goto err;
122280297Sjkim    }
12355714Skris
124280297Sjkim    /* Allocate stack for other certificates */
125280297Sjkim    ocerts = sk_X509_new_null();
126238405Sjkim
127280297Sjkim    if (!ocerts) {
128280297Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE);
129325337Sjkim        goto err;
130280297Sjkim    }
131238405Sjkim
132280297Sjkim    if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
133280297Sjkim        PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR);
134280297Sjkim        goto err;
135280297Sjkim    }
13655714Skris
137280297Sjkim    while ((x = sk_X509_pop(ocerts))) {
138280297Sjkim        if (pkey && *pkey && cert && !*cert) {
139285329Sjkim            ERR_set_mark();
140280297Sjkim            if (X509_check_private_key(x, *pkey)) {
141280297Sjkim                *cert = x;
142280297Sjkim                x = NULL;
143280297Sjkim            }
144285329Sjkim            ERR_pop_to_mark();
145280297Sjkim        }
146238405Sjkim
147280297Sjkim        if (ca && x) {
148280297Sjkim            if (!*ca)
149280297Sjkim                *ca = sk_X509_new_null();
150280297Sjkim            if (!*ca)
151280297Sjkim                goto err;
152280297Sjkim            if (!sk_X509_push(*ca, x))
153280297Sjkim                goto err;
154280297Sjkim            x = NULL;
155280297Sjkim        }
156280297Sjkim        if (x)
157280297Sjkim            X509_free(x);
158280297Sjkim    }
159238405Sjkim
160280297Sjkim    if (ocerts)
161280297Sjkim        sk_X509_pop_free(ocerts, X509_free);
162238405Sjkim
163280297Sjkim    return 1;
16455714Skris
16559191Skris err:
16655714Skris
167325337Sjkim    if (pkey) {
168280297Sjkim        EVP_PKEY_free(*pkey);
169325337Sjkim        *pkey = NULL;
170325337Sjkim    }
171325337Sjkim    if (cert) {
172280297Sjkim        X509_free(*cert);
173325337Sjkim        *cert = NULL;
174325337Sjkim    }
175280297Sjkim    if (x)
176280297Sjkim        X509_free(x);
177280297Sjkim    if (ocerts)
178280297Sjkim        sk_X509_pop_free(ocerts, X509_free);
179280297Sjkim    return 0;
18059191Skris
18155714Skris}
18255714Skris
18355714Skris/* Parse the outer PKCS#12 structure */
18455714Skris
185160814Ssimonstatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
186280297Sjkim                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
18755714Skris{
188280297Sjkim    STACK_OF(PKCS7) *asafes;
189280297Sjkim    STACK_OF(PKCS12_SAFEBAG) *bags;
190280297Sjkim    int i, bagnid;
191280297Sjkim    PKCS7 *p7;
19268651Skris
193280297Sjkim    if (!(asafes = PKCS12_unpack_authsafes(p12)))
194280297Sjkim        return 0;
195280297Sjkim    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
196280297Sjkim        p7 = sk_PKCS7_value(asafes, i);
197280297Sjkim        bagnid = OBJ_obj2nid(p7->type);
198280297Sjkim        if (bagnid == NID_pkcs7_data) {
199280297Sjkim            bags = PKCS12_unpack_p7data(p7);
200280297Sjkim        } else if (bagnid == NID_pkcs7_encrypted) {
201280297Sjkim            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
202280297Sjkim        } else
203280297Sjkim            continue;
204280297Sjkim        if (!bags) {
205280297Sjkim            sk_PKCS7_pop_free(asafes, PKCS7_free);
206280297Sjkim            return 0;
207280297Sjkim        }
208280297Sjkim        if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
209280297Sjkim            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
210280297Sjkim            sk_PKCS7_pop_free(asafes, PKCS7_free);
211280297Sjkim            return 0;
212280297Sjkim        }
213280297Sjkim        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
214280297Sjkim    }
215280297Sjkim    sk_PKCS7_pop_free(asafes, PKCS7_free);
216280297Sjkim    return 1;
21755714Skris}
21855714Skris
219160814Ssimonstatic int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
220280297Sjkim                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
22155714Skris{
222280297Sjkim    int i;
223280297Sjkim    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
224280297Sjkim        if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
225280297Sjkim                       pass, passlen, pkey, ocerts))
226280297Sjkim            return 0;
227280297Sjkim    }
228280297Sjkim    return 1;
22955714Skris}
23055714Skris
23159191Skrisstatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
232280297Sjkim                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
23355714Skris{
234280297Sjkim    PKCS8_PRIV_KEY_INFO *p8;
235280297Sjkim    X509 *x509;
236280297Sjkim    ASN1_TYPE *attrib;
237280297Sjkim    ASN1_BMPSTRING *fname = NULL;
238280297Sjkim    ASN1_OCTET_STRING *lkid = NULL;
23955714Skris
240280297Sjkim    if ((attrib = PKCS12_get_attr(bag, NID_friendlyName)))
241280297Sjkim        fname = attrib->value.bmpstring;
24255714Skris
243280297Sjkim    if ((attrib = PKCS12_get_attr(bag, NID_localKeyID)))
244280297Sjkim        lkid = attrib->value.octet_string;
24555714Skris
246280297Sjkim    switch (M_PKCS12_bag_type(bag)) {
247280297Sjkim    case NID_keyBag:
248280297Sjkim        if (!pkey || *pkey)
249280297Sjkim            return 1;
250280297Sjkim        if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag)))
251280297Sjkim            return 0;
252280297Sjkim        break;
25355714Skris
254280297Sjkim    case NID_pkcs8ShroudedKeyBag:
255280297Sjkim        if (!pkey || *pkey)
256280297Sjkim            return 1;
257280297Sjkim        if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen)))
258280297Sjkim            return 0;
259280297Sjkim        *pkey = EVP_PKCS82PKEY(p8);
260280297Sjkim        PKCS8_PRIV_KEY_INFO_free(p8);
261280297Sjkim        if (!(*pkey))
262280297Sjkim            return 0;
263280297Sjkim        break;
26455714Skris
265280297Sjkim    case NID_certBag:
266280297Sjkim        if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
267280297Sjkim            return 1;
268280297Sjkim        if (!(x509 = PKCS12_certbag2x509(bag)))
269280297Sjkim            return 0;
270280297Sjkim        if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
271280297Sjkim            X509_free(x509);
272280297Sjkim            return 0;
273280297Sjkim        }
274280297Sjkim        if (fname) {
275280297Sjkim            int len, r;
276280297Sjkim            unsigned char *data;
277280297Sjkim            len = ASN1_STRING_to_UTF8(&data, fname);
278280297Sjkim            if (len >= 0) {
279280297Sjkim                r = X509_alias_set1(x509, data, len);
280280297Sjkim                OPENSSL_free(data);
281280297Sjkim                if (!r) {
282280297Sjkim                    X509_free(x509);
283280297Sjkim                    return 0;
284280297Sjkim                }
285280297Sjkim            }
286280297Sjkim        }
28768651Skris
288280297Sjkim        if (!sk_X509_push(ocerts, x509)) {
289280297Sjkim            X509_free(x509);
290280297Sjkim            return 0;
291280297Sjkim        }
29268651Skris
293280297Sjkim        break;
29455714Skris
295280297Sjkim    case NID_safeContentsBag:
296280297Sjkim        return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts);
297280297Sjkim        break;
29855714Skris
299280297Sjkim    default:
300280297Sjkim        return 1;
301280297Sjkim        break;
302280297Sjkim    }
303280297Sjkim    return 1;
30455714Skris}
305