88f7a67c20c7bb2393747e40a1432c98b4b3f5a2
[strongswan.git] / src / libstrongswan / plugins / openssl / openssl_crl.c
1 /*
2 * Copyright (C) 2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
5 * Copyright (C) 2010 Martin Willi
6 * Copyright (C) 2010 revosec AG
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 /*
20 * Copyright (C) 2010 secunet Security Networks AG
21 * Copyright (C) 2010 Thomas Egerer
22 *
23 * Permission is hereby granted, free of charge, to any person obtaining a copy
24 * of this software and associated documentation files (the "Software"), to deal
25 * in the Software without restriction, including without limitation the rights
26 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 * copies of the Software, and to permit persons to whom the Software is
28 * furnished to do so, subject to the following conditions:
29 *
30 * The above copyright notice and this permission notice shall be included in
31 * all copies or substantial portions of the Software.
32 *
33 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
39 * THE SOFTWARE.
40 */
41
42 #include "openssl_crl.h"
43 #include "openssl_util.h"
44
45 #include <openssl/x509.h>
46 #include <openssl/x509v3.h>
47
48 #include <utils/debug.h>
49 #include <collections/enumerator.h>
50 #include <credentials/certificates/x509.h>
51
52 #if OPENSSL_VERSION_NUMBER < 0x10100000L
53 static inline void X509_CRL_get0_signature(const X509_CRL *crl, ASN1_BIT_STRING **psig, X509_ALGOR **palg) {
54 if (psig) { *psig = crl->signature; }
55 if (palg) { *palg = crl->sig_alg; }
56 }
57 #define X509_REVOKED_get0_serialNumber(r) ({ (r)->serialNumber; })
58 #define X509_REVOKED_get0_revocationDate(r) ({ (r)->revocationDate; })
59 #define X509_CRL_get0_extensions(c) ({ (c)->crl->extensions; })
60 #endif
61
62 typedef struct private_openssl_crl_t private_openssl_crl_t;
63
64 /**
65 * Private data of an openssl_crl_t object.
66 */
67 struct private_openssl_crl_t {
68
69 /**
70 * Public openssl_crl_t interface.
71 */
72 openssl_crl_t public;
73
74 /**
75 * OpenSSL representation of a CRL
76 */
77 X509_CRL *crl;
78
79 /**
80 * DER encoding of the CRL
81 */
82 chunk_t encoding;
83
84 /**
85 * Serial Number (crlNumber) of the CRL)
86 */
87 chunk_t serial;
88
89 /**
90 * Number of base CRL (deltaCrlIndicator), if a delta CRL
91 */
92 chunk_t base;
93
94 /**
95 * List of Freshest CRL distribution points
96 */
97 linked_list_t *crl_uris;
98
99 /**
100 * AuthorityKeyIdentifier of the issuing CA
101 */
102 chunk_t authKeyIdentifier;
103
104 /**
105 * Date of this CRL
106 */
107 time_t thisUpdate;
108
109 /**
110 * Date of next CRL expected
111 */
112 time_t nextUpdate;
113
114 /**
115 * Issuer of this CRL
116 */
117 identification_t *issuer;
118
119 /**
120 * Signature scheme used in this CRL
121 */
122 signature_params_t *scheme;
123
124 /**
125 * References to this CRL
126 */
127 refcount_t ref;
128 };
129
130 /**
131 * Enumerator over revoked certificates
132 */
133 typedef struct {
134 /**
135 * Implements enumerator_t
136 */
137 enumerator_t public;
138
139 /**
140 * stack of revoked certificates
141 */
142 STACK_OF(X509_REVOKED) *stack;
143
144 /**
145 * Total number of revoked certificates
146 */
147 int num;
148
149 /**
150 * Current position of enumerator
151 */
152 int i;
153 } crl_enumerator_t;
154
155 /**
156 * from openssl_x509
157 */
158 bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
159 linked_list_t *list);
160
161 METHOD(enumerator_t, crl_enumerate, bool,
162 crl_enumerator_t *this, va_list args)
163 {
164 crl_reason_t *reason;
165 chunk_t *serial;
166 time_t *date;
167
168 VA_ARGS_VGET(args, serial, date, reason);
169
170 if (this->i < this->num)
171 {
172 X509_REVOKED *revoked;
173 ASN1_ENUMERATED *crlrsn;
174
175 revoked = sk_X509_REVOKED_value(this->stack, this->i);
176 if (serial)
177 {
178 *serial = openssl_asn1_str2chunk(
179 X509_REVOKED_get0_serialNumber(revoked));
180 }
181 if (date)
182 {
183 *date = openssl_asn1_to_time(
184 X509_REVOKED_get0_revocationDate(revoked));
185 }
186 if (reason)
187 {
188 *reason = CRL_REASON_UNSPECIFIED;
189 crlrsn = X509_REVOKED_get_ext_d2i(revoked, NID_crl_reason,
190 NULL, NULL);
191 if (crlrsn)
192 {
193 if (ASN1_STRING_type(crlrsn) == V_ASN1_ENUMERATED &&
194 ASN1_STRING_length(crlrsn) == 1)
195 {
196 *reason = *ASN1_STRING_data(crlrsn);
197 }
198 ASN1_STRING_free(crlrsn);
199 }
200 }
201 this->i++;
202 return TRUE;
203 }
204 return FALSE;
205 }
206
207 METHOD(crl_t, create_enumerator, enumerator_t*,
208 private_openssl_crl_t *this)
209 {
210 crl_enumerator_t *enumerator;
211
212 INIT(enumerator,
213 .public = {
214 .enumerate = enumerator_enumerate_default,
215 .venumerate = _crl_enumerate,
216 .destroy = (void*)free,
217 },
218 .stack = X509_CRL_get_REVOKED(this->crl),
219 );
220 if (!enumerator->stack)
221 {
222 free(enumerator);
223 return enumerator_create_empty();
224 }
225 enumerator->num = sk_X509_REVOKED_num(enumerator->stack);
226 return &enumerator->public;
227 }
228
229 METHOD(crl_t, get_serial, chunk_t,
230 private_openssl_crl_t *this)
231 {
232 return this->serial;
233 }
234
235 METHOD(crl_t, is_delta_crl, bool,
236 private_openssl_crl_t *this, chunk_t *base_crl)
237 {
238 if (this->base.len)
239 {
240 if (base_crl)
241 {
242 *base_crl = this->base;
243 }
244 return TRUE;
245 }
246 return FALSE;
247 }
248
249 METHOD(crl_t, create_delta_crl_uri_enumerator, enumerator_t*,
250 private_openssl_crl_t *this)
251 {
252 return this->crl_uris->create_enumerator(this->crl_uris);
253 }
254
255 METHOD(crl_t, get_authKeyIdentifier, chunk_t,
256 private_openssl_crl_t *this)
257 {
258 return this->authKeyIdentifier;
259 }
260
261 METHOD(certificate_t, get_type, certificate_type_t,
262 private_openssl_crl_t *this)
263 {
264 return CERT_X509_CRL;
265 }
266
267 METHOD(certificate_t, get_subject_or_issuer, identification_t*,
268 private_openssl_crl_t *this)
269 {
270 return this->issuer;
271 }
272
273 METHOD(certificate_t, has_subject_or_issuer, id_match_t,
274 private_openssl_crl_t *this, identification_t *id)
275 {
276 if (id->get_type(id) == ID_KEY_ID &&
277 chunk_equals(this->authKeyIdentifier, id->get_encoding(id)))
278 {
279 return ID_MATCH_PERFECT;
280 }
281 return this->issuer->matches(this->issuer, id);
282 }
283
284 METHOD(certificate_t, issued_by, bool,
285 private_openssl_crl_t *this, certificate_t *issuer,
286 signature_params_t **scheme)
287 {
288 chunk_t fingerprint, tbs;
289 public_key_t *key;
290 x509_t *x509;
291 ASN1_BIT_STRING *sig;
292 bool valid;
293
294 if (issuer->get_type(issuer) != CERT_X509)
295 {
296 return FALSE;
297 }
298 x509 = (x509_t*)issuer;
299 if (!(x509->get_flags(x509) & X509_CA))
300 {
301 return FALSE;
302 }
303 key = issuer->get_public_key(issuer);
304 if (!key)
305 {
306 return FALSE;
307 }
308 if (this->authKeyIdentifier.ptr && key)
309 {
310 if (!key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fingerprint) ||
311 !chunk_equals(fingerprint, this->authKeyIdentifier))
312 {
313 return FALSE;
314 }
315 }
316 else
317 {
318 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
319 {
320 return FALSE;
321 }
322 }
323 /* i2d_re_X509_CRL_tbs() was added with 1.1.0 when X509_CRL became opaque */
324 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
325 tbs = openssl_i2chunk(re_X509_CRL_tbs, this->crl);
326 #else
327 tbs = openssl_i2chunk(X509_CRL_INFO, this->crl->crl);
328 #endif
329 X509_CRL_get0_signature(this->crl, &sig, NULL);
330 valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
331 openssl_asn1_str2chunk(sig));
332 free(tbs.ptr);
333 key->destroy(key);
334 if (valid && scheme)
335 {
336 *scheme = signature_params_clone(this->scheme);
337 }
338 return valid;
339 }
340
341 METHOD(certificate_t, get_public_key, public_key_t*,
342 private_openssl_crl_t *this)
343 {
344 return NULL;
345 }
346
347 METHOD(certificate_t, get_validity, bool,
348 private_openssl_crl_t *this,
349 time_t *when, time_t *not_before, time_t *not_after)
350 {
351 time_t t = when ? *when : time(NULL);
352
353 if (not_before)
354 {
355 *not_before = this->thisUpdate;
356 }
357 if (not_after)
358 {
359 *not_after = this->nextUpdate;
360 }
361 return t <= this->nextUpdate;
362 }
363
364 METHOD(certificate_t, get_encoding, bool,
365 private_openssl_crl_t *this, cred_encoding_type_t type, chunk_t *encoding)
366 {
367 if (type == CERT_ASN1_DER)
368 {
369 *encoding = chunk_clone(this->encoding);
370 return TRUE;
371 }
372 return lib->encoding->encode(lib->encoding, type, NULL, encoding,
373 CRED_PART_X509_CRL_ASN1_DER, this->encoding, CRED_PART_END);
374 }
375
376 METHOD(certificate_t, equals, bool,
377 private_openssl_crl_t *this, certificate_t *other)
378 {
379 chunk_t encoding;
380 bool equal;
381
382 if (&this->public.crl.certificate == other)
383 {
384 return TRUE;
385 }
386 if (other->equals == (void*)equals)
387 { /* skip allocation if we have the same implementation */
388 return chunk_equals(this->encoding,
389 ((private_openssl_crl_t*)other)->encoding);
390 }
391 if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
392 {
393 return FALSE;
394 }
395 equal = chunk_equals(this->encoding, encoding);
396 free(encoding.ptr);
397 return equal;
398 }
399
400 METHOD(certificate_t, get_ref, certificate_t*,
401 private_openssl_crl_t *this)
402 {
403 ref_get(&this->ref);
404 return &this->public.crl.certificate;
405 }
406
407 METHOD(certificate_t, destroy, void,
408 private_openssl_crl_t *this)
409 {
410 if (ref_put(&this->ref))
411 {
412 if (this->crl)
413 {
414 X509_CRL_free(this->crl);
415 }
416 signature_params_destroy(this->scheme);
417 this->crl_uris->destroy_function(this->crl_uris,
418 (void*)x509_cdp_destroy);
419 DESTROY_IF(this->issuer);
420 free(this->authKeyIdentifier.ptr);
421 free(this->base.ptr);
422 free(this->serial.ptr);
423 free(this->encoding.ptr);
424 free(this);
425 }
426 }
427
428 /**
429 * Create an empty CRL.
430 */
431 static private_openssl_crl_t *create_empty()
432 {
433 private_openssl_crl_t *this;
434
435 INIT(this,
436 .public = {
437 .crl = {
438 .certificate = {
439 .get_type = _get_type,
440 .get_subject = _get_subject_or_issuer,
441 .get_issuer = _get_subject_or_issuer,
442 .has_subject = _has_subject_or_issuer,
443 .has_issuer = _has_subject_or_issuer,
444 .issued_by = _issued_by,
445 .get_public_key = _get_public_key,
446 .get_validity = _get_validity,
447 .get_encoding = _get_encoding,
448 .equals = _equals,
449 .get_ref = _get_ref,
450 .destroy = _destroy,
451 },
452 .get_serial = _get_serial,
453 .get_authKeyIdentifier = _get_authKeyIdentifier,
454 .is_delta_crl = _is_delta_crl,
455 .create_delta_crl_uri_enumerator = _create_delta_crl_uri_enumerator,
456 .create_enumerator = _create_enumerator,
457 },
458 },
459 .crl_uris = linked_list_create(),
460 .ref = 1,
461 );
462 return this;
463 }
464
465 /**
466 * Parse the authKeyIdentifier extension
467 */
468 static bool parse_authKeyIdentifier_ext(private_openssl_crl_t *this,
469 X509_EXTENSION *ext)
470 {
471 AUTHORITY_KEYID *keyid;
472
473 keyid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext);
474 if (keyid)
475 {
476 free(this->authKeyIdentifier.ptr);
477 this->authKeyIdentifier = chunk_clone(
478 openssl_asn1_str2chunk(keyid->keyid));
479 AUTHORITY_KEYID_free(keyid);
480 return TRUE;
481 }
482 return FALSE;
483 }
484
485 /**
486 * Quick and dirty INTEGER unwrap for crlNumber/deltaCrlIndicator extensions
487 */
488 static bool parse_integer_ext(X509_EXTENSION *ext, chunk_t *out)
489 {
490 chunk_t chunk;
491
492 chunk = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
493 if (chunk.len > 1 && chunk.ptr[0] == V_ASN1_INTEGER &&
494 chunk.ptr[1] == chunk.len - 2)
495 {
496 chunk = chunk_skip(chunk, 2);
497 free(out->ptr);
498 *out = chunk_clone(chunk);
499 return TRUE;
500 }
501 return FALSE;
502 }
503
504 /**
505 * Parse X509 CRL extensions
506 */
507 static bool parse_extensions(private_openssl_crl_t *this)
508 {
509 bool ok;
510 int i, num;
511 X509_EXTENSION *ext;
512 STACK_OF(X509_EXTENSION) *extensions;
513
514 extensions = X509_CRL_get0_extensions(this->crl);
515 if (extensions)
516 {
517 num = sk_X509_EXTENSION_num(extensions);
518 for (i = 0; i < num; ++i)
519 {
520 ext = sk_X509_EXTENSION_value(extensions, i);
521
522 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
523 {
524 case NID_authority_key_identifier:
525 ok = parse_authKeyIdentifier_ext(this, ext);
526 break;
527 case NID_crl_number:
528 ok = parse_integer_ext(ext, &this->serial);
529 break;
530 case NID_delta_crl:
531 ok = parse_integer_ext(ext, &this->base);
532 break;
533 case NID_freshest_crl:
534 ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
535 break;
536 case NID_issuing_distribution_point:
537 /* TODO support of IssuingDistributionPoints */
538 ok = TRUE;
539 break;
540 default:
541 ok = X509_EXTENSION_get_critical(ext) == 0 ||
542 !lib->settings->get_bool(lib->settings,
543 "%s.x509.enforce_critical", TRUE, lib->ns);
544 if (!ok)
545 {
546 DBG1(DBG_LIB, "found unsupported critical X.509 "
547 "CRL extension");
548 }
549 break;
550 }
551 if (!ok)
552 {
553 return FALSE;
554 }
555 }
556 }
557 return TRUE;
558 }
559
560 /**
561 * Parse a X509 CRL
562 */
563 static bool parse_crl(private_openssl_crl_t *this)
564 {
565 const unsigned char *ptr = this->encoding.ptr;
566 chunk_t sig_scheme;
567 X509_ALGOR *alg;
568
569 this->crl = d2i_X509_CRL(NULL, &ptr, this->encoding.len);
570 if (!this->crl)
571 {
572 return FALSE;
573 }
574
575 X509_CRL_get0_signature(this->crl, NULL, &alg);
576 sig_scheme = openssl_i2chunk(X509_ALGOR, alg);
577 INIT(this->scheme);
578 if (!signature_params_parse(sig_scheme, 0, this->scheme))
579 {
580 DBG1(DBG_ASN, "unable to parse signature algorithm");
581 free(sig_scheme.ptr);
582 return FALSE;
583 }
584 free(sig_scheme.ptr);
585
586 this->issuer = openssl_x509_name2id(X509_CRL_get_issuer(this->crl));
587 if (!this->issuer)
588 {
589 return FALSE;
590 }
591 this->thisUpdate = openssl_asn1_to_time(X509_CRL_get_lastUpdate(this->crl));
592 this->nextUpdate = openssl_asn1_to_time(X509_CRL_get_nextUpdate(this->crl));
593
594 return parse_extensions(this);
595 }
596
597 /**
598 * Load the CRL.
599 */
600 openssl_crl_t *openssl_crl_load(certificate_type_t type, va_list args)
601 {
602 chunk_t blob = chunk_empty;
603
604 while (TRUE)
605 {
606 switch (va_arg(args, builder_part_t))
607 {
608 case BUILD_BLOB_ASN1_DER:
609 blob = va_arg(args, chunk_t);
610 continue;
611 case BUILD_END:
612 break;
613 default:
614 return NULL;
615 }
616 break;
617 }
618 if (blob.ptr)
619 {
620 private_openssl_crl_t *this = create_empty();
621
622 this->encoding = chunk_clone(blob);
623 if (parse_crl(this))
624 {
625 return &this->public;
626 }
627 destroy(this);
628 }
629 return NULL;
630 }