1e71b7053SJung-uk Kim /*
2e71b7053SJung-uk Kim  * Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (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 
15e71b7053SJung-uk Kim #if OPENSSL_API_COMPAT < 0x10100000L
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 
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 
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 
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 
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 
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 
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 
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 
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 
74e71b7053SJung-uk Kim X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
75e71b7053SJung-uk Kim {
76e71b7053SJung-uk Kim     if (PKCS12_SAFEBAG_get_nid(bag) != NID_certBag)
77e71b7053SJung-uk Kim         return NULL;
78e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
79e71b7053SJung-uk Kim         return NULL;
80e71b7053SJung-uk Kim     return ASN1_item_unpack(bag->value.bag->value.octet,
81e71b7053SJung-uk Kim                             ASN1_ITEM_rptr(X509));
82e71b7053SJung-uk Kim }
83e71b7053SJung-uk Kim 
84e71b7053SJung-uk Kim X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
85e71b7053SJung-uk Kim {
86e71b7053SJung-uk Kim     if (PKCS12_SAFEBAG_get_nid(bag) != NID_crlBag)
87e71b7053SJung-uk Kim         return NULL;
88e71b7053SJung-uk Kim     if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
89e71b7053SJung-uk Kim         return NULL;
90e71b7053SJung-uk Kim     return ASN1_item_unpack(bag->value.bag->value.octet,
91e71b7053SJung-uk Kim                             ASN1_ITEM_rptr(X509_CRL));
92e71b7053SJung-uk Kim }
93e71b7053SJung-uk Kim 
94e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509)
95e71b7053SJung-uk Kim {
96e71b7053SJung-uk Kim     return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
97e71b7053SJung-uk Kim                                     NID_x509Certificate, NID_certBag);
98e71b7053SJung-uk Kim }
99e71b7053SJung-uk Kim 
100e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
101e71b7053SJung-uk Kim {
102e71b7053SJung-uk Kim     return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
103e71b7053SJung-uk Kim                                     NID_x509Crl, NID_crlBag);
104e71b7053SJung-uk Kim }
105e71b7053SJung-uk Kim 
106e71b7053SJung-uk Kim /* Turn PKCS8 object into a keybag */
107e71b7053SJung-uk Kim 
108e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
109e71b7053SJung-uk Kim {
110e71b7053SJung-uk Kim     PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
111e71b7053SJung-uk Kim 
112e71b7053SJung-uk Kim     if (bag == NULL) {
113e71b7053SJung-uk Kim         PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_P8INF, ERR_R_MALLOC_FAILURE);
114e71b7053SJung-uk Kim         return NULL;
115e71b7053SJung-uk Kim     }
116e71b7053SJung-uk Kim     bag->type = OBJ_nid2obj(NID_keyBag);
117e71b7053SJung-uk Kim     bag->value.keybag = p8;
118e71b7053SJung-uk Kim     return bag;
119e71b7053SJung-uk Kim }
120e71b7053SJung-uk Kim 
121e71b7053SJung-uk Kim /* Turn PKCS8 object into a shrouded keybag */
122e71b7053SJung-uk Kim 
123e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
124e71b7053SJung-uk Kim {
125e71b7053SJung-uk Kim     PKCS12_SAFEBAG *bag = PKCS12_SAFEBAG_new();
126e71b7053SJung-uk Kim 
127e71b7053SJung-uk Kim     /* Set up the safe bag */
128e71b7053SJung-uk Kim     if (bag == NULL) {
129e71b7053SJung-uk Kim         PKCS12err(PKCS12_F_PKCS12_SAFEBAG_CREATE0_PKCS8, ERR_R_MALLOC_FAILURE);
130e71b7053SJung-uk Kim         return NULL;
131e71b7053SJung-uk Kim     }
132e71b7053SJung-uk Kim     bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
133e71b7053SJung-uk Kim     bag->value.shkeybag = p8;
134e71b7053SJung-uk Kim     return bag;
135e71b7053SJung-uk Kim }
136e71b7053SJung-uk Kim 
137e71b7053SJung-uk Kim PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,
138e71b7053SJung-uk Kim                                                     const char *pass,
139e71b7053SJung-uk Kim                                                     int passlen,
140e71b7053SJung-uk Kim                                                     unsigned char *salt,
141e71b7053SJung-uk Kim                                                     int saltlen, int iter,
142e71b7053SJung-uk Kim                                                     PKCS8_PRIV_KEY_INFO *p8inf)
143e71b7053SJung-uk Kim {
144e71b7053SJung-uk Kim     PKCS12_SAFEBAG *bag;
145e71b7053SJung-uk Kim     const EVP_CIPHER *pbe_ciph;
146e71b7053SJung-uk Kim     X509_SIG *p8;
147e71b7053SJung-uk Kim 
148e71b7053SJung-uk Kim     pbe_ciph = EVP_get_cipherbynid(pbe_nid);
149e71b7053SJung-uk Kim     if (pbe_ciph)
150e71b7053SJung-uk Kim         pbe_nid = -1;
151e71b7053SJung-uk Kim 
152e71b7053SJung-uk Kim     p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
153e71b7053SJung-uk Kim                        p8inf);
154e71b7053SJung-uk Kim     if (p8 == NULL)
155e71b7053SJung-uk Kim         return NULL;
156e71b7053SJung-uk Kim 
157e71b7053SJung-uk Kim     bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
158e71b7053SJung-uk Kim     if (bag == NULL)
159e71b7053SJung-uk Kim         X509_SIG_free(p8);
160e71b7053SJung-uk Kim 
161e71b7053SJung-uk Kim     return bag;
162e71b7053SJung-uk Kim }
163