1 /*
2 * Copyright 1999-2023 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 #include "p12_local.h"
14 #include "crypto/x509.h"
15
16 #ifndef OPENSSL_NO_DEPRECATED_1_1_0
PKCS12_get_attr(const PKCS12_SAFEBAG * bag,int attr_nid)17 ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
18 {
19 return PKCS12_get_attr_gen(bag->attrib, attr_nid);
20 }
21 #endif
22
PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG * bag,int attr_nid)23 const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
24 int attr_nid)
25 {
26 return PKCS12_get_attr_gen(bag->attrib, attr_nid);
27 }
28
PKCS8_get_attr(PKCS8_PRIV_KEY_INFO * p8,int attr_nid)29 ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
30 {
31 return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid);
32 }
33
PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG * bag)34 const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
35 {
36 if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
37 return NULL;
38 return bag->value.keybag;
39 }
40
PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG * bag)41 const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
42 {
43 if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
44 return NULL;
45 return bag->value.shkeybag;
46 }
47
STACK_OF(PKCS12_SAFEBAG)48 const STACK_OF(PKCS12_SAFEBAG) *
49 PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
50 {
51 if (OBJ_obj2nid(bag->type) != NID_safeContentsBag)
52 return NULL;
53 return bag->value.safes;
54 }
55
PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG * bag)56 const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
57 {
58 return bag->type;
59 }
60
PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG * bag)61 int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
62 {
63 return OBJ_obj2nid(bag->type);
64 }
65
PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG * bag)66 int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
67 {
68 int btype = PKCS12_SAFEBAG_get_nid(bag);
69
70 if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
71 return -1;
72 return OBJ_obj2nid(bag->value.bag->type);
73 }
74
PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG * bag)75 const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag)
76 {
77 return bag->value.bag->type;
78 }
79
PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG * bag)80 const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag)
81 {
82 return bag->value.bag->value.other;
83 }
84
PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG * bag)85 X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
86 {
87 if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
88 return NULL;
89 if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
90 return NULL;
91 return ASN1_item_unpack(bag->value.bag->value.octet,
92 ASN1_ITEM_rptr(X509));
93 }
94
PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG * bag)95 X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
96 {
97 if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
98 return NULL;
99 if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
100 return NULL;
101 return ASN1_item_unpack(bag->value.bag->value.octet,
102 ASN1_ITEM_rptr(X509_CRL));
103 }
104
PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG * bag,OSSL_LIB_CTX * libctx,const char * propq)105 X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag,
106 OSSL_LIB_CTX *libctx, const char *propq)
107 {
108 X509 *ret = NULL;
109
110 if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
111 return NULL;
112 if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
113 return NULL;
114 ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
115 ASN1_ITEM_rptr(X509), libctx, propq);
116 if (!ossl_x509_set0_libctx(ret, libctx, propq)) {
117 X509_free(ret);
118 return NULL;
119 }
120 return ret;
121 }
122
PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG * bag,OSSL_LIB_CTX * libctx,const char * propq)123 X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag,
124 OSSL_LIB_CTX *libctx, const char *propq)
125 {
126 X509_CRL *ret = NULL;
127
128 if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
129 return NULL;
130 if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
131 return NULL;
132 ret = ASN1_item_unpack_ex(bag->value.bag->value.octet,
133 ASN1_ITEM_rptr(X509_CRL), libctx, propq);
134 if (!ossl_x509_crl_set0_libctx(ret, libctx, propq)) {
135 X509_CRL_free(ret);
136 return NULL;
137 }
138 return ret;
139 }
140
PKCS12_SAFEBAG_create_cert(X509 * x509)141 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
142 {
143 return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
144 NID_x509Certificate, NID_certBag);
145 }
146
PKCS12_SAFEBAG_create_crl(X509_CRL * crl)147 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
148 {
149 return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
150 NID_x509Crl, NID_crlBag);
151 }
152
PKCS12_SAFEBAG_create_secret(int type,int vtype,const unsigned char * value,int len)153 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len)
154 {
155 PKCS12_BAGS *bag;
156 PKCS12_SAFEBAG *safebag;
157
158 if ((bag = PKCS12_BAGS_new()) == NULL) {
159 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
160 return NULL;
161 }
162 bag->type = OBJ_nid2obj(type);
163
164 switch (vtype) {
165 case V_ASN1_OCTET_STRING:
166 {
167 ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new();
168
169 if (strtmp == NULL) {
170 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
171 goto err;
172 }
173 /* Pack data into an octet string */
174 if (!ASN1_OCTET_STRING_set(strtmp, value, len)) {
175 ASN1_OCTET_STRING_free(strtmp);
176 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR);
177 goto err;
178 }
179 bag->value.other = ASN1_TYPE_new();
180 if (bag->value.other == NULL) {
181 ASN1_OCTET_STRING_free(strtmp);
182 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
183 goto err;
184 }
185 ASN1_TYPE_set(bag->value.other, vtype, strtmp);
186 }
187 break;
188
189 default:
190 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE);
191 goto err;
192 }
193
194 if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
195 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
196 goto err;
197 }
198 safebag->value.bag = bag;
199 safebag->type = OBJ_nid2obj(NID_secretBag);
200 return safebag;
201
202 err:
203 PKCS12_BAGS_free(bag);
204 return NULL;
205 }
206
207 /* Turn PKCS8 object into a keybag */
208
PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO * p8)209 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
210 {
211 PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
212
213 if (bag == NULL) {
214 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
215 return NULL;
216 }
217 bag->type = OBJ_nid2obj(NID_keyBag);
218 bag->value.keybag = p8;
219 return bag;
220 }
221
222 /* Turn PKCS8 object into a shrouded keybag */
223
PKCS12_SAFEBAG_create0_pkcs8(X509_SIG * p8)224 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
225 {
226 PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
227
228 /* Set up the safe bag */
229 if (bag == NULL) {
230 ERR_raise(ERR_LIB_PKCS12, ERR_R_ASN1_LIB);
231 return NULL;
232 }
233 bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
234 bag->value.shkeybag = p8;
235 return bag;
236 }
237
PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,PKCS8_PRIV_KEY_INFO * p8inf,OSSL_LIB_CTX * ctx,const char * propq)238 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
239 const char *pass,
240 int passlen,
241 unsigned char *salt,
242 int saltlen, int iter,
243 PKCS8_PRIV_KEY_INFO *p8inf,
244 OSSL_LIB_CTX *ctx,
245 const char *propq)
246 {
247 PKCS12_SAFEBAG *bag = NULL;
248 const EVP_CIPHER *pbe_ciph = NULL;
249 EVP_CIPHER *pbe_ciph_fetch = NULL;
250 X509_SIG *p8;
251
252 ERR_set_mark();
253 pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
254 if (pbe_ciph == NULL)
255 pbe_ciph = EVP_get_cipherbynid(pbe_nid);
256 ERR_pop_to_mark();
257
258 if (pbe_ciph != NULL)
259 pbe_nid = -1;
260
261 p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
262 p8inf, ctx, propq);
263 if (p8 == NULL)
264 goto err;
265
266 bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
267 if (bag == NULL)
268 X509_SIG_free(p8);
269
270 err:
271 EVP_CIPHER_free(pbe_ciph_fetch);
272 return bag;
273 }
274
PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,PKCS8_PRIV_KEY_INFO * p8inf)275 PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
276 const char *pass,
277 int passlen,
278 unsigned char *salt,
279 int saltlen, int iter,
280 PKCS8_PRIV_KEY_INFO *p8inf)
281 {
282 return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen,
283 salt, saltlen, iter, p8inf,
284 NULL, NULL);
285 }
286