Fix a possible memory leak in engine_table_register
[openssl.git] / crypto / pkcs12 / p12_crt.c
1 /* p12_crt.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4  * project.
5  */
6 /* ====================================================================
7  * Copyright (c) 1999-2002 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 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
65                           PKCS12_SAFEBAG *bag);
66
67 static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
68 {
69     int idx;
70     X509_ATTRIBUTE *attr;
71     idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
72     if (idx < 0)
73         return 1;
74     attr = EVP_PKEY_get_attr(pkey, idx);
75     if (!X509at_add1_attr(&bag->attrib, attr))
76         return 0;
77     return 1;
78 }
79
80 PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
81                       STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
82                       int mac_iter, int keytype)
83 {
84     PKCS12 *p12 = NULL;
85     STACK_OF(PKCS7) *safes = NULL;
86     STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
87     PKCS12_SAFEBAG *bag = NULL;
88     int i;
89     unsigned char keyid[EVP_MAX_MD_SIZE];
90     unsigned int keyidlen = 0;
91
92     /* Set defaults */
93     if (!nid_cert) {
94 #ifdef OPENSSL_FIPS
95         if (FIPS_mode())
96             nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
97         else
98 #endif
99 #ifdef OPENSSL_NO_RC2
100             nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
101 #else
102             nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
103 #endif
104     }
105     if (!nid_key)
106         nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
107     if (!iter)
108         iter = PKCS12_DEFAULT_ITER;
109     if (!mac_iter)
110         mac_iter = 1;
111
112     if (!pkey && !cert && !ca) {
113         PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT);
114         return NULL;
115     }
116
117     if (pkey && cert) {
118         if (!X509_check_private_key(cert, pkey))
119             return NULL;
120         X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
121     }
122
123     if (cert) {
124         bag = PKCS12_add_cert(&bags, cert);
125         if (name && !PKCS12_add_friendlyname(bag, name, -1))
126             goto err;
127         if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
128             goto err;
129     }
130
131     /* Add all other certificates */
132     for (i = 0; i < sk_X509_num(ca); i++) {
133         if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
134             goto err;
135     }
136
137     if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
138         goto err;
139
140     sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
141     bags = NULL;
142
143     if (pkey) {
144         bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
145
146         if (!bag)
147             goto err;
148
149         if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
150             goto err;
151         if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
152             goto err;
153
154         if (name && !PKCS12_add_friendlyname(bag, name, -1))
155             goto err;
156         if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
157             goto err;
158     }
159
160     if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
161         goto err;
162
163     sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
164     bags = NULL;
165
166     p12 = PKCS12_add_safes(safes, 0);
167
168     if (!p12)
169         goto err;
170
171     sk_PKCS7_pop_free(safes, PKCS7_free);
172
173     safes = NULL;
174
175     if ((mac_iter != -1) &&
176         !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
177         goto err;
178
179     return p12;
180
181  err:
182
183     if (p12)
184         PKCS12_free(p12);
185     if (safes)
186         sk_PKCS7_pop_free(safes, PKCS7_free);
187     if (bags)
188         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
189     return NULL;
190
191 }
192
193 PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
194 {
195     PKCS12_SAFEBAG *bag = NULL;
196     char *name;
197     int namelen = -1;
198     unsigned char *keyid;
199     int keyidlen = -1;
200
201     /* Add user certificate */
202     if (!(bag = PKCS12_x5092certbag(cert)))
203         goto err;
204
205     /*
206      * Use friendlyName and localKeyID in certificate. (if present)
207      */
208
209     name = (char *)X509_alias_get0(cert, &namelen);
210
211     if (name && !PKCS12_add_friendlyname(bag, name, namelen))
212         goto err;
213
214     keyid = X509_keyid_get0(cert, &keyidlen);
215
216     if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
217         goto err;
218
219     if (!pkcs12_add_bag(pbags, bag))
220         goto err;
221
222     return bag;
223
224  err:
225
226     if (bag)
227         PKCS12_SAFEBAG_free(bag);
228
229     return NULL;
230
231 }
232
233 PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
234                                EVP_PKEY *key, int key_usage, int iter,
235                                int nid_key, char *pass)
236 {
237
238     PKCS12_SAFEBAG *bag = NULL;
239     PKCS8_PRIV_KEY_INFO *p8 = NULL;
240
241     /* Make a PKCS#8 structure */
242     if (!(p8 = EVP_PKEY2PKCS8(key)))
243         goto err;
244     if (key_usage && !PKCS8_add_keyusage(p8, key_usage))
245         goto err;
246     if (nid_key != -1) {
247         bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
248         PKCS8_PRIV_KEY_INFO_free(p8);
249     } else
250         bag = PKCS12_MAKE_KEYBAG(p8);
251
252     if (!bag)
253         goto err;
254
255     if (!pkcs12_add_bag(pbags, bag))
256         goto err;
257
258     return bag;
259
260  err:
261
262     if (bag)
263         PKCS12_SAFEBAG_free(bag);
264
265     return NULL;
266
267 }
268
269 int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
270                     int nid_safe, int iter, char *pass)
271 {
272     PKCS7 *p7 = NULL;
273     int free_safes = 0;
274
275     if (!*psafes) {
276         *psafes = sk_PKCS7_new_null();
277         if (!*psafes)
278             return 0;
279         free_safes = 1;
280     } else
281         free_safes = 0;
282
283     if (nid_safe == 0)
284 #ifdef OPENSSL_NO_RC2
285         nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
286 #else
287         nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
288 #endif
289
290     if (nid_safe == -1)
291         p7 = PKCS12_pack_p7data(bags);
292     else
293         p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags);
294     if (!p7)
295         goto err;
296
297     if (!sk_PKCS7_push(*psafes, p7))
298         goto err;
299
300     return 1;
301
302  err:
303     if (free_safes) {
304         sk_PKCS7_free(*psafes);
305         *psafes = NULL;
306     }
307
308     if (p7)
309         PKCS7_free(p7);
310
311     return 0;
312
313 }
314
315 static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags,
316                           PKCS12_SAFEBAG *bag)
317 {
318     int free_bags;
319     if (!pbags)
320         return 1;
321     if (!*pbags) {
322         *pbags = sk_PKCS12_SAFEBAG_new_null();
323         if (!*pbags)
324             return 0;
325         free_bags = 1;
326     } else
327         free_bags = 0;
328
329     if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) {
330         if (free_bags) {
331             sk_PKCS12_SAFEBAG_free(*pbags);
332             *pbags = NULL;
333         }
334         return 0;
335     }
336
337     return 1;
338
339 }
340
341 PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
342 {
343     PKCS12 *p12;
344     if (nid_p7 <= 0)
345         nid_p7 = NID_pkcs7_data;
346     p12 = PKCS12_init(nid_p7);
347
348     if (!p12)
349         return NULL;
350
351     if (!PKCS12_pack_authsafes(p12, safes)) {
352         PKCS12_free(p12);
353         return NULL;
354     }
355
356     return p12;
357
358 }