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