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