xref: /openssl/crypto/pkcs12/p12_sbag.c (revision da1c088f)
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