]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - crypto/openssl/crypto/pkcs12/p12_add.c
Merge OpenSSL 1.0.1q.
[FreeBSD/stable/10.git] / crypto / openssl / crypto / pkcs12 / p12_add.c
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 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     if (!(bag = PKCS12_BAGS_new())) {
72         PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
73         return NULL;
74     }
75     bag->type = OBJ_nid2obj(nid1);
76     if (!ASN1_item_pack(obj, it, &bag->value.octet)) {
77         PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
78         goto err;
79     }
80     if (!(safebag = PKCS12_SAFEBAG_new())) {
81         PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE);
82         goto err;
83     }
84     safebag->value.bag = bag;
85     safebag->type = OBJ_nid2obj(nid2);
86     return safebag;
87
88  err:
89     PKCS12_BAGS_free(bag);
90     return NULL;
91 }
92
93 /* Turn PKCS8 object into a keybag */
94
95 PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8)
96 {
97     PKCS12_SAFEBAG *bag;
98     if (!(bag = PKCS12_SAFEBAG_new())) {
99         PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE);
100         return NULL;
101     }
102     bag->type = OBJ_nid2obj(NID_keyBag);
103     bag->value.keybag = p8;
104     return bag;
105 }
106
107 /* Turn PKCS8 object into a shrouded keybag */
108
109 PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
110                                      int passlen, unsigned char *salt,
111                                      int saltlen, int iter,
112                                      PKCS8_PRIV_KEY_INFO *p8)
113 {
114     PKCS12_SAFEBAG *bag;
115     const EVP_CIPHER *pbe_ciph;
116
117     /* Set up the safe bag */
118     if (!(bag = PKCS12_SAFEBAG_new())) {
119         PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
120         return NULL;
121     }
122
123     bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag);
124
125     pbe_ciph = EVP_get_cipherbynid(pbe_nid);
126
127     if (pbe_ciph)
128         pbe_nid = -1;
129
130     if (!(bag->value.shkeybag =
131           PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter,
132                         p8))) {
133         PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE);
134         PKCS12_SAFEBAG_free(bag);
135         return NULL;
136     }
137
138     return bag;
139 }
140
141 /* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */
142 PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk)
143 {
144     PKCS7 *p7;
145     if (!(p7 = PKCS7_new())) {
146         PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
147         return NULL;
148     }
149     p7->type = OBJ_nid2obj(NID_pkcs7_data);
150     if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) {
151         PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE);
152         goto err;
153     }
154
155     if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) {
156         PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE);
157         goto err;
158     }
159     return p7;
160
161  err:
162     PKCS7_free(p7);
163     return NULL;
164 }
165
166 /* Unpack SAFEBAGS from PKCS#7 data ContentInfo */
167 STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
168 {
169     if (!PKCS7_type_is_data(p7)) {
170         PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA,
171                   PKCS12_R_CONTENT_TYPE_NOT_DATA);
172         return NULL;
173     }
174     return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
175 }
176
177 /* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */
178
179 PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
180                              unsigned char *salt, int saltlen, int iter,
181                              STACK_OF(PKCS12_SAFEBAG) *bags)
182 {
183     PKCS7 *p7;
184     X509_ALGOR *pbe;
185     const EVP_CIPHER *pbe_ciph;
186     if (!(p7 = PKCS7_new())) {
187         PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
188         return NULL;
189     }
190     if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) {
191         PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA,
192                   PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE);
193         goto err;
194     }
195
196     pbe_ciph = EVP_get_cipherbynid(pbe_nid);
197
198     if (pbe_ciph)
199         pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen);
200     else
201         pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen);
202
203     if (!pbe) {
204         PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE);
205         goto err;
206     }
207     X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm);
208     p7->d.encrypted->enc_data->algorithm = pbe;
209     M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data);
210     if (!(p7->d.encrypted->enc_data->enc_data =
211           PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass,
212                                   passlen, bags, 1))) {
213         PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR);
214         goto err;
215     }
216
217     return p7;
218
219  err:
220     PKCS7_free(p7);
221     return NULL;
222 }
223
224 STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
225                                                   int passlen)
226 {
227     if (!PKCS7_type_is_encrypted(p7))
228         return NULL;
229     return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
230                                    ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
231                                    pass, passlen,
232                                    p7->d.encrypted->enc_data->enc_data, 1);
233 }
234
235 PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
236                                          const char *pass, int passlen)
237 {
238     return PKCS8_decrypt(bag->value.shkeybag, pass, passlen);
239 }
240
241 int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes)
242 {
243     if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES),
244                        &p12->authsafes->d.data))
245         return 1;
246     return 0;
247 }
248
249 STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12)
250 {
251     if (!PKCS7_type_is_data(p12->authsafes)) {
252         PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES,
253                   PKCS12_R_CONTENT_TYPE_NOT_DATA);
254         return NULL;
255     }
256     return ASN1_item_unpack(p12->authsafes->d.data,
257                             ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
258 }