1*de0e0e4dSAntonio Huete Jimenez /* $OpenBSD: p12_sbag.c,v 1.5 2022/08/20 09:16:18 tb Exp $ */
2*de0e0e4dSAntonio Huete Jimenez /*
3*de0e0e4dSAntonio Huete Jimenez * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4*de0e0e4dSAntonio Huete Jimenez * 1999-2018.
5*de0e0e4dSAntonio Huete Jimenez */
6*de0e0e4dSAntonio Huete Jimenez /* ====================================================================
7*de0e0e4dSAntonio Huete Jimenez * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8*de0e0e4dSAntonio Huete Jimenez *
9*de0e0e4dSAntonio Huete Jimenez * Redistribution and use in source and binary forms, with or without
10*de0e0e4dSAntonio Huete Jimenez * modification, are permitted provided that the following conditions
11*de0e0e4dSAntonio Huete Jimenez * are met:
12*de0e0e4dSAntonio Huete Jimenez *
13*de0e0e4dSAntonio Huete Jimenez * 1. Redistributions of source code must retain the above copyright
14*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer.
15*de0e0e4dSAntonio Huete Jimenez *
16*de0e0e4dSAntonio Huete Jimenez * 2. Redistributions in binary form must reproduce the above copyright
17*de0e0e4dSAntonio Huete Jimenez * notice, this list of conditions and the following disclaimer in
18*de0e0e4dSAntonio Huete Jimenez * the documentation and/or other materials provided with the
19*de0e0e4dSAntonio Huete Jimenez * distribution.
20*de0e0e4dSAntonio Huete Jimenez *
21*de0e0e4dSAntonio Huete Jimenez * 3. All advertising materials mentioning features or use of this
22*de0e0e4dSAntonio Huete Jimenez * software must display the following acknowledgment:
23*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project
24*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25*de0e0e4dSAntonio Huete Jimenez *
26*de0e0e4dSAntonio Huete Jimenez * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27*de0e0e4dSAntonio Huete Jimenez * endorse or promote products derived from this software without
28*de0e0e4dSAntonio Huete Jimenez * prior written permission. For written permission, please contact
29*de0e0e4dSAntonio Huete Jimenez * licensing@OpenSSL.org.
30*de0e0e4dSAntonio Huete Jimenez *
31*de0e0e4dSAntonio Huete Jimenez * 5. Products derived from this software may not be called "OpenSSL"
32*de0e0e4dSAntonio Huete Jimenez * nor may "OpenSSL" appear in their names without prior written
33*de0e0e4dSAntonio Huete Jimenez * permission of the OpenSSL Project.
34*de0e0e4dSAntonio Huete Jimenez *
35*de0e0e4dSAntonio Huete Jimenez * 6. Redistributions of any form whatsoever must retain the following
36*de0e0e4dSAntonio Huete Jimenez * acknowledgment:
37*de0e0e4dSAntonio Huete Jimenez * "This product includes software developed by the OpenSSL Project
38*de0e0e4dSAntonio Huete Jimenez * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39*de0e0e4dSAntonio Huete Jimenez *
40*de0e0e4dSAntonio Huete Jimenez * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41*de0e0e4dSAntonio Huete Jimenez * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42*de0e0e4dSAntonio Huete Jimenez * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43*de0e0e4dSAntonio Huete Jimenez * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44*de0e0e4dSAntonio Huete Jimenez * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45*de0e0e4dSAntonio Huete Jimenez * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46*de0e0e4dSAntonio Huete Jimenez * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47*de0e0e4dSAntonio Huete Jimenez * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48*de0e0e4dSAntonio Huete Jimenez * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49*de0e0e4dSAntonio Huete Jimenez * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50*de0e0e4dSAntonio Huete Jimenez * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51*de0e0e4dSAntonio Huete Jimenez * OF THE POSSIBILITY OF SUCH DAMAGE.
52*de0e0e4dSAntonio Huete Jimenez * ====================================================================
53*de0e0e4dSAntonio Huete Jimenez *
54*de0e0e4dSAntonio Huete Jimenez * This product includes cryptographic software written by Eric Young
55*de0e0e4dSAntonio Huete Jimenez * (eay@cryptsoft.com). This product includes software written by Tim
56*de0e0e4dSAntonio Huete Jimenez * Hudson (tjh@cryptsoft.com).
57*de0e0e4dSAntonio Huete Jimenez *
58*de0e0e4dSAntonio Huete Jimenez */
59*de0e0e4dSAntonio Huete Jimenez
60*de0e0e4dSAntonio Huete Jimenez #include <stdio.h>
61*de0e0e4dSAntonio Huete Jimenez
62*de0e0e4dSAntonio Huete Jimenez #include <openssl/err.h>
63*de0e0e4dSAntonio Huete Jimenez #include <openssl/pkcs12.h>
64*de0e0e4dSAntonio Huete Jimenez
65*de0e0e4dSAntonio Huete Jimenez #include "pkcs12_local.h"
66*de0e0e4dSAntonio Huete Jimenez #include "x509_lcl.h"
67*de0e0e4dSAntonio Huete Jimenez
68*de0e0e4dSAntonio Huete Jimenez const ASN1_TYPE *
PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG * bag,int attr_nid)69*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get0_attr(const PKCS12_SAFEBAG *bag, int attr_nid)
70*de0e0e4dSAntonio Huete Jimenez {
71*de0e0e4dSAntonio Huete Jimenez return PKCS12_get_attr_gen(bag->attrib, attr_nid);
72*de0e0e4dSAntonio Huete Jimenez }
73*de0e0e4dSAntonio Huete Jimenez
74*de0e0e4dSAntonio Huete Jimenez ASN1_TYPE *
PKCS8_get_attr(PKCS8_PRIV_KEY_INFO * p8,int attr_nid)75*de0e0e4dSAntonio Huete Jimenez PKCS8_get_attr(PKCS8_PRIV_KEY_INFO *p8, int attr_nid)
76*de0e0e4dSAntonio Huete Jimenez {
77*de0e0e4dSAntonio Huete Jimenez return PKCS12_get_attr_gen(p8->attributes, attr_nid);
78*de0e0e4dSAntonio Huete Jimenez }
79*de0e0e4dSAntonio Huete Jimenez
80*de0e0e4dSAntonio Huete Jimenez const PKCS8_PRIV_KEY_INFO *
PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG * bag)81*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag)
82*de0e0e4dSAntonio Huete Jimenez {
83*de0e0e4dSAntonio Huete Jimenez if (PKCS12_SAFEBAG_get_nid(bag) != NID_keyBag)
84*de0e0e4dSAntonio Huete Jimenez return NULL;
85*de0e0e4dSAntonio Huete Jimenez
86*de0e0e4dSAntonio Huete Jimenez return bag->value.keybag;
87*de0e0e4dSAntonio Huete Jimenez }
88*de0e0e4dSAntonio Huete Jimenez
89*de0e0e4dSAntonio Huete Jimenez const X509_SIG *
PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG * bag)90*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag)
91*de0e0e4dSAntonio Huete Jimenez {
92*de0e0e4dSAntonio Huete Jimenez if (PKCS12_SAFEBAG_get_nid(bag) != NID_pkcs8ShroudedKeyBag)
93*de0e0e4dSAntonio Huete Jimenez return NULL;
94*de0e0e4dSAntonio Huete Jimenez
95*de0e0e4dSAntonio Huete Jimenez return bag->value.shkeybag;
96*de0e0e4dSAntonio Huete Jimenez }
97*de0e0e4dSAntonio Huete Jimenez
STACK_OF(PKCS12_SAFEBAG)98*de0e0e4dSAntonio Huete Jimenez const STACK_OF(PKCS12_SAFEBAG) *
99*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag)
100*de0e0e4dSAntonio Huete Jimenez {
101*de0e0e4dSAntonio Huete Jimenez if (PKCS12_SAFEBAG_get_nid(bag) != NID_safeContentsBag)
102*de0e0e4dSAntonio Huete Jimenez return NULL;
103*de0e0e4dSAntonio Huete Jimenez
104*de0e0e4dSAntonio Huete Jimenez return bag->value.safes;
105*de0e0e4dSAntonio Huete Jimenez }
106*de0e0e4dSAntonio Huete Jimenez
107*de0e0e4dSAntonio Huete Jimenez const ASN1_OBJECT *
PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG * bag)108*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get0_type(const PKCS12_SAFEBAG *bag)
109*de0e0e4dSAntonio Huete Jimenez {
110*de0e0e4dSAntonio Huete Jimenez return bag->type;
111*de0e0e4dSAntonio Huete Jimenez }
112*de0e0e4dSAntonio Huete Jimenez
113*de0e0e4dSAntonio Huete Jimenez int
PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG * bag)114*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get_nid(const PKCS12_SAFEBAG *bag)
115*de0e0e4dSAntonio Huete Jimenez {
116*de0e0e4dSAntonio Huete Jimenez return OBJ_obj2nid(bag->type);
117*de0e0e4dSAntonio Huete Jimenez }
118*de0e0e4dSAntonio Huete Jimenez
119*de0e0e4dSAntonio Huete Jimenez int
PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG * bag)120*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get_bag_nid(const PKCS12_SAFEBAG *bag)
121*de0e0e4dSAntonio Huete Jimenez {
122*de0e0e4dSAntonio Huete Jimenez int bag_type;
123*de0e0e4dSAntonio Huete Jimenez
124*de0e0e4dSAntonio Huete Jimenez bag_type = PKCS12_SAFEBAG_get_nid(bag);
125*de0e0e4dSAntonio Huete Jimenez
126*de0e0e4dSAntonio Huete Jimenez if (bag_type == NID_certBag || bag_type == NID_crlBag ||
127*de0e0e4dSAntonio Huete Jimenez bag_type == NID_secretBag)
128*de0e0e4dSAntonio Huete Jimenez return OBJ_obj2nid(bag->value.bag->type);
129*de0e0e4dSAntonio Huete Jimenez
130*de0e0e4dSAntonio Huete Jimenez return -1;
131*de0e0e4dSAntonio Huete Jimenez }
132*de0e0e4dSAntonio Huete Jimenez
133*de0e0e4dSAntonio Huete Jimenez X509 *
PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG * bag)134*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag)
135*de0e0e4dSAntonio Huete Jimenez {
136*de0e0e4dSAntonio Huete Jimenez if (OBJ_obj2nid(bag->type) != NID_certBag)
137*de0e0e4dSAntonio Huete Jimenez return NULL;
138*de0e0e4dSAntonio Huete Jimenez if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Certificate)
139*de0e0e4dSAntonio Huete Jimenez return NULL;
140*de0e0e4dSAntonio Huete Jimenez return ASN1_item_unpack(bag->value.bag->value.octet, &X509_it);
141*de0e0e4dSAntonio Huete Jimenez }
142*de0e0e4dSAntonio Huete Jimenez
143*de0e0e4dSAntonio Huete Jimenez X509_CRL *
PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG * bag)144*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag)
145*de0e0e4dSAntonio Huete Jimenez {
146*de0e0e4dSAntonio Huete Jimenez if (OBJ_obj2nid(bag->type) != NID_crlBag)
147*de0e0e4dSAntonio Huete Jimenez return NULL;
148*de0e0e4dSAntonio Huete Jimenez if (OBJ_obj2nid(bag->value.bag->type) != NID_x509Crl)
149*de0e0e4dSAntonio Huete Jimenez return NULL;
150*de0e0e4dSAntonio Huete Jimenez return ASN1_item_unpack(bag->value.bag->value.octet, &X509_CRL_it);
151*de0e0e4dSAntonio Huete Jimenez }
152*de0e0e4dSAntonio Huete Jimenez
153*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *
PKCS12_SAFEBAG_create_cert(X509 * x509)154*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_create_cert(X509 *x509)
155*de0e0e4dSAntonio Huete Jimenez {
156*de0e0e4dSAntonio Huete Jimenez return PKCS12_item_pack_safebag(x509, &X509_it,
157*de0e0e4dSAntonio Huete Jimenez NID_x509Certificate, NID_certBag);
158*de0e0e4dSAntonio Huete Jimenez }
159*de0e0e4dSAntonio Huete Jimenez
160*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *
PKCS12_SAFEBAG_create_crl(X509_CRL * crl)161*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_create_crl(X509_CRL *crl)
162*de0e0e4dSAntonio Huete Jimenez {
163*de0e0e4dSAntonio Huete Jimenez return PKCS12_item_pack_safebag(crl, &X509_CRL_it,
164*de0e0e4dSAntonio Huete Jimenez NID_x509Crl, NID_crlBag);
165*de0e0e4dSAntonio Huete Jimenez }
166*de0e0e4dSAntonio Huete Jimenez
167*de0e0e4dSAntonio Huete Jimenez /* Turn PKCS8 object into a keybag */
168*de0e0e4dSAntonio Huete Jimenez
169*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *
PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO * p8)170*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_create0_p8inf(PKCS8_PRIV_KEY_INFO *p8)
171*de0e0e4dSAntonio Huete Jimenez {
172*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *bag;
173*de0e0e4dSAntonio Huete Jimenez
174*de0e0e4dSAntonio Huete Jimenez if ((bag = PKCS12_SAFEBAG_new()) == NULL) {
175*de0e0e4dSAntonio Huete Jimenez PKCS12error(ERR_R_MALLOC_FAILURE);
176*de0e0e4dSAntonio Huete Jimenez return NULL;
177*de0e0e4dSAntonio Huete Jimenez }
178*de0e0e4dSAntonio Huete Jimenez
179*de0e0e4dSAntonio Huete Jimenez bag->type = OBJ_nid2obj(NID_keyBag);
180*de0e0e4dSAntonio Huete Jimenez bag->value.keybag = p8;
181*de0e0e4dSAntonio Huete Jimenez
182*de0e0e4dSAntonio Huete Jimenez return bag;
183*de0e0e4dSAntonio Huete Jimenez }
184*de0e0e4dSAntonio Huete Jimenez
185*de0e0e4dSAntonio Huete Jimenez /* Turn PKCS8 object into a shrouded keybag */
186*de0e0e4dSAntonio Huete Jimenez
187*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *
PKCS12_SAFEBAG_create0_pkcs8(X509_SIG * p8)188*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_create0_pkcs8(X509_SIG *p8)
189*de0e0e4dSAntonio Huete Jimenez {
190*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *bag;
191*de0e0e4dSAntonio Huete Jimenez
192*de0e0e4dSAntonio Huete Jimenez /* Set up the safe bag */
193*de0e0e4dSAntonio Huete Jimenez if ((bag = PKCS12_SAFEBAG_new()) == NULL) {
194*de0e0e4dSAntonio Huete Jimenez PKCS12error(ERR_R_MALLOC_FAILURE);
195*de0e0e4dSAntonio Huete Jimenez return NULL;
196*de0e0e4dSAntonio Huete Jimenez }
197*de0e0e4dSAntonio Huete Jimenez
198*de0e0e4dSAntonio Huete Jimenez bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
199*de0e0e4dSAntonio Huete Jimenez bag->value.shkeybag = p8;
200*de0e0e4dSAntonio Huete Jimenez
201*de0e0e4dSAntonio Huete Jimenez return bag;
202*de0e0e4dSAntonio Huete Jimenez }
203*de0e0e4dSAntonio Huete Jimenez
204*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *
PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid,const char * pass,int passlen,unsigned char * salt,int saltlen,int iter,PKCS8_PRIV_KEY_INFO * p8info)205*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG_create_pkcs8_encrypt(int pbe_nid, const char *pass, int passlen,
206*de0e0e4dSAntonio Huete Jimenez unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8info)
207*de0e0e4dSAntonio Huete Jimenez {
208*de0e0e4dSAntonio Huete Jimenez const EVP_CIPHER *pbe_ciph;
209*de0e0e4dSAntonio Huete Jimenez X509_SIG *p8;
210*de0e0e4dSAntonio Huete Jimenez PKCS12_SAFEBAG *bag;
211*de0e0e4dSAntonio Huete Jimenez
212*de0e0e4dSAntonio Huete Jimenez if ((pbe_ciph = EVP_get_cipherbynid(pbe_nid)) != NULL)
213*de0e0e4dSAntonio Huete Jimenez pbe_nid = -1;
214*de0e0e4dSAntonio Huete Jimenez
215*de0e0e4dSAntonio Huete Jimenez if ((p8 = PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen,
216*de0e0e4dSAntonio Huete Jimenez iter, p8info)) == NULL)
217*de0e0e4dSAntonio Huete Jimenez return NULL;
218*de0e0e4dSAntonio Huete Jimenez
219*de0e0e4dSAntonio Huete Jimenez if ((bag = PKCS12_SAFEBAG_create0_pkcs8(p8)) == NULL) {
220*de0e0e4dSAntonio Huete Jimenez X509_SIG_free(p8);
221*de0e0e4dSAntonio Huete Jimenez return NULL;
222*de0e0e4dSAntonio Huete Jimenez }
223*de0e0e4dSAntonio Huete Jimenez
224*de0e0e4dSAntonio Huete Jimenez return bag;
225*de0e0e4dSAntonio Huete Jimenez }
226