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