1e71b7053SJung-uk Kim /*
2b077aed3SPierre Pronchery  * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim  */
9e71b7053SJung-uk Kim 
10e71b7053SJung-uk Kim #include <stdio.h>
11e71b7053SJung-uk Kim #include "internal/cryptlib.h"
12e71b7053SJung-uk Kim #include <openssl/pkcs12.h>
1317f01e99SJung-uk Kim #include "p12_local.h"
14e71b7053SJung-uk Kim 
15b077aed3SPierre Pronchery #ifndef OPENSSL_NO_DEPRECATED_1_1_0
PKCS12_get_attr(const PKCS12_SAFEBAG * bag,int attr_nid)16e71b7053SJung-uk Kim ASN1_TYPE *PKCS12_get_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
17e71b7053SJung-uk Kim {
18e71b7053SJung-uk Kim     return PKCS12_get_attr_gen(bag->attrib, attr_nid);
19e71b7053SJung-uk Kim }
20e71b7053SJung-uk Kim #endif
21e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG * bag,int attr_nid)22e71b7053SJung-uk Kim const ASN1_TYPE *PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag,
23e71b7053SJung-uk Kim                                           int attr_nid)
24e71b7053SJung-uk Kim {
25e71b7053SJung-uk Kim     return PKCS12_get_attr_gen(bag->attrib, attr_nid);
26e71b7053SJung-uk Kim }
27e71b7053SJung-uk Kim 
PKCS8_get_attr(PKCS8_PRIV_KEY_INFO * p8,int attr_nid)28e71b7053SJung-uk Kim ASN1_TYPE *PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
29e71b7053SJung-uk Kim {
30e71b7053SJung-uk Kim     return PKCS12_get_attr_gen(PKCS8_pkey_get0_attrs(p8), attr_nid);
31e71b7053SJung-uk Kim }
32e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG * bag)33e71b7053SJung-uk Kim const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
34e71b7053SJung-uk Kim {
35e71b7053SJung-uk Kim     if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
36e71b7053SJung-uk Kim         return NULL;
37e71b7053SJung-uk Kim     return bag->value.keybag;
38e71b7053SJung-uk Kim }
39e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG * bag)40e71b7053SJung-uk Kim const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
41e71b7053SJung-uk Kim {
42e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->type) != NID_pkcs8ShroudedKeyBag)
43e71b7053SJung-uk Kim         return NULL;
44e71b7053SJung-uk Kim     return bag->value.shkeybag;
45e71b7053SJung-uk Kim }
46e71b7053SJung-uk Kim 
STACK_OF(PKCS12_SAFEBAG)47e71b7053SJung-uk Kim const STACK_OF(PKCS12_SAFEBAG) *
48e71b7053SJung-uk Kim PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
49e71b7053SJung-uk Kim {
50e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->type) != NID_safeContentsBag)
51e71b7053SJung-uk Kim         return NULL;
52e71b7053SJung-uk Kim     return bag->value.safes;
53e71b7053SJung-uk Kim }
54e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG * bag)55e71b7053SJung-uk Kim const ASN1_OBJECT *PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
56e71b7053SJung-uk Kim {
57e71b7053SJung-uk Kim     return bag->type;
58e71b7053SJung-uk Kim }
59e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG * bag)60e71b7053SJung-uk Kim int PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
61e71b7053SJung-uk Kim {
62e71b7053SJung-uk Kim     return OBJ_obj2nid(bag->type);
63e71b7053SJung-uk Kim }
64e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG * bag)65e71b7053SJung-uk Kim int PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
66e71b7053SJung-uk Kim {
67e71b7053SJung-uk Kim     int btype = PKCS12_SAFEBAG_get_nid(bag);
68e71b7053SJung-uk Kim 
69e71b7053SJung-uk Kim     if (btype != NID_certBag && btype != NID_crlBag && btype != NID_secretBag)
70e71b7053SJung-uk Kim         return -1;
71e71b7053SJung-uk Kim     return OBJ_obj2nid(bag->value.bag->type);
72e71b7053SJung-uk Kim }
73e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG * bag)74b077aed3SPierre Pronchery const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag)
75b077aed3SPierre Pronchery {
76b077aed3SPierre Pronchery     return bag->value.bag->type;
77b077aed3SPierre Pronchery }
78b077aed3SPierre Pronchery 
PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG * bag)79b077aed3SPierre Pronchery const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag)
80b077aed3SPierre Pronchery {
81b077aed3SPierre Pronchery     return bag->value.bag->value.other;
82b077aed3SPierre Pronchery }
83b077aed3SPierre Pronchery 
PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG * bag)84e71b7053SJung-uk Kim X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
85e71b7053SJung-uk Kim {
86e71b7053SJung-uk Kim     if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
87e71b7053SJung-uk Kim         return NULL;
88e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
89e71b7053SJung-uk Kim         return NULL;
90e71b7053SJung-uk Kim     return ASN1_item_unpack(bag->value.bag->value.octet,
91e71b7053SJung-uk Kim                             ASN1_ITEM_rptr(X509));
92e71b7053SJung-uk Kim }
93e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG * bag)94e71b7053SJung-uk Kim X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
95e71b7053SJung-uk Kim {
96e71b7053SJung-uk Kim     if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
97e71b7053SJung-uk Kim         return NULL;
98e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
99e71b7053SJung-uk Kim         return NULL;
100e71b7053SJung-uk Kim     return ASN1_item_unpack(bag->value.bag->value.octet,
101e71b7053SJung-uk Kim                             ASN1_ITEM_rptr(X509_CRL));
102e71b7053SJung-uk Kim }
103e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_create_cert(X509 * x509)104e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
105e71b7053SJung-uk Kim {
106e71b7053SJung-uk Kim     return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
107e71b7053SJung-uk Kim                                     NID_x509Certificate, NID_certBag);
108e71b7053SJung-uk Kim }
109e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_create_crl(X509_CRL * crl)110e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
111e71b7053SJung-uk Kim {
112e71b7053SJung-uk Kim     return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
113e71b7053SJung-uk Kim                                     NID_x509Crl, NID_crlBag);
114e71b7053SJung-uk Kim }
115e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_create_secret(int type,int vtype,const unsigned char * value,int len)116b077aed3SPierre Pronchery PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len)
117b077aed3SPierre Pronchery {
118b077aed3SPierre Pronchery     PKCS12_BAGS *bag;
119b077aed3SPierre Pronchery     PKCS12_SAFEBAG *safebag;
120b077aed3SPierre Pronchery 
121b077aed3SPierre Pronchery     if ((bag = PKCS12_BAGS_new()) == NULL) {
122b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
123b077aed3SPierre Pronchery         return NULL;
124b077aed3SPierre Pronchery     }
125b077aed3SPierre Pronchery     bag->type = OBJ_nid2obj(type);
126b077aed3SPierre Pronchery 
127b077aed3SPierre Pronchery     switch(vtype) {
128b077aed3SPierre Pronchery     case V_ASN1_OCTET_STRING:
129b077aed3SPierre Pronchery         {
130b077aed3SPierre Pronchery             ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new();
131b077aed3SPierre Pronchery 
132b077aed3SPierre Pronchery             if (strtmp == NULL) {
133b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
134b077aed3SPierre Pronchery                 goto err;
135b077aed3SPierre Pronchery             }
136b077aed3SPierre Pronchery             /* Pack data into an octet string */
137b077aed3SPierre Pronchery             if (!ASN1_OCTET_STRING_set(strtmp, value, len)) {
138b077aed3SPierre Pronchery                 ASN1_OCTET_STRING_free(strtmp);
139b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR);
140b077aed3SPierre Pronchery                 goto err;
141b077aed3SPierre Pronchery             }
142b077aed3SPierre Pronchery             bag->value.other = ASN1_TYPE_new();
143b077aed3SPierre Pronchery             if (bag->value.other == NULL) {
144b077aed3SPierre Pronchery                 ASN1_OCTET_STRING_free(strtmp);
145b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
146b077aed3SPierre Pronchery                 goto err;
147b077aed3SPierre Pronchery             }
148b077aed3SPierre Pronchery             ASN1_TYPE_set(bag->value.other, vtype, strtmp);
149b077aed3SPierre Pronchery         }
150b077aed3SPierre Pronchery         break;
151b077aed3SPierre Pronchery 
152b077aed3SPierre Pronchery     default:
153b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE);
154b077aed3SPierre Pronchery         goto err;
155b077aed3SPierre Pronchery     }
156b077aed3SPierre Pronchery 
157b077aed3SPierre Pronchery     if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
158b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
159b077aed3SPierre Pronchery         goto err;
160b077aed3SPierre Pronchery     }
161b077aed3SPierre Pronchery     safebag->value.bag = bag;
162b077aed3SPierre Pronchery     safebag->type = OBJ_nid2obj(NID_secretBag);
163b077aed3SPierre Pronchery     return safebag;
164b077aed3SPierre Pronchery 
165b077aed3SPierre Pronchery  err:
166b077aed3SPierre Pronchery     PKCS12_BAGS_free(bag);
167b077aed3SPierre Pronchery     return NULL;
168b077aed3SPierre Pronchery }
169b077aed3SPierre Pronchery 
170e71b7053SJung-uk Kim /* Turn PKCS8 object into a keybag */
171e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO * p8)172e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
173e71b7053SJung-uk Kim {
174e71b7053SJung-uk Kim     PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
175e71b7053SJung-uk Kim 
176e71b7053SJung-uk Kim     if (bag == NULL) {
177b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
178e71b7053SJung-uk Kim         return NULL;
179e71b7053SJung-uk Kim     }
180e71b7053SJung-uk Kim     bag->type = OBJ_nid2obj(NID_keyBag);
181e71b7053SJung-uk Kim     bag->value.keybag = p8;
182e71b7053SJung-uk Kim     return bag;
183e71b7053SJung-uk Kim }
184e71b7053SJung-uk Kim 
185e71b7053SJung-uk Kim /* Turn PKCS8 object into a shrouded keybag */
186e71b7053SJung-uk Kim 
PKCS12_SAFEBAG_create0_pkcs8(X509_SIG * p8)187e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
188e71b7053SJung-uk Kim {
189e71b7053SJung-uk Kim     PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
190e71b7053SJung-uk Kim 
191e71b7053SJung-uk Kim     /* Set up the safe bag */
192e71b7053SJung-uk Kim     if (bag == NULL) {
193b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
194e71b7053SJung-uk Kim         return NULL;
195e71b7053SJung-uk Kim     }
196e71b7053SJung-uk Kim     bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
197e71b7053SJung-uk Kim     bag->value.shkeybag = p8;
198e71b7053SJung-uk Kim     return bag;
199e71b7053SJung-uk Kim }
200e71b7053SJung-uk Kim 
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)201b077aed3SPierre Pronchery PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
202b077aed3SPierre Pronchery                                                        const char *pass,
203b077aed3SPierre Pronchery                                                        int passlen,
204b077aed3SPierre Pronchery                                                        unsigned char *salt,
205b077aed3SPierre Pronchery                                                        int saltlen, int iter,
206b077aed3SPierre Pronchery                                                        PKCS8_PRIV_KEY_INFO *p8inf,
207b077aed3SPierre Pronchery                                                        OSSL_LIB_CTX *ctx,
208b077aed3SPierre Pronchery                                                        const char *propq)
209b077aed3SPierre Pronchery {
210b077aed3SPierre Pronchery     PKCS12_SAFEBAG *bag = NULL;
211b077aed3SPierre Pronchery     const EVP_CIPHER *pbe_ciph = NULL;
212b077aed3SPierre Pronchery     EVP_CIPHER *pbe_ciph_fetch = NULL;
213b077aed3SPierre Pronchery     X509_SIG *p8;
214b077aed3SPierre Pronchery 
215b077aed3SPierre Pronchery     ERR_set_mark();
216b077aed3SPierre Pronchery     pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
217b077aed3SPierre Pronchery     if (pbe_ciph == NULL)
218b077aed3SPierre Pronchery         pbe_ciph = EVP_get_cipherbynid(pbe_nid);
219b077aed3SPierre Pronchery     ERR_pop_to_mark();
220b077aed3SPierre Pronchery 
221b077aed3SPierre Pronchery     if (pbe_ciph != NULL)
222b077aed3SPierre Pronchery         pbe_nid = -1;
223b077aed3SPierre Pronchery 
224b077aed3SPierre Pronchery     p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
225b077aed3SPierre Pronchery                           p8inf, ctx, propq);
226b077aed3SPierre Pronchery     if (p8 == NULL)
227b077aed3SPierre Pronchery         goto err;
228b077aed3SPierre Pronchery 
229b077aed3SPierre Pronchery     bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
230b077aed3SPierre Pronchery     if (bag == NULL)
231b077aed3SPierre Pronchery         X509_SIG_free(p8);
232b077aed3SPierre Pronchery 
233b077aed3SPierre Pronchery err:
234b077aed3SPierre Pronchery     EVP_CIPHER_free(pbe_ciph_fetch);
235b077aed3SPierre Pronchery     return bag;
236b077aed3SPierre Pronchery }
237b077aed3SPierre Pronchery 
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)238e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
239e71b7053SJung-uk Kim                                                     const char *pass,
240e71b7053SJung-uk Kim                                                     int passlen,
241e71b7053SJung-uk Kim                                                     unsigned char *salt,
242e71b7053SJung-uk Kim                                                     int saltlen, int iter,
243e71b7053SJung-uk Kim                                                     PKCS8_PRIV_KEY_INFO *p8inf)
244e71b7053SJung-uk Kim {
245b077aed3SPierre Pronchery     return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen,
246b077aed3SPierre Pronchery                                                   salt, saltlen, iter, p8inf,
247b077aed3SPierre Pronchery                                                   NULL, NULL);
248e71b7053SJung-uk Kim }
249