~andersk/ubuntu/oneiric/openssl/spurious-reboot

« back to all changes in this revision

Viewing changes to crypto/asn1/x_crl.c

  • Committer: Bazaar Package Importer
  • Author(s): Kurt Roeckx
  • Date: 2010-12-12 15:37:21 UTC
  • mto: (1.2.1 upstream) (11.2.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 55.
  • Revision ID: james.westby@ubuntu.com-20101212153721-mfw51stum5hwztpd
Tags: upstream-1.0.0c
ImportĀ upstreamĀ versionĀ 1.0.0c

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
 
59
59
#include <stdio.h>
60
60
#include "cryptlib.h"
 
61
#include "asn1_locl.h"
61
62
#include <openssl/asn1t.h>
62
63
#include <openssl/x509.h>
 
64
#include <openssl/x509v3.h>
63
65
 
64
66
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
65
67
                                const X509_REVOKED * const *b);
 
68
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
66
69
 
67
70
ASN1_SEQUENCE(X509_REVOKED) = {
68
71
        ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
70
73
        ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
71
74
} ASN1_SEQUENCE_END(X509_REVOKED)
72
75
 
 
76
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
 
77
static int def_crl_lookup(X509_CRL *crl,
 
78
                X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
 
79
 
 
80
static X509_CRL_METHOD int_crl_meth =
 
81
        {
 
82
        0,
 
83
        0,0,
 
84
        def_crl_lookup,
 
85
        def_crl_verify
 
86
        };
 
87
 
 
88
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
 
89
 
73
90
/* The X509_CRL_INFO structure needs a bit of customisation.
74
91
 * Since we cache the original encoding the signature wont be affected by
75
92
 * reordering of the revoked field.
76
93
 */
77
 
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it)
 
94
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 
95
                                                                void *exarg)
78
96
{
79
97
        X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
80
98
 
101
119
        ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
102
120
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
103
121
 
104
 
ASN1_SEQUENCE_ref(X509_CRL, 0, CRYPTO_LOCK_X509_CRL) = {
 
122
/* Set CRL entry issuer according to CRL certificate issuer extension.
 
123
 * Check for unhandled critical CRL entry extensions.
 
124
 */
 
125
 
 
126
static int crl_set_issuers(X509_CRL *crl)
 
127
        {
 
128
 
 
129
        int i, j;
 
130
        GENERAL_NAMES *gens, *gtmp;
 
131
        STACK_OF(X509_REVOKED) *revoked;
 
132
 
 
133
        revoked = X509_CRL_get_REVOKED(crl);
 
134
 
 
135
        gens = NULL;
 
136
        for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
 
137
                {
 
138
                X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
 
139
                STACK_OF(X509_EXTENSION) *exts;
 
140
                ASN1_ENUMERATED *reason;
 
141
                X509_EXTENSION *ext;
 
142
                gtmp = X509_REVOKED_get_ext_d2i(rev, 
 
143
                                                NID_certificate_issuer,
 
144
                                                &j, NULL);
 
145
                if (!gtmp && (j != -1))
 
146
                        {
 
147
                        crl->flags |= EXFLAG_INVALID;
 
148
                        return 1;
 
149
                        }
 
150
 
 
151
                if (gtmp)
 
152
                        {
 
153
                        gens = gtmp;
 
154
                        if (!crl->issuers)
 
155
                                {
 
156
                                crl->issuers = sk_GENERAL_NAMES_new_null();
 
157
                                if (!crl->issuers)
 
158
                                        return 0;
 
159
                                }
 
160
                        if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
 
161
                                return 0;
 
162
                        }
 
163
                rev->issuer = gens;
 
164
 
 
165
                reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
 
166
                                                                &j, NULL);
 
167
                if (!reason && (j != -1))
 
168
                        {
 
169
                        crl->flags |= EXFLAG_INVALID;
 
170
                        return 1;
 
171
                        }
 
172
 
 
173
                if (reason)
 
174
                        {
 
175
                        rev->reason = ASN1_ENUMERATED_get(reason);
 
176
                        ASN1_ENUMERATED_free(reason);
 
177
                        }
 
178
                else
 
179
                        rev->reason = CRL_REASON_NONE;  
 
180
 
 
181
                /* Check for critical CRL entry extensions */
 
182
 
 
183
                exts = rev->extensions;
 
184
 
 
185
                for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
 
186
                        {
 
187
                        ext = sk_X509_EXTENSION_value(exts, j);
 
188
                        if (ext->critical > 0)
 
189
                                {
 
190
                                if (OBJ_obj2nid(ext->object) ==
 
191
                                        NID_certificate_issuer)
 
192
                                        continue;
 
193
                                crl->flags |= EXFLAG_CRITICAL;
 
194
                                break;
 
195
                                }
 
196
                        }
 
197
 
 
198
 
 
199
                }
 
200
 
 
201
        return 1;
 
202
 
 
203
        }
 
204
 
 
205
/* The X509_CRL structure needs a bit of customisation. Cache some extensions
 
206
 * and hash of the whole CRL.
 
207
 */
 
208
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
 
209
                                                                void *exarg)
 
210
        {
 
211
        X509_CRL *crl = (X509_CRL *)*pval;
 
212
        STACK_OF(X509_EXTENSION) *exts;
 
213
        X509_EXTENSION *ext;
 
214
        int idx;
 
215
 
 
216
        switch(operation)
 
217
                {
 
218
                case ASN1_OP_NEW_POST:
 
219
                crl->idp = NULL;
 
220
                crl->akid = NULL;
 
221
                crl->flags = 0;
 
222
                crl->idp_flags = 0;
 
223
                crl->idp_reasons = CRLDP_ALL_REASONS;
 
224
                crl->meth = default_crl_method;
 
225
                crl->meth_data = NULL;
 
226
                crl->issuers = NULL;
 
227
                crl->crl_number = NULL;
 
228
                crl->base_crl_number = NULL;
 
229
                break;
 
230
 
 
231
                case ASN1_OP_D2I_POST:
 
232
#ifndef OPENSSL_NO_SHA
 
233
                X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
 
234
#endif
 
235
                crl->idp = X509_CRL_get_ext_d2i(crl,
 
236
                                NID_issuing_distribution_point, NULL, NULL);
 
237
                if (crl->idp)
 
238
                        setup_idp(crl, crl->idp);
 
239
 
 
240
                crl->akid = X509_CRL_get_ext_d2i(crl,
 
241
                                NID_authority_key_identifier, NULL, NULL);      
 
242
 
 
243
                crl->crl_number = X509_CRL_get_ext_d2i(crl,
 
244
                                NID_crl_number, NULL, NULL);    
 
245
 
 
246
                crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
 
247
                                NID_delta_crl, NULL, NULL);     
 
248
                /* Delta CRLs must have CRL number */
 
249
                if (crl->base_crl_number && !crl->crl_number)
 
250
                        crl->flags |= EXFLAG_INVALID;
 
251
 
 
252
                /* See if we have any unhandled critical CRL extensions and 
 
253
                 * indicate this in a flag. We only currently handle IDP so
 
254
                 * anything else critical sets the flag.
 
255
                 *
 
256
                 * This code accesses the X509_CRL structure directly:
 
257
                 * applications shouldn't do this.
 
258
                 */
 
259
 
 
260
                exts = crl->crl->extensions;
 
261
 
 
262
                for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
 
263
                        {
 
264
                        int nid;
 
265
                        ext = sk_X509_EXTENSION_value(exts, idx);
 
266
                        nid = OBJ_obj2nid(ext->object);
 
267
                        if (nid == NID_freshest_crl)
 
268
                                crl->flags |= EXFLAG_FRESHEST;
 
269
                        if (ext->critical > 0)
 
270
                                {
 
271
                                /* We handle IDP and deltas */
 
272
                                if ((nid == NID_issuing_distribution_point)
 
273
                                        || (nid == NID_delta_crl))
 
274
                                        break;;
 
275
                                crl->flags |= EXFLAG_CRITICAL;
 
276
                                break;
 
277
                                }
 
278
                        }
 
279
 
 
280
 
 
281
                if (!crl_set_issuers(crl))
 
282
                        return 0;
 
283
 
 
284
                if (crl->meth->crl_init)
 
285
                        {
 
286
                        if (crl->meth->crl_init(crl) == 0)
 
287
                                return 0;
 
288
                        }
 
289
                break;
 
290
 
 
291
                case ASN1_OP_FREE_POST:
 
292
                if (crl->meth->crl_free)
 
293
                        {
 
294
                        if (!crl->meth->crl_free(crl))
 
295
                                return 0;
 
296
                        }
 
297
                if (crl->akid)
 
298
                        AUTHORITY_KEYID_free(crl->akid);
 
299
                if (crl->idp)
 
300
                        ISSUING_DIST_POINT_free(crl->idp);
 
301
                ASN1_INTEGER_free(crl->crl_number);
 
302
                ASN1_INTEGER_free(crl->base_crl_number);
 
303
                sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
 
304
                break;
 
305
                }
 
306
        return 1;
 
307
        }
 
308
 
 
309
/* Convert IDP into a more convenient form */
 
310
 
 
311
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
 
312
        {
 
313
        int idp_only = 0;
 
314
        /* Set various flags according to IDP */
 
315
        crl->idp_flags |= IDP_PRESENT;
 
316
        if (idp->onlyuser > 0)
 
317
                {
 
318
                idp_only++;
 
319
                crl->idp_flags |= IDP_ONLYUSER;
 
320
                }
 
321
        if (idp->onlyCA > 0)
 
322
                {
 
323
                idp_only++;
 
324
                crl->idp_flags |= IDP_ONLYCA;
 
325
                }
 
326
        if (idp->onlyattr > 0)
 
327
                {
 
328
                idp_only++;
 
329
                crl->idp_flags |= IDP_ONLYATTR;
 
330
                }
 
331
 
 
332
        if (idp_only > 1)
 
333
                crl->idp_flags |= IDP_INVALID;
 
334
 
 
335
        if (idp->indirectCRL > 0)
 
336
                crl->idp_flags |= IDP_INDIRECT;
 
337
 
 
338
        if (idp->onlysomereasons)
 
339
                {
 
340
                crl->idp_flags |= IDP_REASONS;
 
341
                if (idp->onlysomereasons->length > 0)
 
342
                        crl->idp_reasons = idp->onlysomereasons->data[0];
 
343
                if (idp->onlysomereasons->length > 1)
 
344
                        crl->idp_reasons |=
 
345
                                (idp->onlysomereasons->data[1] << 8);
 
346
                crl->idp_reasons &= CRLDP_ALL_REASONS;
 
347
                }
 
348
 
 
349
        DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
 
350
        }
 
351
 
 
352
ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
105
353
        ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
106
354
        ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
107
355
        ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
134
382
        return 1;
135
383
}
136
384
 
 
385
int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
 
386
        {
 
387
        if (crl->meth->crl_verify)
 
388
                return crl->meth->crl_verify(crl, r);
 
389
        return 0;
 
390
        }
 
391
 
 
392
int X509_CRL_get0_by_serial(X509_CRL *crl,
 
393
                X509_REVOKED **ret, ASN1_INTEGER *serial)
 
394
        {
 
395
        if (crl->meth->crl_lookup)
 
396
                return crl->meth->crl_lookup(crl, ret, serial, NULL);
 
397
        return 0;
 
398
        }
 
399
 
 
400
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
 
401
        {
 
402
        if (crl->meth->crl_lookup)
 
403
                return crl->meth->crl_lookup(crl, ret,
 
404
                                                X509_get_serialNumber(x),
 
405
                                                X509_get_issuer_name(x));
 
406
        return 0;
 
407
        }
 
408
 
 
409
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
 
410
        {
 
411
        return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
 
412
                crl->sig_alg, crl->signature,crl->crl,r));
 
413
        }
 
414
 
 
415
static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
 
416
                                                X509_REVOKED *rev)
 
417
        {
 
418
        int i;
 
419
 
 
420
        if (!rev->issuer)
 
421
                {
 
422
                if (!nm)
 
423
                        return 1;
 
424
                if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
 
425
                        return 1;
 
426
                return 0;
 
427
                }
 
428
 
 
429
        if (!nm)
 
430
                nm = X509_CRL_get_issuer(crl);
 
431
 
 
432
        for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
 
433
                {
 
434
                GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
 
435
                if (gen->type != GEN_DIRNAME)
 
436
                        continue;
 
437
                if (!X509_NAME_cmp(nm, gen->d.directoryName))
 
438
                        return 1;
 
439
                }
 
440
        return 0;
 
441
 
 
442
        }
 
443
 
 
444
static int def_crl_lookup(X509_CRL *crl,
 
445
                X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
 
446
        {
 
447
        X509_REVOKED rtmp, *rev;
 
448
        int idx;
 
449
        rtmp.serialNumber = serial;
 
450
        /* Sort revoked into serial number order if not already sorted.
 
451
         * Do this under a lock to avoid race condition.
 
452
         */
 
453
        if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
 
454
                {
 
455
                CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
 
456
                sk_X509_REVOKED_sort(crl->crl->revoked);
 
457
                CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
 
458
                }
 
459
        idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
 
460
        if(idx < 0)
 
461
                return 0;
 
462
        /* Need to look for matching name */
 
463
        for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
 
464
                {
 
465
                rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
 
466
                if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
 
467
                        return 0;
 
468
                if (crl_revoked_issuer_match(crl, issuer, rev))
 
469
                        {
 
470
                        if (ret)
 
471
                                *ret = rev;
 
472
                        if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
 
473
                                return 2;
 
474
                        return 1;
 
475
                        }
 
476
                }
 
477
        return 0;
 
478
        }
 
479
 
 
480
void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
 
481
        {
 
482
        if (meth == NULL)
 
483
                default_crl_method = &int_crl_meth;
 
484
        else 
 
485
                default_crl_method = meth;
 
486
        }
 
487
 
 
488
X509_CRL_METHOD *X509_CRL_METHOD_new(
 
489
        int (*crl_init)(X509_CRL *crl),
 
490
        int (*crl_free)(X509_CRL *crl),
 
491
        int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
 
492
                                ASN1_INTEGER *ser, X509_NAME *issuer),
 
493
        int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
 
494
        {
 
495
        X509_CRL_METHOD *m;
 
496
        m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
 
497
        if (!m)
 
498
                return NULL;
 
499
        m->crl_init = crl_init;
 
500
        m->crl_free = crl_free;
 
501
        m->crl_lookup = crl_lookup;
 
502
        m->crl_verify = crl_verify;
 
503
        m->flags = X509_CRL_METHOD_DYNAMIC;
 
504
        return m;
 
505
        }
 
506
 
 
507
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
 
508
        {
 
509
        if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
 
510
                return;
 
511
        OPENSSL_free(m);
 
512
        }
 
513
 
 
514
void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
 
515
        {
 
516
        crl->meth_data = dat;
 
517
        }
 
518
 
 
519
void *X509_CRL_get_meth_data(X509_CRL *crl)
 
520
        {
 
521
        return crl->meth_data;
 
522
        }
 
523
 
137
524
IMPLEMENT_STACK_OF(X509_REVOKED)
138
525
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
139
526
IMPLEMENT_STACK_OF(X509_CRL)