2 * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include "internal/cryptlib.h"
12 #include <openssl/pkcs12.h>
13 #include "p12_local.h"
15 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
17 static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
20 static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
22 int idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
26 return X509at_add1_attr(&bag->attrib, EVP_PKEY_get_attr(pkey, idx)) != NULL;
29 PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey,
30 X509 *cert, STACK_OF(X509) *ca, int nid_key, int nid_cert,
31 int iter, int mac_iter, int keytype,
32 OSSL_LIB_CTX *ctx, const char *propq,
33 PKCS12_create_cb *cb, void *cbarg)
36 STACK_OF(PKCS7) *safes = NULL;
37 STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
38 PKCS12_SAFEBAG *bag = NULL;
40 unsigned char keyid[EVP_MAX_MD_SIZE];
41 unsigned int keyidlen = 0;
44 if (nid_cert == NID_undef)
45 nid_cert = NID_aes_256_cbc;
46 if (nid_key == NID_undef)
47 nid_key = NID_aes_256_cbc;
49 iter = PKCS12_DEFAULT_ITER;
51 mac_iter = PKCS12_DEFAULT_ITER;
53 if (pkey == NULL && cert == NULL && ca == NULL) {
54 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_ARGUMENT);
59 if (!X509_check_private_key(cert, pkey))
61 if (!X509_digest(cert, EVP_sha1(), keyid, &keyidlen))
66 bag = PKCS12_add_cert(&bags, cert);
67 if (name && !PKCS12_add_friendlyname(bag, name, -1))
69 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
72 cbret = cb(bag, cbarg);
74 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED);
76 } else if (cbret == 0) {
77 pkcs12_remove_bag(&bags, bag);
82 /* Add all other certificates */
83 for (i = 0; i < sk_X509_num(ca); i++) {
84 if ((bag = PKCS12_add_cert(&bags, sk_X509_value(ca, i))) == NULL)
87 cbret = cb(bag, cbarg);
89 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED);
91 } else if (cbret == 0) {
92 pkcs12_remove_bag(&bags, bag);
97 if (bags && !PKCS12_add_safe_ex(&safes, bags, nid_cert, iter, pass,
101 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
105 bag = PKCS12_add_key_ex(&bags, pkey, keytype, iter, nid_key, pass,
111 if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
113 if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
116 if (name && !PKCS12_add_friendlyname(bag, name, -1))
118 if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
121 cbret = cb(bag, cbarg);
123 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CALLBACK_FAILED);
125 } else if (cbret == 0) {
126 pkcs12_remove_bag(&bags, bag);
131 if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
134 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
137 p12 = PKCS12_add_safes_ex(safes, 0, ctx, propq);
142 sk_PKCS7_pop_free(safes, PKCS7_free);
146 if ((mac_iter != -1) &&
147 !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
154 sk_PKCS7_pop_free(safes, PKCS7_free);
155 sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
160 PKCS12 *PKCS12_create_ex(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
161 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
162 int mac_iter, int keytype,
163 OSSL_LIB_CTX *ctx, const char *propq)
165 return PKCS12_create_ex2(pass, name, pkey, cert, ca, nid_key, nid_cert,
166 iter, mac_iter, keytype, ctx, propq,
170 PKCS12 *PKCS12_create(const char *pass, const char *name, EVP_PKEY *pkey, X509 *cert,
171 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
172 int mac_iter, int keytype)
174 return PKCS12_create_ex(pass, name, pkey, cert, ca, nid_key, nid_cert,
175 iter, mac_iter, keytype, NULL, NULL);
178 PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
180 PKCS12_SAFEBAG *bag = NULL;
183 unsigned char *keyid;
186 /* Add user certificate */
187 if ((bag = PKCS12_SAFEBAG_create_cert(cert)) == NULL)
191 * Use friendlyName and localKeyID in certificate. (if present)
194 name = (char *)X509_alias_get0(cert, &namelen);
196 if (name && !PKCS12_add_friendlyname(bag, name, namelen))
199 keyid = X509_keyid_get0(cert, &keyidlen);
201 if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
204 if (!pkcs12_add_bag(pbags, bag))
210 PKCS12_SAFEBAG_free(bag);
215 PKCS12_SAFEBAG *PKCS12_add_key_ex(STACK_OF(PKCS12_SAFEBAG) **pbags,
216 EVP_PKEY *key, int key_usage, int iter,
217 int nid_key, const char *pass,
218 OSSL_LIB_CTX *ctx, const char *propq)
221 PKCS12_SAFEBAG *bag = NULL;
222 PKCS8_PRIV_KEY_INFO *p8 = NULL;
224 /* Make a PKCS#8 structure */
225 if ((p8 = EVP_PKEY2PKCS8(key)) == NULL)
227 if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
230 bag = PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(nid_key, pass, -1, NULL, 0,
231 iter, p8, ctx, propq);
232 PKCS8_PRIV_KEY_INFO_free(p8);
234 bag = PKCS12_SAFEBAG_create0_p8inf(p8);
239 if (!pkcs12_add_bag(pbags, bag))
245 PKCS12_SAFEBAG_free(bag);
250 PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
251 EVP_PKEY *key, int key_usage, int iter,
252 int nid_key, const char *pass)
254 return PKCS12_add_key_ex(pbags, key, key_usage, iter, nid_key, pass,
258 PKCS12_SAFEBAG *PKCS12_add_secret(STACK_OF(PKCS12_SAFEBAG) **pbags,
259 int nid_type, const unsigned char *value, int len)
261 PKCS12_SAFEBAG *bag = NULL;
263 /* Add secret, storing the value as an octet string */
264 if ((bag = PKCS12_SAFEBAG_create_secret(nid_type, V_ASN1_OCTET_STRING, value, len)) == NULL)
267 if (!pkcs12_add_bag(pbags, bag))
272 PKCS12_SAFEBAG_free(bag);
276 int PKCS12_add_safe_ex(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
277 int nid_safe, int iter, const char *pass,
278 OSSL_LIB_CTX *ctx, const char *propq)
283 if (*psafes == NULL) {
284 *psafes = sk_PKCS7_new_null();
291 #ifdef OPENSSL_NO_RC2
292 nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
294 nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
298 p7 = PKCS12_pack_p7data(bags);
300 p7 = PKCS12_pack_p7encdata_ex(nid_safe, pass, -1, NULL, 0, iter, bags, ctx, propq);
304 if (!sk_PKCS7_push(*psafes, p7))
311 sk_PKCS7_free(*psafes);
318 int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
319 int nid_safe, int iter, const char *pass)
321 return PKCS12_add_safe_ex(psafes, bags, nid_safe, iter, pass, NULL, NULL);
325 static int pkcs12_remove_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
330 if (pbags == NULL || bag == NULL)
333 if ((tmp = sk_PKCS12_SAFEBAG_delete_ptr(*pbags, bag)) == NULL)
336 PKCS12_SAFEBAG_free(tmp);
340 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
347 if (*pbags == NULL) {
348 *pbags = sk_PKCS12_SAFEBAG_new_null();
354 if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
356 sk_PKCS12_SAFEBAG_free(*pbags);
366 PKCS12 *PKCS12_add_safes_ex(STACK_OF(PKCS7) *safes, int nid_p7,
367 OSSL_LIB_CTX *ctx, const char *propq)
372 nid_p7 = NID_pkcs7_data;
373 p12 = PKCS12_init_ex(nid_p7, ctx, propq);
377 if (!PKCS12_pack_authsafes(p12, safes)) {
386 PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
388 return PKCS12_add_safes_ex(safes, nid_p7, NULL, NULL);