1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include <stdio.h>
11e1051a39Sopenharmony_ci#include "internal/cryptlib.h"
12e1051a39Sopenharmony_ci#include <openssl/pkcs12.h>
13e1051a39Sopenharmony_ci#include "crypto/x509.h" /* for ossl_x509_add_cert_new() */
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_ci/* Simplified PKCS#12 routines */
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_cistatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
18e1051a39Sopenharmony_ci                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cistatic int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
21e1051a39Sopenharmony_ci                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_cistatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
24e1051a39Sopenharmony_ci                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts);
25e1051a39Sopenharmony_ci
26e1051a39Sopenharmony_ci/*
27e1051a39Sopenharmony_ci * Parse and decrypt a PKCS#12 structure returning user key, user cert and
28e1051a39Sopenharmony_ci * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it
29e1051a39Sopenharmony_ci * should point to a valid STACK structure. pkey and/or cert may be NULL;
30e1051a39Sopenharmony_ci * if non-NULL the variables they point to can be passed uninitialised.
31e1051a39Sopenharmony_ci */
32e1051a39Sopenharmony_ci
33e1051a39Sopenharmony_ciint PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
34e1051a39Sopenharmony_ci                 STACK_OF(X509) **ca)
35e1051a39Sopenharmony_ci{
36e1051a39Sopenharmony_ci    STACK_OF(X509) *ocerts = NULL;
37e1051a39Sopenharmony_ci    X509 *x = NULL;
38e1051a39Sopenharmony_ci
39e1051a39Sopenharmony_ci    if (pkey != NULL)
40e1051a39Sopenharmony_ci        *pkey = NULL;
41e1051a39Sopenharmony_ci    if (cert != NULL)
42e1051a39Sopenharmony_ci        *cert = NULL;
43e1051a39Sopenharmony_ci
44e1051a39Sopenharmony_ci    /* Check for NULL PKCS12 structure */
45e1051a39Sopenharmony_ci
46e1051a39Sopenharmony_ci    if (p12 == NULL) {
47e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER);
48e1051a39Sopenharmony_ci        return 0;
49e1051a39Sopenharmony_ci    }
50e1051a39Sopenharmony_ci
51e1051a39Sopenharmony_ci    /* Check the mac */
52e1051a39Sopenharmony_ci
53e1051a39Sopenharmony_ci    /*
54e1051a39Sopenharmony_ci     * If password is zero length or NULL then try verifying both cases to
55e1051a39Sopenharmony_ci     * determine which password is correct. The reason for this is that under
56e1051a39Sopenharmony_ci     * PKCS#12 password based encryption no password and a zero length
57e1051a39Sopenharmony_ci     * password are two different things...
58e1051a39Sopenharmony_ci     */
59e1051a39Sopenharmony_ci
60e1051a39Sopenharmony_ci    if (pass == NULL || *pass == '\0') {
61e1051a39Sopenharmony_ci        if (!PKCS12_mac_present(p12)
62e1051a39Sopenharmony_ci            || PKCS12_verify_mac(p12, NULL, 0))
63e1051a39Sopenharmony_ci            pass = NULL;
64e1051a39Sopenharmony_ci        else if (PKCS12_verify_mac(p12, "", 0))
65e1051a39Sopenharmony_ci            pass = "";
66e1051a39Sopenharmony_ci        else {
67e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE);
68e1051a39Sopenharmony_ci            goto err;
69e1051a39Sopenharmony_ci        }
70e1051a39Sopenharmony_ci    } else if (!PKCS12_verify_mac(p12, pass, -1)) {
71e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE);
72e1051a39Sopenharmony_ci        goto err;
73e1051a39Sopenharmony_ci    }
74e1051a39Sopenharmony_ci
75e1051a39Sopenharmony_ci    /* If needed, allocate stack for other certificates */
76e1051a39Sopenharmony_ci    if ((cert != NULL || ca != NULL)
77e1051a39Sopenharmony_ci            && (ocerts = sk_X509_new_null()) == NULL) {
78e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
79e1051a39Sopenharmony_ci        goto err;
80e1051a39Sopenharmony_ci    }
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci    if (!parse_pk12(p12, pass, -1, pkey, ocerts)) {
83e1051a39Sopenharmony_ci        int err = ERR_peek_last_error();
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ci        if (ERR_GET_LIB(err) != ERR_LIB_EVP
86e1051a39Sopenharmony_ci                && ERR_GET_REASON(err) != EVP_R_UNSUPPORTED_ALGORITHM)
87e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR);
88e1051a39Sopenharmony_ci        goto err;
89e1051a39Sopenharmony_ci    }
90e1051a39Sopenharmony_ci
91e1051a39Sopenharmony_ci    /* Split the certs in ocerts over *cert and *ca as far as requested */
92e1051a39Sopenharmony_ci    while ((x = sk_X509_shift(ocerts)) != NULL) {
93e1051a39Sopenharmony_ci        if (pkey != NULL && *pkey != NULL
94e1051a39Sopenharmony_ci                && cert != NULL && *cert == NULL) {
95e1051a39Sopenharmony_ci            int match;
96e1051a39Sopenharmony_ci
97e1051a39Sopenharmony_ci            ERR_set_mark();
98e1051a39Sopenharmony_ci            match = X509_check_private_key(x, *pkey);
99e1051a39Sopenharmony_ci            ERR_pop_to_mark();
100e1051a39Sopenharmony_ci            if (match) {
101e1051a39Sopenharmony_ci                *cert = x;
102e1051a39Sopenharmony_ci                continue;
103e1051a39Sopenharmony_ci            }
104e1051a39Sopenharmony_ci        }
105e1051a39Sopenharmony_ci
106e1051a39Sopenharmony_ci        if (ca != NULL) {
107e1051a39Sopenharmony_ci            if (!ossl_x509_add_cert_new(ca, x, X509_ADD_FLAG_DEFAULT))
108e1051a39Sopenharmony_ci                goto err;
109e1051a39Sopenharmony_ci            continue;
110e1051a39Sopenharmony_ci        }
111e1051a39Sopenharmony_ci        X509_free(x);
112e1051a39Sopenharmony_ci    }
113e1051a39Sopenharmony_ci    sk_X509_free(ocerts);
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ci    return 1;
116e1051a39Sopenharmony_ci
117e1051a39Sopenharmony_ci err:
118e1051a39Sopenharmony_ci
119e1051a39Sopenharmony_ci    if (pkey != NULL) {
120e1051a39Sopenharmony_ci        EVP_PKEY_free(*pkey);
121e1051a39Sopenharmony_ci        *pkey = NULL;
122e1051a39Sopenharmony_ci    }
123e1051a39Sopenharmony_ci    if (cert != NULL) {
124e1051a39Sopenharmony_ci        X509_free(*cert);
125e1051a39Sopenharmony_ci        *cert = NULL;
126e1051a39Sopenharmony_ci    }
127e1051a39Sopenharmony_ci    X509_free(x);
128e1051a39Sopenharmony_ci    sk_X509_pop_free(ocerts, X509_free);
129e1051a39Sopenharmony_ci    return 0;
130e1051a39Sopenharmony_ci
131e1051a39Sopenharmony_ci}
132e1051a39Sopenharmony_ci
133e1051a39Sopenharmony_ci/* Parse the outer PKCS#12 structure */
134e1051a39Sopenharmony_ci
135e1051a39Sopenharmony_ci/* pkey and/or ocerts may be NULL */
136e1051a39Sopenharmony_cistatic int parse_pk12(PKCS12 *p12, const char *pass, int passlen,
137e1051a39Sopenharmony_ci                      EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
138e1051a39Sopenharmony_ci{
139e1051a39Sopenharmony_ci    STACK_OF(PKCS7) *asafes;
140e1051a39Sopenharmony_ci    STACK_OF(PKCS12_SAFEBAG) *bags;
141e1051a39Sopenharmony_ci    int i, bagnid;
142e1051a39Sopenharmony_ci    PKCS7 *p7;
143e1051a39Sopenharmony_ci
144e1051a39Sopenharmony_ci    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
145e1051a39Sopenharmony_ci        return 0;
146e1051a39Sopenharmony_ci    for (i = 0; i < sk_PKCS7_num(asafes); i++) {
147e1051a39Sopenharmony_ci        p7 = sk_PKCS7_value(asafes, i);
148e1051a39Sopenharmony_ci        bagnid = OBJ_obj2nid(p7->type);
149e1051a39Sopenharmony_ci        if (bagnid == NID_pkcs7_data) {
150e1051a39Sopenharmony_ci            bags = PKCS12_unpack_p7data(p7);
151e1051a39Sopenharmony_ci        } else if (bagnid == NID_pkcs7_encrypted) {
152e1051a39Sopenharmony_ci            bags = PKCS12_unpack_p7encdata(p7, pass, passlen);
153e1051a39Sopenharmony_ci        } else
154e1051a39Sopenharmony_ci            continue;
155e1051a39Sopenharmony_ci        if (!bags) {
156e1051a39Sopenharmony_ci            sk_PKCS7_pop_free(asafes, PKCS7_free);
157e1051a39Sopenharmony_ci            return 0;
158e1051a39Sopenharmony_ci        }
159e1051a39Sopenharmony_ci        if (!parse_bags(bags, pass, passlen, pkey, ocerts)) {
160e1051a39Sopenharmony_ci            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
161e1051a39Sopenharmony_ci            sk_PKCS7_pop_free(asafes, PKCS7_free);
162e1051a39Sopenharmony_ci            return 0;
163e1051a39Sopenharmony_ci        }
164e1051a39Sopenharmony_ci        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
165e1051a39Sopenharmony_ci    }
166e1051a39Sopenharmony_ci    sk_PKCS7_pop_free(asafes, PKCS7_free);
167e1051a39Sopenharmony_ci    return 1;
168e1051a39Sopenharmony_ci}
169e1051a39Sopenharmony_ci
170e1051a39Sopenharmony_ci/* pkey and/or ocerts may be NULL */
171e1051a39Sopenharmony_cistatic int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass,
172e1051a39Sopenharmony_ci                      int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
173e1051a39Sopenharmony_ci{
174e1051a39Sopenharmony_ci    int i;
175e1051a39Sopenharmony_ci    for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
176e1051a39Sopenharmony_ci        if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i),
177e1051a39Sopenharmony_ci                       pass, passlen, pkey, ocerts))
178e1051a39Sopenharmony_ci            return 0;
179e1051a39Sopenharmony_ci    }
180e1051a39Sopenharmony_ci    return 1;
181e1051a39Sopenharmony_ci}
182e1051a39Sopenharmony_ci
183e1051a39Sopenharmony_ci/* pkey and/or ocerts may be NULL */
184e1051a39Sopenharmony_cistatic int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen,
185e1051a39Sopenharmony_ci                     EVP_PKEY **pkey, STACK_OF(X509) *ocerts)
186e1051a39Sopenharmony_ci{
187e1051a39Sopenharmony_ci    PKCS8_PRIV_KEY_INFO *p8;
188e1051a39Sopenharmony_ci    X509 *x509;
189e1051a39Sopenharmony_ci    const ASN1_TYPE *attrib;
190e1051a39Sopenharmony_ci    ASN1_BMPSTRING *fname = NULL;
191e1051a39Sopenharmony_ci    ASN1_OCTET_STRING *lkid = NULL;
192e1051a39Sopenharmony_ci
193e1051a39Sopenharmony_ci    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_friendlyName)))
194e1051a39Sopenharmony_ci        fname = attrib->value.bmpstring;
195e1051a39Sopenharmony_ci
196e1051a39Sopenharmony_ci    if ((attrib = PKCS12_SAFEBAG_get0_attr(bag, NID_localKeyID)))
197e1051a39Sopenharmony_ci        lkid = attrib->value.octet_string;
198e1051a39Sopenharmony_ci
199e1051a39Sopenharmony_ci    switch (PKCS12_SAFEBAG_get_nid(bag)) {
200e1051a39Sopenharmony_ci    case NID_keyBag:
201e1051a39Sopenharmony_ci        if (pkey == NULL || *pkey != NULL)
202e1051a39Sopenharmony_ci            return 1;
203e1051a39Sopenharmony_ci        *pkey = EVP_PKCS82PKEY(PKCS12_SAFEBAG_get0_p8inf(bag));
204e1051a39Sopenharmony_ci        if (*pkey == NULL)
205e1051a39Sopenharmony_ci            return 0;
206e1051a39Sopenharmony_ci        break;
207e1051a39Sopenharmony_ci
208e1051a39Sopenharmony_ci    case NID_pkcs8ShroudedKeyBag:
209e1051a39Sopenharmony_ci        if (pkey == NULL || *pkey != NULL)
210e1051a39Sopenharmony_ci            return 1;
211e1051a39Sopenharmony_ci        if ((p8 = PKCS12_decrypt_skey(bag, pass, passlen)) == NULL)
212e1051a39Sopenharmony_ci            return 0;
213e1051a39Sopenharmony_ci        *pkey = EVP_PKCS82PKEY(p8);
214e1051a39Sopenharmony_ci        PKCS8_PRIV_KEY_INFO_free(p8);
215e1051a39Sopenharmony_ci        if (!(*pkey))
216e1051a39Sopenharmony_ci            return 0;
217e1051a39Sopenharmony_ci        break;
218e1051a39Sopenharmony_ci
219e1051a39Sopenharmony_ci    case NID_certBag:
220e1051a39Sopenharmony_ci        if (ocerts == NULL
221e1051a39Sopenharmony_ci                || PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate)
222e1051a39Sopenharmony_ci            return 1;
223e1051a39Sopenharmony_ci        if ((x509 = PKCS12_SAFEBAG_get1_cert(bag)) == NULL)
224e1051a39Sopenharmony_ci            return 0;
225e1051a39Sopenharmony_ci        if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) {
226e1051a39Sopenharmony_ci            X509_free(x509);
227e1051a39Sopenharmony_ci            return 0;
228e1051a39Sopenharmony_ci        }
229e1051a39Sopenharmony_ci        if (fname) {
230e1051a39Sopenharmony_ci            int len, r;
231e1051a39Sopenharmony_ci            unsigned char *data;
232e1051a39Sopenharmony_ci
233e1051a39Sopenharmony_ci            len = ASN1_STRING_to_UTF8(&data, fname);
234e1051a39Sopenharmony_ci            if (len >= 0) {
235e1051a39Sopenharmony_ci                r = X509_alias_set1(x509, data, len);
236e1051a39Sopenharmony_ci                OPENSSL_free(data);
237e1051a39Sopenharmony_ci                if (!r) {
238e1051a39Sopenharmony_ci                    X509_free(x509);
239e1051a39Sopenharmony_ci                    return 0;
240e1051a39Sopenharmony_ci                }
241e1051a39Sopenharmony_ci            }
242e1051a39Sopenharmony_ci        }
243e1051a39Sopenharmony_ci
244e1051a39Sopenharmony_ci        if (!sk_X509_push(ocerts, x509)) {
245e1051a39Sopenharmony_ci            X509_free(x509);
246e1051a39Sopenharmony_ci            return 0;
247e1051a39Sopenharmony_ci        }
248e1051a39Sopenharmony_ci
249e1051a39Sopenharmony_ci        break;
250e1051a39Sopenharmony_ci
251e1051a39Sopenharmony_ci    case NID_safeContentsBag:
252e1051a39Sopenharmony_ci        return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey,
253e1051a39Sopenharmony_ci                          ocerts);
254e1051a39Sopenharmony_ci
255e1051a39Sopenharmony_ci    default:
256e1051a39Sopenharmony_ci        return 1;
257e1051a39Sopenharmony_ci    }
258e1051a39Sopenharmony_ci    return 1;
259e1051a39Sopenharmony_ci}
260