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