2 * Copyright 1999-2024 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/core.h>
13 #include <openssl/core_names.h>
14 #include <openssl/pkcs12.h>
15 #include "p12_local.h"
16 #include "crypto/pkcs7/pk7_local.h"
18 /* Pack an object into an OCTET STRING and turn into a safebag */
20 PKCS12_SAFEBAG
*PKCS12_item_pack_safebag(void *obj
, const ASN1_ITEM
*it
,
24 PKCS12_SAFEBAG
*safebag
;
26 if ((bag
= PKCS12_BAGS_new()) == NULL
) {
27 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
30 bag
->type
= OBJ_nid2obj(nid1
);
31 if (!ASN1_item_pack(obj
, it
, &bag
->value
.octet
)) {
32 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
35 if ((safebag
= PKCS12_SAFEBAG_new()) == NULL
) {
36 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
39 safebag
->value
.bag
= bag
;
40 safebag
->type
= OBJ_nid2obj(nid2
);
44 PKCS12_BAGS_free(bag
);
48 /* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
49 PKCS7
*PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG
) *sk
)
53 if ((p7
= PKCS7_new()) == NULL
) {
54 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
57 p7
->type
= OBJ_nid2obj(NID_pkcs7_data
);
58 if ((p7
->d
.data
= ASN1_OCTET_STRING_new()) == NULL
) {
59 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
63 if (!ASN1_item_pack(sk
, ASN1_ITEM_rptr(PKCS12_SAFEBAGS
), &p7
->d
.data
)) {
64 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_CANT_PACK_STRUCTURE
);
74 /* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
75 STACK_OF(PKCS12_SAFEBAG
) *PKCS12_unpack_p7data(PKCS7
*p7
)
77 if (!PKCS7_type_is_data(p7
)) {
78 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_CONTENT_TYPE_NOT_DATA
);
82 if (p7
->d
.data
== NULL
) {
83 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_DECODE_ERROR
);
87 return ASN1_item_unpack_ex(p7
->d
.data
, ASN1_ITEM_rptr(PKCS12_SAFEBAGS
),
88 ossl_pkcs7_ctx_get0_libctx(&p7
->ctx
),
89 ossl_pkcs7_ctx_get0_propq(&p7
->ctx
));
92 /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
94 PKCS7
*PKCS12_pack_p7encdata_ex(int pbe_nid
, const char *pass
, int passlen
,
95 unsigned char *salt
, int saltlen
, int iter
,
96 STACK_OF(PKCS12_SAFEBAG
) *bags
,
97 OSSL_LIB_CTX
*ctx
, const char *propq
)
101 const EVP_CIPHER
*pbe_ciph
= NULL
;
102 EVP_CIPHER
*pbe_ciph_fetch
= NULL
;
104 if ((p7
= PKCS7_new_ex(ctx
, propq
)) == NULL
) {
105 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
108 if (!PKCS7_set_type(p7
, NID_pkcs7_encrypted
)) {
109 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE
);
114 pbe_ciph
= pbe_ciph_fetch
= EVP_CIPHER_fetch(ctx
, OBJ_nid2sn(pbe_nid
), propq
);
115 if (pbe_ciph
== NULL
)
116 pbe_ciph
= EVP_get_cipherbynid(pbe_nid
);
119 if (pbe_ciph
!= NULL
) {
120 pbe
= PKCS5_pbe2_set_iv_ex(pbe_ciph
, iter
, salt
, saltlen
, NULL
, -1, ctx
);
122 pbe
= PKCS5_pbe_set_ex(pbe_nid
, iter
, salt
, saltlen
, ctx
);
126 ERR_raise(ERR_LIB_PKCS12
, ERR_R_ASN1_LIB
);
129 X509_ALGOR_free(p7
->d
.encrypted
->enc_data
->algorithm
);
130 p7
->d
.encrypted
->enc_data
->algorithm
= pbe
;
131 ASN1_OCTET_STRING_free(p7
->d
.encrypted
->enc_data
->enc_data
);
132 if (!(p7
->d
.encrypted
->enc_data
->enc_data
=
133 PKCS12_item_i2d_encrypt_ex(pbe
, ASN1_ITEM_rptr(PKCS12_SAFEBAGS
), pass
,
134 passlen
, bags
, 1, ctx
, propq
))) {
135 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_ENCRYPT_ERROR
);
139 EVP_CIPHER_free(pbe_ciph_fetch
);
144 EVP_CIPHER_free(pbe_ciph_fetch
);
148 PKCS7
*PKCS12_pack_p7encdata(int pbe_nid
, const char *pass
, int passlen
,
149 unsigned char *salt
, int saltlen
, int iter
,
150 STACK_OF(PKCS12_SAFEBAG
) *bags
)
152 return PKCS12_pack_p7encdata_ex(pbe_nid
, pass
, passlen
, salt
, saltlen
,
153 iter
, bags
, NULL
, NULL
);
156 STACK_OF(PKCS12_SAFEBAG
) *PKCS12_unpack_p7encdata(PKCS7
*p7
, const char *pass
,
159 if (!PKCS7_type_is_encrypted(p7
))
162 if (p7
->d
.encrypted
== NULL
) {
163 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_DECODE_ERROR
);
167 return PKCS12_item_decrypt_d2i_ex(p7
->d
.encrypted
->enc_data
->algorithm
,
168 ASN1_ITEM_rptr(PKCS12_SAFEBAGS
),
170 p7
->d
.encrypted
->enc_data
->enc_data
, 1,
171 p7
->ctx
.libctx
, p7
->ctx
.propq
);
174 PKCS8_PRIV_KEY_INFO
*PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG
*bag
,
175 const char *pass
, int passlen
,
176 OSSL_LIB_CTX
*ctx
, const char *propq
)
178 return PKCS8_decrypt_ex(bag
->value
.shkeybag
, pass
, passlen
, ctx
, propq
);
181 PKCS8_PRIV_KEY_INFO
*PKCS12_decrypt_skey(const PKCS12_SAFEBAG
*bag
,
182 const char *pass
, int passlen
)
184 return PKCS12_decrypt_skey_ex(bag
, pass
, passlen
, NULL
, NULL
);
187 int PKCS12_pack_authsafes(PKCS12
*p12
, STACK_OF(PKCS7
) *safes
)
189 if (ASN1_item_pack(safes
, ASN1_ITEM_rptr(PKCS12_AUTHSAFES
),
190 &p12
->authsafes
->d
.data
))
195 STACK_OF(PKCS7
) *PKCS12_unpack_authsafes(const PKCS12
*p12
)
197 STACK_OF(PKCS7
) *p7s
;
202 if (!PKCS7_type_is_data(p12
->authsafes
)) {
203 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_CONTENT_TYPE_NOT_DATA
);
207 if (p12
->authsafes
->d
.data
== NULL
) {
208 ERR_raise(ERR_LIB_PKCS12
, PKCS12_R_DECODE_ERROR
);
212 p7ctx
= &p12
->authsafes
->ctx
;
213 p7s
= ASN1_item_unpack_ex(p12
->authsafes
->d
.data
,
214 ASN1_ITEM_rptr(PKCS12_AUTHSAFES
),
215 ossl_pkcs7_ctx_get0_libctx(p7ctx
),
216 ossl_pkcs7_ctx_get0_propq(p7ctx
));
218 for (i
= 0; i
< sk_PKCS7_num(p7s
); i
++) {
219 p7
= sk_PKCS7_value(p7s
, i
);
220 if (!ossl_pkcs7_ctx_propagate(p12
->authsafes
, p7
))