~ubuntu-branches/ubuntu/precise/openssl098/precise

« back to all changes in this revision

Viewing changes to crypto/pkcs12/p12_crt.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2011-03-23 19:50:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110323195031-6h9crj4bymhhr8b8
Tags: upstream-0.9.8o
ImportĀ upstreamĀ versionĀ 0.9.8o

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* p12_crt.c */
 
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
 
3
 * project.
 
4
 */
 
5
/* ====================================================================
 
6
 * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 *
 
12
 * 1. Redistributions of source code must retain the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer. 
 
14
 *
 
15
 * 2. Redistributions in binary form must reproduce the above copyright
 
16
 *    notice, this list of conditions and the following disclaimer in
 
17
 *    the documentation and/or other materials provided with the
 
18
 *    distribution.
 
19
 *
 
20
 * 3. All advertising materials mentioning features or use of this
 
21
 *    software must display the following acknowledgment:
 
22
 *    "This product includes software developed by the OpenSSL Project
 
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
 
24
 *
 
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
 
26
 *    endorse or promote products derived from this software without
 
27
 *    prior written permission. For written permission, please contact
 
28
 *    licensing@OpenSSL.org.
 
29
 *
 
30
 * 5. Products derived from this software may not be called "OpenSSL"
 
31
 *    nor may "OpenSSL" appear in their names without prior written
 
32
 *    permission of the OpenSSL Project.
 
33
 *
 
34
 * 6. Redistributions of any form whatsoever must retain the following
 
35
 *    acknowledgment:
 
36
 *    "This product includes software developed by the OpenSSL Project
 
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
 
38
 *
 
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
 
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
 
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 
51
 * ====================================================================
 
52
 *
 
53
 * This product includes cryptographic software written by Eric Young
 
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
 
55
 * Hudson (tjh@cryptsoft.com).
 
56
 *
 
57
 */
 
58
 
 
59
#include <stdio.h>
 
60
#include "cryptlib.h"
 
61
#include <openssl/pkcs12.h>
 
62
#ifdef OPENSSL_FIPS
 
63
#include <openssl/fips.h>
 
64
#endif
 
65
 
 
66
 
 
67
 
 
68
static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag);
 
69
 
 
70
static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid)
 
71
        {
 
72
        int idx;
 
73
        X509_ATTRIBUTE *attr;
 
74
        idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1);
 
75
        if (idx < 0)
 
76
                return 1;
 
77
        attr = EVP_PKEY_get_attr(pkey, idx);
 
78
        if (!X509at_add1_attr(&bag->attrib, attr))
 
79
                return 0;
 
80
        return 1;
 
81
        }
 
82
 
 
83
PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
 
84
             STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, int mac_iter,
 
85
             int keytype)
 
86
{
 
87
        PKCS12 *p12 = NULL;
 
88
        STACK_OF(PKCS7) *safes = NULL;
 
89
        STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
 
90
        PKCS12_SAFEBAG *bag = NULL;
 
91
        int i;
 
92
        unsigned char keyid[EVP_MAX_MD_SIZE];
 
93
        unsigned int keyidlen = 0;
 
94
 
 
95
        /* Set defaults */
 
96
        if (!nid_cert)
 
97
                {
 
98
#ifdef OPENSSL_FIPS
 
99
                if (FIPS_mode())
 
100
                        nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
 
101
                else
 
102
#endif
 
103
                nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC;
 
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
                {
 
114
                PKCS12err(PKCS12_F_PKCS12_CREATE,PKCS12_R_INVALID_NULL_ARGUMENT);
 
115
                return NULL;
 
116
                }
 
117
 
 
118
        if (pkey && cert)
 
119
                {
 
120
                if(!X509_check_private_key(cert, pkey))
 
121
                        return NULL;
 
122
                X509_digest(cert, EVP_sha1(), keyid, &keyidlen);
 
123
                }
 
124
 
 
125
        if (cert)
 
126
                {
 
127
                bag = PKCS12_add_cert(&bags, cert);
 
128
                if(name && !PKCS12_add_friendlyname(bag, name, -1))
 
129
                        goto err;
 
130
                if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
 
131
                        goto err;
 
132
                }
 
133
 
 
134
        /* Add all other certificates */
 
135
        for(i = 0; i < sk_X509_num(ca); i++)
 
136
                {
 
137
                if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i)))
 
138
                        goto err;
 
139
                }
 
140
 
 
141
        if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass))
 
142
                        goto err;
 
143
 
 
144
        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
 
145
        bags = NULL;
 
146
 
 
147
        if (pkey)
 
148
                {
 
149
                bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass);
 
150
 
 
151
                if (!bag)
 
152
                        goto err;
 
153
 
 
154
                if (!copy_bag_attr(bag, pkey, NID_ms_csp_name))
 
155
                        goto err;
 
156
                if (!copy_bag_attr(bag, pkey, NID_LocalKeySet))
 
157
                        goto err;
 
158
 
 
159
                if(name && !PKCS12_add_friendlyname(bag, name, -1))
 
160
                        goto err;
 
161
                if(keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
 
162
                        goto err;
 
163
                }
 
164
 
 
165
        if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL))
 
166
                        goto err;
 
167
 
 
168
        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
 
169
        bags = NULL;
 
170
 
 
171
        p12 = PKCS12_add_safes(safes, 0);
 
172
 
 
173
        if (!p12)
 
174
                goto err;
 
175
 
 
176
        sk_PKCS7_pop_free(safes, PKCS7_free);
 
177
 
 
178
        safes = NULL;
 
179
 
 
180
        if ((mac_iter != -1) &&
 
181
                !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL))
 
182
            goto err;
 
183
 
 
184
        return p12;
 
185
 
 
186
        err:
 
187
 
 
188
        if (p12)
 
189
                PKCS12_free(p12);
 
190
        if (safes)
 
191
                sk_PKCS7_pop_free(safes, PKCS7_free);
 
192
        if (bags)
 
193
                sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
 
194
        return NULL;
 
195
 
 
196
}
 
197
 
 
198
PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert)
 
199
        {
 
200
        PKCS12_SAFEBAG *bag = NULL;
 
201
        char *name;
 
202
        int namelen = -1;
 
203
        unsigned char *keyid;
 
204
        int keyidlen = -1;
 
205
 
 
206
        /* Add user certificate */
 
207
        if(!(bag = PKCS12_x5092certbag(cert)))
 
208
                goto err;
 
209
 
 
210
        /* Use friendlyName and localKeyID in certificate.
 
211
         * (if present)
 
212
         */
 
213
 
 
214
        name = (char *)X509_alias_get0(cert, &namelen);
 
215
 
 
216
        if(name && !PKCS12_add_friendlyname(bag, name, namelen))
 
217
                goto err;
 
218
 
 
219
        keyid = X509_keyid_get0(cert, &keyidlen);
 
220
 
 
221
        if(keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
 
222
                goto err;
 
223
 
 
224
        if (!pkcs12_add_bag(pbags, bag))
 
225
                goto err;
 
226
 
 
227
        return bag;
 
228
 
 
229
        err:
 
230
 
 
231
        if (bag)
 
232
                PKCS12_SAFEBAG_free(bag);
 
233
 
 
234
        return NULL;
 
235
 
 
236
        }
 
237
 
 
238
PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
 
239
                                                int key_usage, int iter,
 
240
                                                int nid_key, char *pass)
 
241
        {
 
242
 
 
243
        PKCS12_SAFEBAG *bag = NULL;
 
244
        PKCS8_PRIV_KEY_INFO *p8 = NULL;
 
245
 
 
246
        /* Make a PKCS#8 structure */
 
247
        if(!(p8 = EVP_PKEY2PKCS8(key)))
 
248
                goto err;
 
249
        if(key_usage && !PKCS8_add_keyusage(p8, key_usage))
 
250
                goto err;
 
251
        if (nid_key != -1)
 
252
                {
 
253
                bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8);
 
254
                PKCS8_PRIV_KEY_INFO_free(p8);
 
255
                }
 
256
        else
 
257
                bag = PKCS12_MAKE_KEYBAG(p8);
 
258
 
 
259
        if(!bag)
 
260
                goto err;
 
261
 
 
262
        if (!pkcs12_add_bag(pbags, bag))
 
263
                goto err;
 
264
 
 
265
        return bag;
 
266
 
 
267
        err:
 
268
 
 
269
        if (bag)
 
270
                PKCS12_SAFEBAG_free(bag);
 
271
 
 
272
        return NULL;
 
273
 
 
274
        }
 
275
 
 
276
int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
 
277
                                                int nid_safe, int iter, char *pass)
 
278
        {
 
279
        PKCS7 *p7 = NULL;
 
280
        int free_safes = 0;
 
281
 
 
282
        if (!*psafes)
 
283
                {
 
284
                *psafes = sk_PKCS7_new_null();
 
285
                if (!*psafes)
 
286
                        return 0;
 
287
                free_safes = 1;
 
288
                }
 
289
        else
 
290
                free_safes = 0;
 
291
 
 
292
        if (nid_safe == 0)
 
293
                nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC;
 
294
 
 
295
        if (nid_safe == -1)
 
296
                p7 = PKCS12_pack_p7data(bags);
 
297
        else
 
298
                p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0,
 
299
                                          iter, bags);
 
300
        if (!p7)
 
301
                goto err;
 
302
 
 
303
        if (!sk_PKCS7_push(*psafes, p7))
 
304
                goto err;
 
305
 
 
306
        return 1;
 
307
 
 
308
        err:
 
309
        if (free_safes)
 
310
                {
 
311
                sk_PKCS7_free(*psafes);
 
312
                *psafes = NULL;
 
313
                }
 
314
 
 
315
        if (p7)
 
316
                PKCS7_free(p7);
 
317
 
 
318
        return 0;
 
319
 
 
320
        }
 
321
 
 
322
static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, PKCS12_SAFEBAG *bag)
 
323
        {
 
324
        int free_bags;
 
325
        if (!pbags)
 
326
                return 1;
 
327
        if (!*pbags)
 
328
                {
 
329
                *pbags = sk_PKCS12_SAFEBAG_new_null();
 
330
                if (!*pbags)
 
331
                        return 0;
 
332
                free_bags = 1;
 
333
                }
 
334
        else 
 
335
                free_bags = 0;
 
336
 
 
337
        if (!sk_PKCS12_SAFEBAG_push(*pbags, bag))
 
338
                {
 
339
                if (free_bags)
 
340
                        {
 
341
                        sk_PKCS12_SAFEBAG_free(*pbags);
 
342
                        *pbags = NULL;
 
343
                        }
 
344
                return 0;
 
345
                }
 
346
 
 
347
        return 1;
 
348
 
 
349
        }
 
350
                
 
351
 
 
352
PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7)
 
353
        {
 
354
        PKCS12 *p12;
 
355
        if (nid_p7 <= 0)
 
356
                nid_p7 = NID_pkcs7_data;
 
357
        p12 = PKCS12_init(nid_p7);
 
358
 
 
359
        if (!p12)
 
360
                return NULL;
 
361
 
 
362
        if(!PKCS12_pack_authsafes(p12, safes))
 
363
                {
 
364
                PKCS12_free(p12);
 
365
                return NULL;
 
366
                }
 
367
 
 
368
        return p12;
 
369
 
 
370
        }