2 * Copyright (C) 2015-2018 Tobias Brunner
3 * Copyright (C) 2010 Martin Willi
4 * Copyright (C) 2010 revosec AG
5 * Copyright (C) 2009 Andreas Steffen
6 * HSR Hochschule fuer Technik Rapperswil
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>.
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
21 #include "revocation_validator.h"
23 #include <utils/debug.h>
24 #include <credentials/certificates/x509.h>
25 #include <credentials/certificates/crl.h>
26 #include <credentials/certificates/ocsp_request.h>
27 #include <credentials/certificates/ocsp_response.h>
28 #include <credentials/sets/ocsp_response_wrapper.h>
29 #include <selectors/traffic_selector.h>
31 typedef struct private_revocation_validator_t private_revocation_validator_t
;
34 * Private data of an revocation_validator_t object.
36 struct private_revocation_validator_t
{
39 * Public revocation_validator_t interface.
41 revocation_validator_t
public;
44 * Enable OCSP validation
49 * Enable CRL validation
58 static certificate_t
*fetch_ocsp(char *url
, certificate_t
*subject
,
59 certificate_t
*issuer
)
61 certificate_t
*request
, *response
;
62 chunk_t send
, receive
;
64 /* TODO: requestor name, signature */
65 request
= lib
->creds
->create(lib
->creds
,
66 CRED_CERTIFICATE
, CERT_X509_OCSP_REQUEST
,
67 BUILD_CA_CERT
, issuer
,
68 BUILD_CERT
, subject
, BUILD_END
);
71 DBG1(DBG_CFG
, "generating ocsp request failed");
75 if (!request
->get_encoding(request
, CERT_ASN1_DER
, &send
))
77 DBG1(DBG_CFG
, "encoding ocsp request failed");
78 request
->destroy(request
);
81 request
->destroy(request
);
83 DBG1(DBG_CFG
, " requesting ocsp status from '%s' ...", url
);
84 if (lib
->fetcher
->fetch(lib
->fetcher
, url
, &receive
,
85 FETCH_REQUEST_DATA
, send
,
86 FETCH_REQUEST_TYPE
, "application/ocsp-request",
87 FETCH_END
) != SUCCESS
)
89 DBG1(DBG_CFG
, "ocsp request to %s failed", url
);
95 response
= lib
->creds
->create(lib
->creds
,
96 CRED_CERTIFICATE
, CERT_X509_OCSP_RESPONSE
,
97 BUILD_BLOB_ASN1_DER
, receive
, BUILD_END
);
101 DBG1(DBG_CFG
, "parsing ocsp response failed");
108 * check the signature of an OCSP response
110 static bool verify_ocsp(ocsp_response_t
*response
, certificate_t
*ca
)
112 certificate_t
*issuer
, *subject
;
113 identification_t
*responder
;
114 ocsp_response_wrapper_t
*wrapper
;
115 enumerator_t
*enumerator
;
117 bool verified
= FALSE
, found
= FALSE
;
119 wrapper
= ocsp_response_wrapper_create((ocsp_response_t
*)response
);
120 lib
->credmgr
->add_local_set(lib
->credmgr
, &wrapper
->set
, FALSE
);
122 subject
= &response
->certificate
;
123 responder
= subject
->get_issuer(subject
);
125 /* check OCSP response using CA or directly delegated OCSP signer */
126 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
, CERT_X509
,
127 KEY_ANY
, responder
, FALSE
);
128 while (enumerator
->enumerate(enumerator
, &issuer
))
130 x509
= (x509_t
*)issuer
;
131 if (!issuer
->get_validity(issuer
, NULL
, NULL
, NULL
))
132 { /* OCSP signer currently invalid */
135 if (!ca
->equals(ca
, issuer
))
136 { /* delegated OCSP signer? */
137 if (!lib
->credmgr
->issued_by(lib
->credmgr
, issuer
, ca
, NULL
))
138 { /* OCSP response not signed by CA, nor delegated OCSP signer */
141 if (!(x509
->get_flags(x509
) & X509_OCSP_SIGNER
))
142 { /* delegated OCSP signer does not have OCSP signer flag */
147 if (lib
->credmgr
->issued_by(lib
->credmgr
, subject
, issuer
, NULL
))
149 DBG1(DBG_CFG
, " ocsp response correctly signed by \"%Y\"",
150 issuer
->get_subject(issuer
));
154 DBG1(DBG_CFG
, "ocsp response verification failed, "
155 "invalid signature");
157 enumerator
->destroy(enumerator
);
161 /* as fallback, use any locally installed OCSP signer certificate */
162 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
,
163 CERT_X509
, KEY_ANY
, responder
, TRUE
);
164 while (enumerator
->enumerate(enumerator
, &issuer
))
166 x509
= (x509_t
*)issuer
;
167 /* while issued_by() accepts both OCSP signer or CA basic
168 * constraint flags to verify OCSP responses, unrelated but trusted
169 * OCSP signers must explicitly have the OCSP signer flag set. */
170 if ((x509
->get_flags(x509
) & X509_OCSP_SIGNER
) &&
171 issuer
->get_validity(issuer
, NULL
, NULL
, NULL
))
174 if (lib
->credmgr
->issued_by(lib
->credmgr
, subject
, issuer
, NULL
))
176 DBG1(DBG_CFG
, " ocsp response correctly signed by \"%Y\"",
177 issuer
->get_subject(issuer
));
181 DBG1(DBG_CFG
, "ocsp response verification failed, "
182 "invalid signature");
185 enumerator
->destroy(enumerator
);
188 lib
->credmgr
->remove_local_set(lib
->credmgr
, &wrapper
->set
);
189 wrapper
->destroy(wrapper
);
193 DBG1(DBG_CFG
, "ocsp response verification failed, "
194 "no signer certificate '%Y' found", responder
);
200 * Get the better of two OCSP responses, and check for usable OCSP info
202 static certificate_t
*get_better_ocsp(certificate_t
*cand
, certificate_t
*best
,
203 x509_t
*subject
, x509_t
*issuer
,
204 cert_validation_t
*valid
, bool cache
)
206 ocsp_response_t
*response
;
207 time_t revocation
, this_update
, next_update
, valid_until
;
209 bool revoked
= FALSE
;
211 response
= (ocsp_response_t
*)cand
;
213 /* check ocsp signature */
214 if (!verify_ocsp(response
, &issuer
->interface
))
219 /* check if response contains our certificate */
220 switch (response
->get_status(response
, subject
, issuer
, &revocation
, &reason
,
221 &this_update
, &next_update
))
223 case VALIDATION_REVOKED
:
224 /* subject has been revoked by a valid OCSP response */
225 DBG1(DBG_CFG
, "certificate was revoked on %T, reason: %N",
226 &revocation
, TRUE
, crl_reason_names
, reason
);
229 case VALIDATION_GOOD
:
230 /* results in either good or stale */
233 case VALIDATION_FAILED
:
234 /* candidate unusable, does not contain our cert */
235 DBG1(DBG_CFG
, " ocsp response contains no status on our certificate");
240 /* select the better of the two responses */
241 if (best
== NULL
|| certificate_is_newer(cand
, best
))
245 if (best
->get_validity(best
, NULL
, NULL
, &valid_until
))
247 DBG1(DBG_CFG
, " ocsp response is valid: until %T",
248 &valid_until
, FALSE
);
249 *valid
= VALIDATION_GOOD
;
251 { /* cache non-stale only, stale certs get refetched */
252 lib
->credmgr
->cache_cert(lib
->credmgr
, best
);
257 DBG1(DBG_CFG
, " ocsp response is stale: since %T",
258 &valid_until
, FALSE
);
259 *valid
= VALIDATION_STALE
;
264 *valid
= VALIDATION_STALE
;
268 { /* revoked always counts, even if stale */
269 *valid
= VALIDATION_REVOKED
;
275 * validate a x509 certificate using OCSP
277 static cert_validation_t
check_ocsp(x509_t
*subject
, x509_t
*issuer
,
280 enumerator_t
*enumerator
;
281 cert_validation_t valid
= VALIDATION_SKIPPED
;
282 certificate_t
*best
= NULL
, *current
;
283 identification_t
*keyid
= NULL
;
284 public_key_t
*public;
288 /** lookup cache for valid OCSP responses */
289 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
,
290 CERT_X509_OCSP_RESPONSE
, KEY_ANY
, NULL
, FALSE
);
291 while (enumerator
->enumerate(enumerator
, ¤t
))
293 current
->get_ref(current
);
294 best
= get_better_ocsp(current
, best
, subject
, issuer
, &valid
, FALSE
);
295 if (best
&& valid
!= VALIDATION_STALE
)
297 DBG1(DBG_CFG
, " using cached ocsp response");
301 enumerator
->destroy(enumerator
);
303 /* derive the authorityKeyIdentifier from the issuer's public key */
304 current
= &issuer
->interface
;
305 public = current
->get_public_key(current
);
306 if (public && public->get_fingerprint(public, KEYID_PUBKEY_SHA1
, &chunk
))
308 keyid
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
310 /** fetch from configured OCSP responder URLs */
311 if (keyid
&& valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
)
313 enumerator
= lib
->credmgr
->create_cdp_enumerator(lib
->credmgr
,
314 CERT_X509_OCSP_RESPONSE
, keyid
);
315 while (enumerator
->enumerate(enumerator
, &uri
))
317 current
= fetch_ocsp(uri
, &subject
->interface
, &issuer
->interface
);
320 best
= get_better_ocsp(current
, best
, subject
, issuer
,
322 if (best
&& valid
!= VALIDATION_STALE
)
328 enumerator
->destroy(enumerator
);
333 /* fallback to URL fetching from subject certificate's URIs */
334 if (valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
)
336 enumerator
= subject
->create_ocsp_uri_enumerator(subject
);
337 while (enumerator
->enumerate(enumerator
, &uri
))
339 current
= fetch_ocsp(uri
, &subject
->interface
, &issuer
->interface
);
342 best
= get_better_ocsp(current
, best
, subject
, issuer
,
344 if (best
&& valid
!= VALIDATION_STALE
)
350 enumerator
->destroy(enumerator
);
352 /* an uri was found, but no result. switch validation state to failed */
353 if (valid
== VALIDATION_SKIPPED
&& uri
)
355 valid
= VALIDATION_FAILED
;
359 auth
->add(auth
, AUTH_RULE_OCSP_VALIDATION
, valid
);
360 if (valid
== VALIDATION_GOOD
)
361 { /* successful OCSP check fulfills also CRL constraint */
362 auth
->add(auth
, AUTH_RULE_CRL_VALIDATION
, VALIDATION_GOOD
);
370 * fetch a CRL from an URL
372 static certificate_t
* fetch_crl(char *url
)
377 DBG1(DBG_CFG
, " fetching crl from '%s' ...", url
);
378 if (lib
->fetcher
->fetch(lib
->fetcher
, url
, &chunk
, FETCH_END
) != SUCCESS
)
380 DBG1(DBG_CFG
, "crl fetching failed");
383 crl
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, CERT_X509_CRL
,
384 BUILD_BLOB_PEM
, chunk
, BUILD_END
);
388 DBG1(DBG_CFG
, "crl fetched successfully but parsing failed");
395 * check the signature of an CRL
397 static bool verify_crl(certificate_t
*crl
)
399 certificate_t
*issuer
;
400 enumerator_t
*enumerator
;
401 bool verified
= FALSE
;
403 enumerator
= lib
->credmgr
->create_trusted_enumerator(lib
->credmgr
,
404 KEY_ANY
, crl
->get_issuer(crl
), FALSE
);
405 while (enumerator
->enumerate(enumerator
, &issuer
, NULL
))
407 if (lib
->credmgr
->issued_by(lib
->credmgr
, crl
, issuer
, NULL
))
409 DBG1(DBG_CFG
, " crl correctly signed by \"%Y\"",
410 issuer
->get_subject(issuer
));
415 enumerator
->destroy(enumerator
);
421 * Report the given CRL's validity and cache it if valid and requested
423 static bool is_crl_valid(certificate_t
*crl
, time_t now
, bool cache
)
427 if (crl
->get_validity(crl
, &now
, NULL
, &valid_until
))
429 DBG1(DBG_CFG
, " crl is valid: until %T", &valid_until
, FALSE
);
432 lib
->credmgr
->cache_cert(lib
->credmgr
, crl
);
436 DBG1(DBG_CFG
, " crl is stale: since %T", &valid_until
, FALSE
);
441 * Check if the CRL should be used yet
443 static bool is_crl_not_valid_yet(certificate_t
*crl
, time_t now
)
447 if (!crl
->get_validity(crl
, &now
, &this_update
, NULL
))
449 if (this_update
> now
)
451 DBG1(DBG_CFG
, " crl is not valid: until %T", &this_update
, FALSE
);
454 /* we accept stale CRLs */
460 * Get the better of two CRLs, and check for usable CRL info
462 static certificate_t
*get_better_crl(certificate_t
*cand
, certificate_t
*best
,
463 x509_t
*subject
, cert_validation_t
*valid
,
464 bool cache
, crl_t
*base
)
466 enumerator_t
*enumerator
;
467 time_t now
, revocation
;
469 chunk_t subject_serial
, serial
;
470 crl_t
*crl
= (crl_t
*)cand
;
474 if (!crl
->is_delta_crl(crl
, &serial
) ||
475 !chunk_equals(serial
, base
->get_serial(base
)))
483 if (crl
->is_delta_crl(crl
, NULL
))
490 /* check CRL signature */
491 if (!verify_crl(cand
))
493 DBG1(DBG_CFG
, "crl response verification failed");
498 if (is_crl_not_valid_yet(cand
, now
))
504 subject_serial
= chunk_skip_zero(subject
->get_serial(subject
));
505 enumerator
= crl
->create_enumerator(crl
);
506 while (enumerator
->enumerate(enumerator
, &serial
, &revocation
, &reason
))
508 if (chunk_equals(subject_serial
, chunk_skip_zero(serial
)))
510 if (reason
!= CRL_REASON_CERTIFICATE_HOLD
)
512 *valid
= VALIDATION_REVOKED
;
516 /* if the cert is on hold, a newer CRL might not contain it */
517 *valid
= VALIDATION_ON_HOLD
;
519 is_crl_valid(cand
, now
, cache
);
520 DBG1(DBG_CFG
, "certificate was revoked on %T, reason: %N",
521 &revocation
, TRUE
, crl_reason_names
, reason
);
522 enumerator
->destroy(enumerator
);
527 enumerator
->destroy(enumerator
);
529 /* select the better of the two CRLs */
530 if (best
== NULL
|| crl_is_newer(crl
, (crl_t
*)best
))
534 if (is_crl_valid(best
, now
, cache
))
536 *valid
= VALIDATION_GOOD
;
540 *valid
= VALIDATION_STALE
;
545 *valid
= VALIDATION_STALE
;
552 * Find or fetch a certificate for a given crlIssuer
554 static cert_validation_t
find_crl(x509_t
*subject
, identification_t
*issuer
,
555 crl_t
*base
, certificate_t
**best
,
558 cert_validation_t valid
= VALIDATION_SKIPPED
;
559 enumerator_t
*enumerator
;
560 certificate_t
*current
;
563 /* find a cached (delta) crl */
564 enumerator
= lib
->credmgr
->create_cert_enumerator(lib
->credmgr
,
565 CERT_X509_CRL
, KEY_ANY
, issuer
, FALSE
);
566 while (enumerator
->enumerate(enumerator
, ¤t
))
568 current
->get_ref(current
);
569 *best
= get_better_crl(current
, *best
, subject
, &valid
, FALSE
, base
);
570 if (*best
&& valid
!= VALIDATION_STALE
)
572 DBG1(DBG_CFG
, " using cached crl");
576 enumerator
->destroy(enumerator
);
578 /* fallback to fetching crls from credential sets cdps */
579 if (!base
&& valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
)
581 enumerator
= lib
->credmgr
->create_cdp_enumerator(lib
->credmgr
,
582 CERT_X509_CRL
, issuer
);
583 while (enumerator
->enumerate(enumerator
, &uri
))
586 current
= fetch_crl(uri
);
589 if (!current
->has_issuer(current
, issuer
))
591 DBG1(DBG_CFG
, "issuer of fetched CRL '%Y' does not match CRL "
592 "issuer '%Y'", current
->get_issuer(current
), issuer
);
593 current
->destroy(current
);
596 *best
= get_better_crl(current
, *best
, subject
,
598 if (*best
&& valid
!= VALIDATION_STALE
)
604 enumerator
->destroy(enumerator
);
610 * Check if the issuer of the given CRL matches
612 static bool check_issuer(certificate_t
*crl
, x509_t
*issuer
, x509_cdp_t
*cdp
)
614 certificate_t
*cissuer
= (certificate_t
*)issuer
;
615 identification_t
*id
;
617 bool matches
= FALSE
;
621 return crl
->has_issuer(crl
, cdp
->issuer
);
623 /* check SKI/AKI first, but fall back to DN matching */
624 chunk
= issuer
->get_subjectKeyIdentifier(issuer
);
627 id
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
628 matches
= crl
->has_issuer(crl
, id
);
631 return matches
|| crl
->has_issuer(crl
, cissuer
->get_subject(cissuer
));
635 * Look for a delta CRL for a given base CRL
637 static cert_validation_t
check_delta_crl(x509_t
*subject
, x509_t
*issuer
,
638 crl_t
*base
, cert_validation_t base_valid
)
640 cert_validation_t valid
= VALIDATION_SKIPPED
;
641 certificate_t
*best
= NULL
, *current
, *cissuer
= (certificate_t
*)issuer
;
642 enumerator_t
*enumerator
;
643 identification_t
*id
;
648 /* find cached delta CRL via subjectKeyIdentifier */
649 chunk
= issuer
->get_subjectKeyIdentifier(issuer
);
652 id
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
653 valid
= find_crl(subject
, id
, base
, &best
, &uri
);
657 /* find delta CRL by CRLIssuer */
658 enumerator
= subject
->create_crl_uri_enumerator(subject
);
659 while (valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
&&
660 enumerator
->enumerate(enumerator
, &cdp
))
664 valid
= find_crl(subject
, cdp
->issuer
, base
, &best
, &uri
);
667 enumerator
->destroy(enumerator
);
669 /* fetch from URIs found in Freshest CRL extension */
670 enumerator
= base
->create_delta_crl_uri_enumerator(base
);
671 while (valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
&&
672 enumerator
->enumerate(enumerator
, &cdp
))
674 current
= fetch_crl(cdp
->uri
);
677 if (!check_issuer(current
, issuer
, cdp
))
679 DBG1(DBG_CFG
, "issuer of fetched delta CRL '%Y' does not match "
680 "certificate's %sissuer '%Y'",
681 current
->get_issuer(current
), cdp
->issuer
? "CRL " : "",
682 cdp
->issuer
?: cissuer
->get_subject(cissuer
));
683 current
->destroy(current
);
686 best
= get_better_crl(current
, best
, subject
, &valid
, TRUE
, base
);
687 if (best
&& valid
!= VALIDATION_STALE
)
693 enumerator
->destroy(enumerator
);
704 * validate a x509 certificate using CRL
706 static cert_validation_t
check_crl(x509_t
*subject
, x509_t
*issuer
,
709 cert_validation_t valid
= VALIDATION_SKIPPED
;
710 certificate_t
*best
= NULL
, *cissuer
= (certificate_t
*)issuer
;
711 identification_t
*id
;
713 bool uri_found
= FALSE
;
714 certificate_t
*current
;
715 enumerator_t
*enumerator
;
718 /* use issuers subjectKeyIdentifier to find a cached CRL / fetch from CDP */
719 chunk
= issuer
->get_subjectKeyIdentifier(issuer
);
722 id
= identification_create_from_encoding(ID_KEY_ID
, chunk
);
723 valid
= find_crl(subject
, id
, NULL
, &best
, &uri_found
);
727 /* find a cached CRL or fetch via configured CDP via CRLIssuer */
728 enumerator
= subject
->create_crl_uri_enumerator(subject
);
729 while (valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
&&
730 enumerator
->enumerate(enumerator
, &cdp
))
734 valid
= find_crl(subject
, cdp
->issuer
, NULL
, &best
, &uri_found
);
737 enumerator
->destroy(enumerator
);
739 /* fallback to fetching CRLs from CDPs found in subjects certificate */
740 if (valid
!= VALIDATION_GOOD
&& valid
!= VALIDATION_REVOKED
)
742 enumerator
= subject
->create_crl_uri_enumerator(subject
);
743 while (enumerator
->enumerate(enumerator
, &cdp
))
746 current
= fetch_crl(cdp
->uri
);
749 if (!check_issuer(current
, issuer
, cdp
))
751 DBG1(DBG_CFG
, "issuer of fetched CRL '%Y' does not match "
752 "certificate's %sissuer '%Y'",
753 current
->get_issuer(current
), cdp
->issuer
? "CRL " : "",
754 cdp
->issuer
?: cissuer
->get_subject(cissuer
));
755 current
->destroy(current
);
758 best
= get_better_crl(current
, best
, subject
, &valid
,
760 if (best
&& valid
!= VALIDATION_STALE
)
766 enumerator
->destroy(enumerator
);
769 /* look for delta CRLs */
770 if (best
&& (valid
== VALIDATION_GOOD
|| valid
== VALIDATION_STALE
))
772 valid
= check_delta_crl(subject
, issuer
, (crl_t
*)best
, valid
);
775 /* an uri was found, but no result. switch validation state to failed */
776 if (valid
== VALIDATION_SKIPPED
&& uri_found
)
778 valid
= VALIDATION_FAILED
;
782 if (valid
== VALIDATION_SKIPPED
)
783 { /* if we skipped CRL validation, we use the result of OCSP for
784 * constraint checking */
785 auth
->add(auth
, AUTH_RULE_CRL_VALIDATION
,
786 auth
->get(auth
, AUTH_RULE_OCSP_VALIDATION
));
790 auth
->add(auth
, AUTH_RULE_CRL_VALIDATION
, valid
);
797 METHOD(cert_validator_t
, validate
, bool,
798 private_revocation_validator_t
*this, certificate_t
*subject
,
799 certificate_t
*issuer
, bool online
, u_int pathlen
, bool anchor
,
802 if (online
&& (this->enable_ocsp
|| this->enable_crl
) &&
803 subject
->get_type(subject
) == CERT_X509
&&
804 issuer
->get_type(issuer
) == CERT_X509
)
806 DBG1(DBG_CFG
, "checking certificate status of \"%Y\"",
807 subject
->get_subject(subject
));
809 if (this->enable_ocsp
)
811 switch (check_ocsp((x509_t
*)subject
, (x509_t
*)issuer
,
812 pathlen
? NULL
: auth
))
814 case VALIDATION_GOOD
:
815 DBG1(DBG_CFG
, "certificate status is good");
817 case VALIDATION_REVOKED
:
818 case VALIDATION_ON_HOLD
:
819 /* has already been logged */
820 lib
->credmgr
->call_hook(lib
->credmgr
, CRED_HOOK_REVOKED
,
823 case VALIDATION_SKIPPED
:
824 DBG2(DBG_CFG
, "ocsp check skipped, no ocsp found");
826 case VALIDATION_STALE
:
827 DBG1(DBG_CFG
, "ocsp information stale, fallback to crl");
829 case VALIDATION_FAILED
:
830 DBG1(DBG_CFG
, "ocsp check failed, fallback to crl");
835 if (this->enable_crl
)
837 switch (check_crl((x509_t
*)subject
, (x509_t
*)issuer
,
838 pathlen
? NULL
: auth
))
840 case VALIDATION_GOOD
:
841 DBG1(DBG_CFG
, "certificate status is good");
843 case VALIDATION_REVOKED
:
844 case VALIDATION_ON_HOLD
:
845 /* has already been logged */
846 lib
->credmgr
->call_hook(lib
->credmgr
, CRED_HOOK_REVOKED
,
849 case VALIDATION_FAILED
:
850 case VALIDATION_SKIPPED
:
851 DBG1(DBG_CFG
, "certificate status is not available");
853 case VALIDATION_STALE
:
854 DBG1(DBG_CFG
, "certificate status is unknown, crl is stale");
859 lib
->credmgr
->call_hook(lib
->credmgr
, CRED_HOOK_VALIDATION_FAILED
,
865 METHOD(revocation_validator_t
, destroy
, void,
866 private_revocation_validator_t
*this)
874 revocation_validator_t
*revocation_validator_create()
876 private_revocation_validator_t
*this;
880 .validator
.validate
= _validate
,
883 .enable_ocsp
= lib
->settings
->get_bool(lib
->settings
,
884 "%s.plugins.revocation.enable_ocsp", TRUE
, lib
->ns
),
885 .enable_crl
= lib
->settings
->get_bool(lib
->settings
,
886 "%s.plugins.revocation.enable_crl", TRUE
, lib
->ns
),
889 if (!this->enable_ocsp
)
891 DBG1(DBG_LIB
, "all OCSP validation disabled");
893 if (!this->enable_crl
)
895 DBG1(DBG_LIB
, "all CRL validation disabled");
897 return &this->public;