xref: /freebsd/crypto/openssl/crypto/pkcs12/p12_crt.c (revision d6b92ffa)
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 }
359