xref: /freebsd-src/crypto/openssl/crypto/pkcs12/p12_sbag.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim  *
4*b077aed3SPierre 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 
15*b077aed3SPierre 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)74*b077aed3SPierre Pronchery const ASN1_OBJECT *PKCS12_SAFEBAG_get0_bag_type(const PKCS12_SAFEBAG *bag)
75*b077aed3SPierre Pronchery {
76*b077aed3SPierre Pronchery     return bag->value.bag->type;
77*b077aed3SPierre Pronchery }
78*b077aed3SPierre Pronchery 
PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG * bag)79*b077aed3SPierre Pronchery const ASN1_TYPE *PKCS12_SAFEBAG_get0_bag_obj(const PKCS12_SAFEBAG *bag)
80*b077aed3SPierre Pronchery {
81*b077aed3SPierre Pronchery     return bag->value.bag->value.other;
82*b077aed3SPierre Pronchery }
83*b077aed3SPierre 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)116*b077aed3SPierre Pronchery PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_secret(int type, int vtype, const unsigned char *value, int len)
117*b077aed3SPierre Pronchery {
118*b077aed3SPierre Pronchery     PKCS12_BAGS *bag;
119*b077aed3SPierre Pronchery     PKCS12_SAFEBAG *safebag;
120*b077aed3SPierre Pronchery 
121*b077aed3SPierre Pronchery     if ((bag = PKCS12_BAGS_new()) == NULL) {
122*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
123*b077aed3SPierre Pronchery         return NULL;
124*b077aed3SPierre Pronchery     }
125*b077aed3SPierre Pronchery     bag->type = OBJ_nid2obj(type);
126*b077aed3SPierre Pronchery 
127*b077aed3SPierre Pronchery     switch(vtype) {
128*b077aed3SPierre Pronchery     case V_ASN1_OCTET_STRING:
129*b077aed3SPierre Pronchery         {
130*b077aed3SPierre Pronchery             ASN1_OCTET_STRING *strtmp = ASN1_OCTET_STRING_new();
131*b077aed3SPierre Pronchery 
132*b077aed3SPierre Pronchery             if (strtmp == NULL) {
133*b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
134*b077aed3SPierre Pronchery                 goto err;
135*b077aed3SPierre Pronchery             }
136*b077aed3SPierre Pronchery             /* Pack data into an octet string */
137*b077aed3SPierre Pronchery             if (!ASN1_OCTET_STRING_set(strtmp, value, len)) {
138*b077aed3SPierre Pronchery                 ASN1_OCTET_STRING_free(strtmp);
139*b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, PKCS12_R_ENCODE_ERROR);
140*b077aed3SPierre Pronchery                 goto err;
141*b077aed3SPierre Pronchery             }
142*b077aed3SPierre Pronchery             bag->value.other = ASN1_TYPE_new();
143*b077aed3SPierre Pronchery             if (bag->value.other == NULL) {
144*b077aed3SPierre Pronchery                 ASN1_OCTET_STRING_free(strtmp);
145*b077aed3SPierre Pronchery                 ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
146*b077aed3SPierre Pronchery                 goto err;
147*b077aed3SPierre Pronchery             }
148*b077aed3SPierre Pronchery             ASN1_TYPE_set(bag->value.other, vtype, strtmp);
149*b077aed3SPierre Pronchery         }
150*b077aed3SPierre Pronchery         break;
151*b077aed3SPierre Pronchery 
152*b077aed3SPierre Pronchery     default:
153*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_TYPE);
154*b077aed3SPierre Pronchery         goto err;
155*b077aed3SPierre Pronchery     }
156*b077aed3SPierre Pronchery 
157*b077aed3SPierre Pronchery     if ((safebag = PKCS12_SAFEBAG_new()) == NULL) {
158*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_PKCS12, ERR_R_MALLOC_FAILURE);
159*b077aed3SPierre Pronchery         goto err;
160*b077aed3SPierre Pronchery     }
161*b077aed3SPierre Pronchery     safebag->value.bag = bag;
162*b077aed3SPierre Pronchery     safebag->type = OBJ_nid2obj(NID_secretBag);
163*b077aed3SPierre Pronchery     return safebag;
164*b077aed3SPierre Pronchery 
165*b077aed3SPierre Pronchery  err:
166*b077aed3SPierre Pronchery     PKCS12_BAGS_free(bag);
167*b077aed3SPierre Pronchery     return NULL;
168*b077aed3SPierre Pronchery }
169*b077aed3SPierre 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) {
177*b077aed3SPierre 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) {
193*b077aed3SPierre 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)201*b077aed3SPierre Pronchery PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(int pbe_nid,
202*b077aed3SPierre Pronchery                                                        const char *pass,
203*b077aed3SPierre Pronchery                                                        int passlen,
204*b077aed3SPierre Pronchery                                                        unsigned char *salt,
205*b077aed3SPierre Pronchery                                                        int saltlen, int iter,
206*b077aed3SPierre Pronchery                                                        PKCS8_PRIV_KEY_INFO *p8inf,
207*b077aed3SPierre Pronchery                                                        OSSL_LIB_CTX *ctx,
208*b077aed3SPierre Pronchery                                                        const char *propq)
209*b077aed3SPierre Pronchery {
210*b077aed3SPierre Pronchery     PKCS12_SAFEBAG *bag = NULL;
211*b077aed3SPierre Pronchery     const EVP_CIPHER *pbe_ciph = NULL;
212*b077aed3SPierre Pronchery     EVP_CIPHER *pbe_ciph_fetch = NULL;
213*b077aed3SPierre Pronchery     X509_SIG *p8;
214*b077aed3SPierre Pronchery 
215*b077aed3SPierre Pronchery     ERR_set_mark();
216*b077aed3SPierre Pronchery     pbe_ciph = pbe_ciph_fetch = EVP_CIPHER_fetch(ctx, OBJ_nid2sn(pbe_nid), propq);
217*b077aed3SPierre Pronchery     if (pbe_ciph == NULL)
218*b077aed3SPierre Pronchery         pbe_ciph = EVP_get_cipherbynid(pbe_nid);
219*b077aed3SPierre Pronchery     ERR_pop_to_mark();
220*b077aed3SPierre Pronchery 
221*b077aed3SPierre Pronchery     if (pbe_ciph != NULL)
222*b077aed3SPierre Pronchery         pbe_nid = -1;
223*b077aed3SPierre Pronchery 
224*b077aed3SPierre Pronchery     p8 = PKCS8_encrypt_ex(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
225*b077aed3SPierre Pronchery                           p8inf, ctx, propq);
226*b077aed3SPierre Pronchery     if (p8 == NULL)
227*b077aed3SPierre Pronchery         goto err;
228*b077aed3SPierre Pronchery 
229*b077aed3SPierre Pronchery     bag = PKCS12_SAFEBAG_create0_pkcs8(p8);
230*b077aed3SPierre Pronchery     if (bag == NULL)
231*b077aed3SPierre Pronchery         X509_SIG_free(p8);
232*b077aed3SPierre Pronchery 
233*b077aed3SPierre Pronchery err:
234*b077aed3SPierre Pronchery     EVP_CIPHER_free(pbe_ciph_fetch);
235*b077aed3SPierre Pronchery     return bag;
236*b077aed3SPierre Pronchery }
237*b077aed3SPierre 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 {
245*b077aed3SPierre Pronchery     return PKCS12_SAFEBAG_create_pkcs8_encrypt_ex(pbe_nid, pass, passlen,
246*b077aed3SPierre Pronchery                                                   salt, saltlen, iter, p8inf,
247*b077aed3SPierre Pronchery                                                   NULL, NULL);
248e71b7053SJung-uk Kim }
249