]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/pkcs12/p12_crt.c
Move PKCS#12 KDF to provider.
[thirdparty/openssl.git] / crypto / pkcs12 / p12_crt.c
CommitLineData
0f113f3e 1/*
7e06a675 2 * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved.
8d8c7266 3 *
54fffdf4 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
b1322259
RS
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
8d8c7266
DSH
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
ec577822 12#include <openssl/pkcs12.h>
706457b7 13#include "p12_local.h"
8d8c7266 14
852c2ed2
RS
15DEFINE_STACK_OF(X509)
16DEFINE_STACK_OF(PKCS7)
17DEFINE_STACK_OF(PKCS12_SAFEBAG)
18
0f113f3e
MC
19static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
20 PKCS12_SAFEBAG *bag);
9a48b07e 21
8528128b 22static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
0f113f3e
MC
23{
24 int idx;
25 X509_ATTRIBUTE *attr;
26 idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
27 if (idx < 0)
28 return 1;
29 attr = EVP_PKEY_get_attr(pkey, idx);
30 if (!X509at_add1_attr(&bag->attrib, attr))
31 return 0;
32 return 1;
33}
8528128b 34
82af00fb 35PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
0f113f3e
MC
36 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
37 int mac_iter, int keytype)
8d8c7266 38{
0f113f3e
MC
39 PKCS12 *p12 = NULL;
40 STACK_OF(PKCS7) *safes = NULL;
41 STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
42 PKCS12_SAFEBAG *bag = NULL;
43 int i;
44 unsigned char keyid[EVP_MAX_MD_SIZE];
45 unsigned int keyidlen = 0;
46
47 /* Set defaults */
48 if (!nid_cert)
558c94ef 49#ifdef OPENSSL_NO_RC2
0f113f3e 50 nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
558c94ef 51#else
0f113f3e 52 nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
558c94ef 53#endif
0f113f3e
MC
54 if (!nid_key)
55 nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
56 if (!iter)
57 iter = PKCS12_DEFAULT_ITER;
58 if (!mac_iter)
59 mac_iter = 1;
60
12a765a5 61 if (pkey == NULL && cert == NULL && ca == NULL) {
0f113f3e
MC
62 PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
63 return NULL;
64 }
65
66 if (pkey && cert) {
67 if (!X509_check_private_key(cert, pkey))
68 return NULL;
7e06a675
BE
69 if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen))
70 return NULL;
0f113f3e
MC
71 }
72
73 if (cert) {
74 bag = PKCS12_add_cert(&bags, cert);
75 if (name && !PKCS12_add_friendlyname(bag, name, -1))
76 goto err;
77 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
78 goto err;
79 }
80
81 /* Add all other certificates */
82 for (i = 0; i < sk_X509_num(ca); i++) {
83 if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
84 goto err;
85 }
86
87 if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
88 goto err;
89
90 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
91 bags = NULL;
92
93 if (pkey) {
94 bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
95
96 if (!bag)
97 goto err;
98
99 if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
100 goto err;
101 if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
102 goto err;
103
104 if (name && !PKCS12_add_friendlyname(bag, name, -1))
105 goto err;
106 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
107 goto err;
108 }
109
110 if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
111 goto err;
112
113 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
114 bags = NULL;
115
116 p12 = PKCS12_add_safes(safes, 0);
117
12a765a5 118 if (p12 == NULL)
0f113f3e
MC
119 goto err;
120
121 sk_PKCS7_pop_free(safes, PKCS7_free);
122
123 safes = NULL;
124
125 if ((mac_iter != -1) &&
126 !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
127 goto err;
128
129 return p12;
130
131 err:
e0e920b1
RS
132 PKCS12_free(p12);
133 sk_PKCS7_pop_free(safes, PKCS7_free);
134 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
0f113f3e 135 return NULL;
9a48b07e
DSH
136
137}
138
139PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
0f113f3e
MC
140{
141 PKCS12_SAFEBAG *bag = NULL;
142 char *name;
143 int namelen = -1;
144 unsigned char *keyid;
145 int keyidlen = -1;
8d8c7266 146
0f113f3e 147 /* Add user certificate */
293042c9 148 if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
0f113f3e 149 goto err;
9a48b07e 150
0f113f3e
MC
151 /*
152 * Use friendlyName and localKeyID in certificate. (if present)
153 */
9a48b07e 154
0f113f3e 155 name = (char *)X509_alias_get0(cert, &namelen);
9a48b07e 156
0f113f3e
MC
157 if (name && !PKCS12_add_friendlyname(bag, name, namelen))
158 goto err;
9a48b07e 159
0f113f3e 160 keyid = X509_keyid_get0(cert, &keyidlen);
9a48b07e 161
0f113f3e
MC
162 if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
163 goto err;
9a48b07e 164
0f113f3e
MC
165 if (!pkcs12_add_bag(pbags, bag))
166 goto err;
9a48b07e 167
0f113f3e 168 return bag;
9a48b07e 169
0f113f3e 170 err:
e0e920b1 171 PKCS12_SAFEBAG_free(bag);
0f113f3e 172 return NULL;
8d8c7266 173
0f113f3e 174}
9a48b07e 175
0f113f3e
MC
176PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
177 EVP_PKEY *key, int key_usage, int iter,
82af00fb 178 int nid_key, const char *pass)
0f113f3e 179{
9a48b07e 180
0f113f3e
MC
181 PKCS12_SAFEBAG *bag = NULL;
182 PKCS8_PRIV_KEY_INFO *p8 = NULL;
9a48b07e 183
0f113f3e 184 /* Make a PKCS#8 structure */
75ebbd9a 185 if ((p8 = EVP_PKEY2PKCS8(key)) == NULL)
0f113f3e
MC
186 goto err;
187 if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
188 goto err;
189 if (nid_key != -1) {
425f3300
DSH
190 bag = PKCS12_SAFEBAG_create_pkcs8_encrypt(nid_key, pass, -1, NULL, 0,
191 iter, p8);
0f113f3e
MC
192 PKCS8_PRIV_KEY_INFO_free(p8);
193 } else
425f3300 194 bag = PKCS12_SAFEBAG_create0_p8inf(p8);
9a48b07e 195
0f113f3e
MC
196 if (!bag)
197 goto err;
9a48b07e 198
0f113f3e
MC
199 if (!pkcs12_add_bag(pbags, bag))
200 goto err;
9a48b07e 201
0f113f3e 202 return bag;
9a48b07e 203
0f113f3e 204 err:
e0e920b1 205 PKCS12_SAFEBAG_free(bag);
0f113f3e 206 return NULL;
9a48b07e 207
0f113f3e 208}
8d8c7266 209
c5ec6dcf
JS
210PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
211 int nid_type, const unsigned char *value, int len)
212{
213 PKCS12_SAFEBAG *bag = NULL;
214
215 /* Add secret, storing the value as an octet string */
216 if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL)
217 goto err;
218
219 if (!pkcs12_add_bag(pbags, bag))
220 goto err;
221
222 return bag;
223 err:
224 PKCS12_SAFEBAG_free(bag);
225 return NULL;
226}
227
9a48b07e 228int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
82af00fb 229 int nid_safe, int iter, const char *pass)
0f113f3e
MC
230{
231 PKCS7 *p7 = NULL;
232 int free_safes = 0;
233
12a765a5 234 if (*psafes == NULL) {
0f113f3e 235 *psafes = sk_PKCS7_new_null();
12a765a5 236 if (*psafes == NULL)
0f113f3e
MC
237 return 0;
238 free_safes = 1;
12a765a5 239 }
0f113f3e
MC
240
241 if (nid_safe == 0)
558c94ef 242#ifdef OPENSSL_NO_RC2
0f113f3e 243 nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
558c94ef 244#else
0f113f3e 245 nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
558c94ef 246#endif
9a48b07e 247
0f113f3e
MC
248 if (nid_safe == -1)
249 p7 = PKCS12_pack_p7data(bags);
250 else
251 p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
12a765a5 252 if (p7 == NULL)
0f113f3e
MC
253 goto err;
254
255 if (!sk_PKCS7_push(*psafes, p7))
256 goto err;
257
258 return 1;
259
260 err:
261 if (free_safes) {
262 sk_PKCS7_free(*psafes);
263 *psafes = NULL;
264 }
e0e920b1 265 PKCS7_free(p7);
0f113f3e
MC
266 return 0;
267
268}
269
270static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
271 PKCS12_SAFEBAG *bag)
272{
12a765a5
RS
273 int free_bags = 0;
274
275 if (pbags == NULL)
0f113f3e 276 return 1;
12a765a5 277 if (*pbags == NULL) {
0f113f3e 278 *pbags = sk_PKCS12_SAFEBAG_new_null();
12a765a5 279 if (*pbags == NULL)
0f113f3e
MC
280 return 0;
281 free_bags = 1;
12a765a5 282 }
0f113f3e
MC
283
284 if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
285 if (free_bags) {
286 sk_PKCS12_SAFEBAG_free(*pbags);
287 *pbags = NULL;
288 }
289 return 0;
290 }
291
292 return 1;
293
294}
9a48b07e
DSH
295
296PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
0f113f3e
MC
297{
298 PKCS12 *p12;
12a765a5 299
0f113f3e
MC
300 if (nid_p7 <= 0)
301 nid_p7 = NID_pkcs7_data;
302 p12 = PKCS12_init(nid_p7);
12a765a5 303 if (p12 == NULL)
0f113f3e 304 return NULL;
9a48b07e 305
0f113f3e
MC
306 if (!PKCS12_pack_authsafes(p12, safes)) {
307 PKCS12_free(p12);
308 return NULL;
309 }
8d8c7266 310
0f113f3e 311 return p12;
8d8c7266 312
0f113f3e 313}