Line data Source code
1 : /* p12_add.c */
2 : /*
3 : * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
4 : * 1999.
5 : */
6 : /* ====================================================================
7 : * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8 : *
9 : * Redistribution and use in source and binary forms, with or without
10 : * modification, are permitted provided that the following conditions
11 : * are met:
12 : *
13 : * 1. Redistributions of source code must retain the above copyright
14 : * notice, this list of conditions and the following disclaimer.
15 : *
16 : * 2. Redistributions in binary form must reproduce the above copyright
17 : * notice, this list of conditions and the following disclaimer in
18 : * the documentation and/or other materials provided with the
19 : * distribution.
20 : *
21 : * 3. All advertising materials mentioning features or use of this
22 : * software must display the following acknowledgment:
23 : * "This product includes software developed by the OpenSSL Project
24 : * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 : *
26 : * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 : * endorse or promote products derived from this software without
28 : * prior written permission. For written permission, please contact
29 : * licensing@OpenSSL.org.
30 : *
31 : * 5. Products derived from this software may not be called "OpenSSL"
32 : * nor may "OpenSSL" appear in their names without prior written
33 : * permission of the OpenSSL Project.
34 : *
35 : * 6. Redistributions of any form whatsoever must retain the following
36 : * acknowledgment:
37 : * "This product includes software developed by the OpenSSL Project
38 : * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 : *
40 : * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 : * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 : * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 : * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 : * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 : * OF THE POSSIBILITY OF SUCH DAMAGE.
52 : * ====================================================================
53 : *
54 : * This product includes cryptographic software written by Eric Young
55 : * (eay@cryptsoft.com). This product includes software written by Tim
56 : * Hudson (tjh@cryptsoft.com).
57 : *
58 : */
59 :
60 : #include <stdio.h>
61 : #include "cryptlib.h"
62 : #include <openssl/pkcs12.h>
63 :
64 : /* Pack an object into an OCTET STRING and turn into a safebag */
65 :
66 0 : PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
67 : int nid1, int nid2)
68 : {
69 : PKCS12_BAGS *bag;
70 : PKCS12_SAFEBAG *safebag;
71 0 : if (!(bag = PKCS12_BAGS_new())) {
72 0 : PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
73 0 : return NULL;
74 : }
75 0 : bag->type = OBJ_nid2obj(nid1);
76 0 : if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
77 0 : PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
78 0 : return NULL;
79 : }
80 0 : if (!(safebag = PKCS12_SAFEBAG_new())) {
81 0 : PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
82 0 : return NULL;
83 : }
84 0 : safebag->value.bag = bag;
85 0 : safebag->type = OBJ_nid2obj(nid2);
86 0 : return safebag;
87 : }
88 :
89 : /* Turn PKCS8 object into a keybag */
90 :
91 0 : PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
92 : {
93 : PKCS12_SAFEBAG *bag;
94 0 : if (!(bag = PKCS12_SAFEBAG_new())) {
95 0 : PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE);
96 0 : return NULL;
97 : }
98 0 : bag->type = OBJ_nid2obj(NID_keyBag);
99 0 : bag->value.keybag = p8;
100 0 : return bag;
101 : }
102 :
103 : /* Turn PKCS8 object into a shrouded keybag */
104 :
105 0 : PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
106 : int passlen, unsigned char *salt,
107 : int saltlen, int iter,
108 : PKCS8_PRIV_KEY_INFO *p8)
109 : {
110 : PKCS12_SAFEBAG *bag;
111 : const EVP_CIPHER *pbe_ciph;
112 :
113 : /* Set up the safe bag */
114 0 : if (!(bag = PKCS12_SAFEBAG_new())) {
115 0 : PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
116 0 : return NULL;
117 : }
118 :
119 0 : bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
120 :
121 0 : pbe_ciph = EVP_get_cipherbynid(pbe_nid);
122 :
123 0 : if (pbe_ciph)
124 : pbe_nid = -1;
125 :
126 0 : if (!(bag->value.shkeybag =
127 0 : PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
128 : p8))) {
129 0 : PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
130 0 : return NULL;
131 : }
132 :
133 : return bag;
134 : }
135 :
136 : /* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
137 0 : PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
138 : {
139 : PKCS7 *p7;
140 0 : if (!(p7 = PKCS7_new())) {
141 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
142 0 : return NULL;
143 : }
144 0 : p7->type = OBJ_nid2obj(NID_pkcs7_data);
145 0 : if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
146 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
147 0 : return NULL;
148 : }
149 :
150 0 : if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
151 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
152 0 : return NULL;
153 : }
154 : return p7;
155 : }
156 :
157 : /* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
158 0 : STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
159 : {
160 0 : if (!PKCS7_type_is_data(p7)) {
161 0 : PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
162 : PKCS12_R_CONTENT_TYPE_NOT_DATA);
163 0 : return NULL;
164 : }
165 0 : return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
166 : }
167 :
168 : /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
169 :
170 0 : PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
171 : unsigned char *salt, int saltlen, int iter,
172 : STACK_OF(PKCS12_SAFEBAG) *bags)
173 : {
174 : PKCS7 *p7;
175 : X509_ALGOR *pbe;
176 : const EVP_CIPHER *pbe_ciph;
177 0 : if (!(p7 = PKCS7_new())) {
178 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
179 0 : return NULL;
180 : }
181 0 : if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
182 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
183 : PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
184 0 : return NULL;
185 : }
186 :
187 0 : pbe_ciph = EVP_get_cipherbynid(pbe_nid);
188 :
189 0 : if (pbe_ciph)
190 0 : pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
191 : else
192 0 : pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
193 :
194 0 : if (!pbe) {
195 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
196 0 : return NULL;
197 : }
198 0 : X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
199 0 : p7->d.encrypted->enc_data->algorithm = pbe;
200 0 : M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
201 0 : if (!(p7->d.encrypted->enc_data->enc_data =
202 0 : PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
203 : passlen, bags, 1))) {
204 0 : PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
205 0 : return NULL;
206 : }
207 :
208 : return p7;
209 : }
210 :
211 0 : STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
212 : int passlen)
213 : {
214 0 : if (!PKCS7_type_is_encrypted(p7))
215 : return NULL;
216 0 : return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
217 : ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
218 : pass, passlen,
219 0 : p7->d.encrypted->enc_data->enc_data, 1);
220 : }
221 :
222 0 : PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
223 : const char *pass, int passlen)
224 : {
225 0 : return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
226 : }
227 :
228 0 : int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
229 : {
230 0 : if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
231 0 : &p12->authsafes->d.data))
232 : return 1;
233 0 : return 0;
234 : }
235 :
236 0 : STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
237 : {
238 0 : if (!PKCS7_type_is_data(p12->authsafes)) {
239 0 : PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
240 : PKCS12_R_CONTENT_TYPE_NOT_DATA);
241 0 : return NULL;
242 : }
243 0 : return ASN1_item_unpack(p12->authsafes->d.data,
244 : ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
245 : }
|