caching of ocsp responses (experimental), no crl caching yet
[strongswan.git] / src / libstrongswan / plugins / x509 / x509_crl.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * $Id$
16 */
17
18 #include "x509_crl.h"
19
20 typedef struct private_x509_crl_t private_x509_crl_t;
21 typedef struct revoked_t revoked_t;
22
23 #include <debug.h>
24 #include <library.h>
25 #include <asn1/asn1.h>
26 #include <asn1/pem.h>
27 #include <credentials/certificates/x509.h>
28 #include <utils/linked_list.h>
29
30 /**
31 * entry for a revoked certificate
32 */
33 struct revoked_t {
34 /**
35 * serial of the revoked certificate
36 */
37 chunk_t serial;
38
39 /**
40 * date of revocation
41 */
42 time_t date;
43
44 /**
45 * reason for revocation
46 */
47 crl_reason_t reason;
48 };
49
50 /**
51 * private data of x509_crl
52 */
53 struct private_x509_crl_t {
54
55 /**
56 * public functions
57 */
58 x509_crl_t public;
59
60 /**
61 * X.509 crl encoding in ASN.1 DER format
62 */
63 chunk_t encoding;
64
65 /**
66 * X.509 crl body over which signature is computed
67 */
68 chunk_t tbsCertList;
69
70 /**
71 * Version of the X.509 crl
72 */
73 u_int version;
74
75 /**
76 * ID representing the crl issuer
77 */
78 identification_t *issuer;
79
80 /**
81 * CRL number
82 */
83 chunk_t crlNumber;
84
85 /**
86 * Time when the crl was generated
87 */
88 time_t thisUpdate;
89
90 /**
91 * Time when an update crl will be available
92 */
93 time_t nextUpdate;
94
95 /**
96 * list of revoked certificates as revoked_t
97 */
98 linked_list_t *revoked;
99
100 /**
101 * Authority Key Identifier
102 */
103 identification_t *authKeyIdentifier;
104
105 /**
106 * Authority Key Serial Number
107 */
108 chunk_t authKeySerialNumber;
109
110 /**
111 * Signature algorithm
112 */
113 int algorithm;
114
115 /**
116 * Signature
117 */
118 chunk_t signature;
119
120 /**
121 * reference counter
122 */
123 refcount_t ref;
124 };
125
126 /**
127 * from x509_cert
128 */
129 extern identification_t* x509_parse_authorityKeyIdentifier(
130 chunk_t blob, int level0,
131 chunk_t *authKeySerialNumber);
132
133 /**
134 * ASN.1 definition of an X.509 certificate revocation list
135 */
136 static const asn1Object_t crlObjects[] = {
137 { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
138 { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
139 { 2, "version", ASN1_INTEGER, ASN1_OPT |
140 ASN1_BODY }, /* 2 */
141 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
142 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
143 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
144 { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
145 { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
146 { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
147 ASN1_LOOP }, /* 8 */
148 { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
149 { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
150 { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
151 { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
152 ASN1_LOOP }, /* 12 */
153 { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
154 { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
155 { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
156 ASN1_BODY }, /* 15 */
157 { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
158 { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
159 { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
160 { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
161 { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
162 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
163 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
164 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
165 ASN1_BODY }, /* 23 */
166 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
167 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
168 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
169 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
170 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
171 };
172
173 #define CRL_OBJ_TBS_CERT_LIST 1
174 #define CRL_OBJ_VERSION 2
175 #define CRL_OBJ_SIG_ALG 4
176 #define CRL_OBJ_ISSUER 5
177 #define CRL_OBJ_THIS_UPDATE 6
178 #define CRL_OBJ_NEXT_UPDATE 7
179 #define CRL_OBJ_USER_CERTIFICATE 10
180 #define CRL_OBJ_REVOCATION_DATE 11
181 #define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
182 #define CRL_OBJ_CRL_ENTRY_CRITICAL 15
183 #define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
184 #define CRL_OBJ_EXTN_ID 22
185 #define CRL_OBJ_CRITICAL 23
186 #define CRL_OBJ_EXTN_VALUE 24
187 #define CRL_OBJ_ALGORITHM 27
188 #define CRL_OBJ_SIGNATURE 28
189 #define CRL_OBJ_ROOF 29
190
191 /**
192 * Parses an X.509 Certificate Revocation List (CRL)
193 */
194 static bool parse(private_x509_crl_t *this)
195 {
196 asn1_ctx_t ctx;
197 bool critical;
198 chunk_t extnID;
199 chunk_t userCertificate = chunk_empty;
200 revoked_t *revoked = NULL;
201 chunk_t object;
202 u_int level;
203 int sig_alg = OID_UNKNOWN;
204 int objectID = 0;
205
206 asn1_init(&ctx, this->encoding, 0, FALSE, FALSE);
207 while (objectID < CRL_OBJ_ROOF)
208 {
209 if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
210 {
211 return FALSE;
212 }
213
214 /* those objects which will parsed further need the next higher level */
215 level++;
216
217 switch (objectID)
218 {
219 case CRL_OBJ_TBS_CERT_LIST:
220 this->tbsCertList = object;
221 break;
222 case CRL_OBJ_VERSION:
223 this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
224 DBG2(" v%d", this->version);
225 break;
226 case CRL_OBJ_SIG_ALG:
227 sig_alg = parse_algorithmIdentifier(object, level, NULL);
228 break;
229 case CRL_OBJ_ISSUER:
230 this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
231 DBG2(" '%D'", this->issuer);
232 break;
233 case CRL_OBJ_THIS_UPDATE:
234 this->thisUpdate = parse_time(object, level);
235 break;
236 case CRL_OBJ_NEXT_UPDATE:
237 this->nextUpdate = parse_time(object, level);
238 break;
239 case CRL_OBJ_USER_CERTIFICATE:
240 userCertificate = object;
241 break;
242 case CRL_OBJ_REVOCATION_DATE:
243 revoked = malloc_thing(revoked_t);
244 revoked->serial = userCertificate;
245 revoked->date = parse_time(object, level);
246 revoked->reason = CRL_UNSPECIFIED;
247 this->revoked->insert_last(this->revoked, (void *)revoked);
248 break;
249 case CRL_OBJ_CRL_ENTRY_EXTN_ID:
250 case CRL_OBJ_EXTN_ID:
251 extnID = object;
252 break;
253 case CRL_OBJ_CRL_ENTRY_CRITICAL:
254 case CRL_OBJ_CRITICAL:
255 critical = object.len && *object.ptr;
256 DBG2(" %s", critical ? "TRUE" : "FALSE");
257 break;
258 case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
259 case CRL_OBJ_EXTN_VALUE:
260 {
261 int extn_oid = known_oid(extnID);
262
263 if (revoked && extn_oid == OID_CRL_REASON_CODE)
264 {
265 if (*object.ptr == ASN1_ENUMERATED &&
266 asn1_length(&object) == 1)
267 {
268 revoked->reason = *object.ptr;
269 }
270 DBG2(" '%N'", crl_reason_names, revoked->reason);
271 }
272 else if (extn_oid == OID_AUTHORITY_KEY_ID)
273 {
274
275 this->authKeyIdentifier = x509_parse_authorityKeyIdentifier(object,
276 level, &this->authKeySerialNumber);
277 }
278 else if (extn_oid == OID_CRL_NUMBER)
279 {
280 if (!parse_asn1_simple_object(&object, ASN1_INTEGER,
281 level, "crlNumber"))
282 {
283 return FALSE;
284 }
285 this->crlNumber = object;
286 }
287 }
288 break;
289 case CRL_OBJ_ALGORITHM:
290 {
291 this->algorithm = parse_algorithmIdentifier(object, level, NULL);
292 if (this->algorithm != sig_alg)
293 {
294 DBG1(" signature algorithms do not agree");
295 return FALSE;
296 }
297 break;
298 }
299 case CRL_OBJ_SIGNATURE:
300 this->signature = object;
301 break;
302 default:
303 break;
304 }
305 objectID++;
306 }
307 return TRUE;
308 }
309
310 /**
311 * enumerator filter callback for create_enumerator
312 */
313 static bool filter(void *data, revoked_t **revoked, chunk_t *serial, void *p2,
314 time_t *date, void *p3, crl_reason_t *reason)
315 {
316 if (serial)
317 {
318 *serial = (*revoked)->serial;
319 }
320 if (date)
321 {
322 *date = (*revoked)->date;
323 }
324 if (reason)
325 {
326 *reason = (*revoked)->reason;
327 }
328 return TRUE;
329 }
330
331 /**
332 * Implementation of crl_t.get_serial.
333 */
334 static chunk_t get_serial(private_x509_crl_t *this)
335 {
336 return this->crlNumber;
337 }
338
339 /**
340 * Implementation of crl_t.get_authKeyIdentifier.
341 */
342 static identification_t* get_authKeyIdentifier(private_x509_crl_t *this)
343 {
344 return this->authKeyIdentifier;
345 }
346 /**
347 * Implementation of crl_t.create_enumerator.
348 */
349 static enumerator_t* create_enumerator(private_x509_crl_t *this)
350 {
351 return enumerator_create_filter(
352 this->revoked->create_enumerator(this->revoked),
353 (void*)filter, NULL, NULL);
354 }
355
356 /**
357 * Implementation of certificate_t.get_type
358 */
359 static certificate_type_t get_type(private_x509_crl_t *this)
360 {
361 return CERT_X509_CRL;
362 }
363
364 /**
365 * Implementation of certificate_t.get_issuer and get_subject
366 */
367 static identification_t* get_issuer(private_x509_crl_t *this)
368 {
369 return this->issuer;
370 }
371
372 /**
373 * Implementation of certificate_t.has_subject and has_issuer.
374 */
375 static id_match_t has_issuer(private_x509_crl_t *this, identification_t *issuer)
376 {
377 id_match_t match;
378
379 if (issuer->get_type(issuer) == ID_PUBKEY_SHA1)
380 {
381 if (this->authKeyIdentifier)
382 {
383 match = issuer->matches(issuer, this->authKeyIdentifier);
384 }
385 else
386 {
387 match = ID_MATCH_NONE;
388 }
389 }
390 else
391 {
392 match = this->issuer->matches(this->issuer, issuer);
393 }
394 return match;
395 }
396
397 /**
398 * Implementation of certificate_t.issued_by
399 */
400 static bool issued_by(private_x509_crl_t *this, certificate_t *issuer)
401 {
402 public_key_t *key;
403 signature_scheme_t scheme;
404 bool valid;
405 x509_t *x509 = (x509_t*)issuer;
406
407 /* check if issuer is an X.509 CA certificate */
408 if (issuer->get_type(issuer) != CERT_X509)
409 {
410 return FALSE;
411 }
412 if (!(x509->get_flags(x509) & X509_CA))
413 {
414 return FALSE;
415 }
416
417 /* get the public key of the issuer */
418 key = issuer->get_public_key(issuer);
419
420 /* compare keyIdentifiers if available, otherwise use DNs */
421 if (this->authKeyIdentifier && key)
422 {
423 identification_t *subjectKeyIdentifier = key->get_id(key, ID_PUBKEY_SHA1);
424
425 if (!subjectKeyIdentifier->equals(subjectKeyIdentifier,
426 this->authKeyIdentifier))
427 {
428 return FALSE;
429 }
430 }
431 else
432 {
433 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
434 {
435 return FALSE;
436 }
437 }
438 /* TODO: generic OID to scheme mapper? */
439 switch (this->algorithm)
440 {
441 case OID_MD5_WITH_RSA:
442 scheme = SIGN_RSA_EMSA_PKCS1_MD5;
443 break;
444 case OID_SHA1_WITH_RSA:
445 scheme = SIGN_RSA_EMSA_PKCS1_SHA1;
446 break;
447 case OID_SHA256_WITH_RSA:
448 scheme = SIGN_RSA_EMSA_PKCS1_SHA256;
449 break;
450 case OID_SHA384_WITH_RSA:
451 scheme = SIGN_RSA_EMSA_PKCS1_SHA384;
452 break;
453 case OID_SHA512_WITH_RSA:
454 scheme = SIGN_RSA_EMSA_PKCS1_SHA512;
455 break;
456 default:
457 return FALSE;
458 }
459 if (key == NULL)
460 {
461 return FALSE;
462 }
463 valid = key->verify(key, scheme, this->tbsCertList, this->signature);
464 key->destroy(key);
465 return valid;
466 }
467
468 /**
469 * Implementation of certificate_t.get_public_key
470 */
471 static public_key_t* get_public_key(private_x509_crl_t *this)
472 {
473 return NULL;
474 }
475
476 /**
477 * Implementation of certificate_t.asdf
478 */
479 static private_x509_crl_t* get_ref(private_x509_crl_t *this)
480 {
481 ref_get(&this->ref);
482 return this;
483 }
484
485 /**
486 * Implementation of certificate_t.get_validity.
487 */
488 static bool get_validity(private_x509_crl_t *this, time_t *when,
489 time_t *not_before, time_t *not_after)
490 {
491 time_t t;
492
493 if (when)
494 {
495 t = *when;
496 }
497 else
498 {
499 t = time(NULL);
500 }
501 if (not_before)
502 {
503 *not_before = this->thisUpdate;
504 }
505 if (not_after)
506 {
507 *not_after = this->nextUpdate;
508 }
509 return (t <= this->nextUpdate);
510 }
511
512 /**
513 * Implementation of certificate_t.is_newer.
514 */
515 static bool is_newer(private_x509_crl_t *this, crl_t *that)
516 {
517 chunk_t that_crlNumber = that->get_serial(that);
518 bool new;
519
520 /* compare crlNumbers if available - otherwise use thisUpdate */
521 if (this->crlNumber.ptr != NULL && that_crlNumber.ptr != NULL)
522 {
523 new = chunk_compare(this->crlNumber, that_crlNumber) > 0;
524 DBG1(" crl #%#B is %s - existing crl #%#B %s",
525 &this->crlNumber, new ? "newer":"not newer",
526 &that_crlNumber, new ? "replaced":"retained");
527 }
528 else
529 {
530 certificate_t *this_cert = &this->public.crl.certificate;
531 certificate_t *that_cert = &that->certificate;
532
533 time_t this_update, that_update, now = time(NULL);
534
535 this_cert->get_validity(this_cert, &now, &this_update, NULL);
536 that_cert->get_validity(that_cert, &now, &that_update, NULL);
537 new = this_update > that_update;
538 DBG1(" crl from %#T is %s - existing crl from %#T %s",
539 &this_update, FALSE, new ? "newer":"not newer",
540 &that_update, FALSE, new ? "replaced":"retained");
541 }
542 return new;
543 }
544
545 /**
546 * Implementation of certificate_t.get_encoding.
547 */
548 static chunk_t get_encoding(private_x509_crl_t *this)
549 {
550 return chunk_clone(this->encoding);
551 }
552
553 /**
554 * Implementation of certificate_t.equals.
555 */
556 static bool equals(private_x509_crl_t *this, certificate_t *other)
557 {
558 if ((certificate_t*)this == other)
559 {
560 return TRUE;
561 }
562 if (other->equals == (void*)equals)
563 { /* same implementation */
564 return chunk_equals(this->signature,
565 ((private_x509_crl_t*)other)->signature);
566 }
567 /* TODO: compare against other implementations */
568 return FALSE;
569 }
570
571 /**
572 * Implementation of certificate_t.destroy
573 */
574 static void destroy(private_x509_crl_t *this)
575 {
576 if (ref_put(&this->ref))
577 {
578 this->revoked->destroy_function(this->revoked, free);
579 DESTROY_IF(this->issuer);
580 DESTROY_IF(this->authKeyIdentifier);
581 free(this->encoding.ptr);
582 free(this);
583 }
584 }
585
586 /**
587 * create an empty but initialized X.509 crl
588 */
589 static private_x509_crl_t* create_empty(void)
590 {
591 private_x509_crl_t *this = malloc_thing(private_x509_crl_t);
592
593 this->public.crl.get_serial = (chunk_t (*)(crl_t*))get_serial;
594 this->public.crl.get_authKeyIdentifier = (identification_t* (*)(crl_t*))get_authKeyIdentifier;
595 this->public.crl.create_enumerator = (enumerator_t* (*)(crl_t*))create_enumerator;
596 this->public.crl.certificate.get_type = (certificate_type_t (*)(certificate_t *this))get_type;
597 this->public.crl.certificate.get_subject = (identification_t* (*)(certificate_t *this))get_issuer;
598 this->public.crl.certificate.get_issuer = (identification_t* (*)(certificate_t *this))get_issuer;
599 this->public.crl.certificate.has_subject = (id_match_t (*)(certificate_t*, identification_t *subject))has_issuer;
600 this->public.crl.certificate.has_issuer = (id_match_t (*)(certificate_t*, identification_t *issuer))has_issuer;
601 this->public.crl.certificate.issued_by = (bool (*)(certificate_t *this, certificate_t *issuer))issued_by;
602 this->public.crl.certificate.get_public_key = (public_key_t* (*)(certificate_t *this))get_public_key;
603 this->public.crl.certificate.get_validity = (bool (*)(certificate_t*, time_t *when, time_t *, time_t*))get_validity;
604 this->public.crl.certificate.is_newer = (bool (*)(certificate_t*,certificate_t*))is_newer;
605 this->public.crl.certificate.get_encoding = (chunk_t (*)(certificate_t*))get_encoding;
606 this->public.crl.certificate.equals = (bool (*)(certificate_t*, certificate_t *other))equals;
607 this->public.crl.certificate.get_ref = (certificate_t* (*)(certificate_t *this))get_ref;
608 this->public.crl.certificate.destroy = (void (*)(certificate_t *this))destroy;
609
610 this->encoding = chunk_empty;
611 this->tbsCertList = chunk_empty;
612 this->issuer = NULL;
613 this->crlNumber = chunk_empty;
614 this->revoked = linked_list_create();
615 this->authKeyIdentifier = NULL;
616 this->authKeySerialNumber = chunk_empty;
617 this->ref = 1;
618
619 return this;
620 }
621
622 /**
623 * create an X.509 crl from a chunk
624 */
625 static private_x509_crl_t* create_from_chunk(chunk_t chunk)
626 {
627 private_x509_crl_t *this = create_empty();
628
629 this->encoding = chunk;
630 if (!parse(this))
631 {
632 destroy(this);
633 return NULL;
634 }
635 return this;
636 }
637
638 /**
639 * create an X.509 crl from a file
640 */
641 static private_x509_crl_t* create_from_file(char *path)
642 {
643 bool pgp = FALSE;
644 chunk_t chunk;
645 private_x509_crl_t *this;
646
647 if (!pem_asn1_load_file(path, NULL, &chunk, &pgp))
648 {
649 return NULL;
650 }
651
652 this = create_from_chunk(chunk);
653
654 if (this == NULL)
655 {
656 DBG1(" could not parse loaded crl file '%s'",path);
657 return NULL;
658 }
659 DBG1(" loaded crl file '%s'", path);
660 return this;
661 }
662
663 typedef struct private_builder_t private_builder_t;
664 /**
665 * Builder implementation for certificate loading
666 */
667 struct private_builder_t {
668 /** implements the builder interface */
669 builder_t public;
670 /** loaded CRL */
671 private_x509_crl_t *crl;
672 };
673
674 /**
675 * Implementation of builder_t.build
676 */
677 static private_x509_crl_t *build(private_builder_t *this)
678 {
679 private_x509_crl_t *crl = this->crl;
680
681 free(this);
682 return crl;
683 }
684
685 /**
686 * Implementation of builder_t.add
687 */
688 static void add(private_builder_t *this, builder_part_t part, ...)
689 {
690 va_list args;
691
692 if (this->crl)
693 {
694 DBG1("ignoring surplus build part %N", builder_part_names, part);
695 return;
696 }
697
698 va_start(args, part);
699 switch (part)
700 {
701 case BUILD_FROM_FILE:
702 this->crl = create_from_file(va_arg(args, char*));
703 break;
704 case BUILD_BLOB_ASN1_DER:
705 {
706 this->crl = create_from_chunk(va_arg(args, chunk_t));
707 break;
708 }
709 default:
710 DBG1("ignoring unsupported build part %N", builder_part_names, part);
711 break;
712 }
713 va_end(args);
714 }
715
716 /**
717 * Builder construction function
718 */
719 builder_t *x509_crl_builder(certificate_type_t type)
720 {
721 private_builder_t *this;
722
723 if (type != CERT_X509_CRL)
724 {
725 return NULL;
726 }
727
728 this = malloc_thing(private_builder_t);
729
730 this->crl = NULL;
731 this->public.add = (void(*)(builder_t *this, builder_part_t part, ...))add;
732 this->public.build = (void*(*)(builder_t *this))build;
733
734 return &this->public;
735 }
736