~ubuntu-branches/ubuntu/maverick/openssl/maverick

« back to all changes in this revision

Viewing changes to crypto/pkcs12/p12_crt.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2005-12-13 21:37:42 UTC
  • mto: (11.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20051213213742-d0ydaylf80l16bj1
Tags: upstream-0.9.8a
ImportĀ upstreamĀ versionĀ 0.9.8a

Show diffs side-by-side

added added

removed removed

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