]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
cert-validator: Use a separate method for online revocation checking
authorTobias Brunner <tobias@strongswan.org>
Wed, 21 Sep 2022 08:22:16 +0000 (10:22 +0200)
committerTobias Brunner <tobias@strongswan.org>
Mon, 3 Oct 2022 08:48:46 +0000 (10:48 +0200)
This avoids having to repeat offline checks after basic trust chain
validation.

src/libcharon/plugins/addrblock/addrblock_validator.c
src/libcharon/plugins/coupling/coupling_validator.c
src/libstrongswan/credentials/cert_validator.h
src/libstrongswan/credentials/credential_manager.c
src/libstrongswan/plugins/acert/acert_validator.c
src/libstrongswan/plugins/constraints/constraints_validator.c
src/libstrongswan/plugins/revocation/revocation_validator.c

index 3fbabbca573595ed45f5989c0a32823cfec213b9..3fa37a2f3baadb05e290518ddccc993c1187d3e5 100644 (file)
@@ -110,8 +110,7 @@ static bool check_addrblock(private_addrblock_validator_t *this,
 
 METHOD(cert_validator_t, validate, bool,
        private_addrblock_validator_t *this, certificate_t *subject,
-       certificate_t *issuer, bool online, u_int pathlen, bool anchor,
-       auth_cfg_t *auth)
+       certificate_t *issuer, u_int pathlen, bool anchor, auth_cfg_t *auth)
 {
        if (subject->get_type(subject) == CERT_X509 &&
                issuer->get_type(issuer) == CERT_X509)
index 6cbec4b8f36c37a0d6310cfd532e2d99b83d06d8..e5261e2d5af1df976eff96abe529ab49da4045be 100644 (file)
@@ -136,9 +136,8 @@ static bool add_entry(private_coupling_validator_t *this, char *hash,
 }
 
 METHOD(cert_validator_t, validate, bool,
-       private_coupling_validator_t *this,
-       certificate_t *subject, certificate_t *issuer,
-       bool online, u_int pathlen, bool anchor, auth_cfg_t *auth)
+       private_coupling_validator_t *this, certificate_t *subject,
+       certificate_t *issuer, u_int pathlen, bool anchor, auth_cfg_t *auth)
 {
        bool valid = FALSE;
        char hash[MAX_HASH_SIZE];
index c5857958f07eb9b7f899d711577a45b22891e8cd..e6ea2465f581f2acae9717ef59027fce089cfc5c 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (C) 2022 Tobias Brunner
  * Copyright (C) 2010 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
@@ -51,6 +52,7 @@ struct cert_validator_t {
         */
        status_t (*check_lifetime)(cert_validator_t *this, certificate_t *cert,
                                                           int pathlen, bool anchor, auth_cfg_t *auth);
+
        /**
         * Validate a subject certificate in relation to its issuer.
         *
@@ -59,15 +61,35 @@ struct cert_validator_t {
         *
         * @param subject               subject certificate to check
         * @param issuer                issuer of subject
-        * @param online                whether to do online revocation checking
         * @param pathlen               the current length of the path bottom-up
         * @param anchor                is issuer trusted root anchor
         * @param auth                  container for resulting authentication info
         * @return                              TRUE if subject certificate valid
         */
        bool (*validate)(cert_validator_t *this, certificate_t *subject,
-                                        certificate_t *issuer, bool online, u_int pathlen,
-                                        bool anchor, auth_cfg_t *auth);
+                                        certificate_t *issuer, u_int pathlen, bool anchor,
+                                        auth_cfg_t *auth);
+
+       /**
+        * Do extended online revocation checking for the given subject certificate
+        * in relation to its issuer.
+        *
+        * If FALSE is returned, the validator should call_hook() on the
+        * credential manager with an appropriate type and the certificate.
+        *
+        * @note This is called after successful basic validation of the complete
+        * trust chain including validation via validate().
+        *
+        * @param subject               subject certificate to check
+        * @param issuer                issuer of subject
+        * @param pathlen               the current length of the path bottom-up
+        * @param anchor                is issuer trusted root anchor
+        * @param auth                  container for resulting authentication info
+        * @return                              TRUE if subject certificate valid
+        */
+       bool (*validate_online)(cert_validator_t *this, certificate_t *subject,
+                                                       certificate_t *issuer, u_int pathlen, bool anchor,
+                                                       auth_cfg_t *auth);
 };
 
 #endif /** CERT_VALIDATOR_H_ @}*/
index 798785544e412bd3a052f8ebd68070da86b092ef..cf268891600d13f46c04890e1e2edafb6f9e8ef3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Tobias Brunner
+ * Copyright (C) 2015-2022 Tobias Brunner
  * Copyright (C) 2007 Martin Willi
  *
  * Copyright (C) secunet Security Networks AG
@@ -600,11 +600,11 @@ static bool check_lifetime(private_credential_manager_t *this,
 }
 
 /**
- * check a certificate for its lifetime
+ * Check a certificate's lifetime and consult plugins
  */
 static bool check_certificate(private_credential_manager_t *this,
-                               certificate_t *subject, certificate_t *issuer, bool online,
-                               int pathlen, bool anchor, auth_cfg_t *auth)
+                                                         certificate_t *subject, certificate_t *issuer,
+                                                         int pathlen, bool anchor, auth_cfg_t *auth)
 {
        cert_validator_t *validator;
        enumerator_t *enumerator;
@@ -618,12 +618,34 @@ static bool check_certificate(private_credential_manager_t *this,
        enumerator = this->validators->create_enumerator(this->validators);
        while (enumerator->enumerate(enumerator, &validator))
        {
-               if (!validator->validate)
+               if (validator->validate &&
+                       !validator->validate(validator, subject, issuer,
+                                                                pathlen, anchor, auth))
                {
-                       continue;
+                       enumerator->destroy(enumerator);
+                       return FALSE;
                }
-               if (!validator->validate(validator, subject, issuer,
-                                                                online, pathlen, anchor, auth))
+       }
+       enumerator->destroy(enumerator);
+       return TRUE;
+}
+
+/**
+ * Do online revocation checking
+ */
+static bool check_certificate_online(private_credential_manager_t *this,
+                                                         certificate_t *subject, certificate_t *issuer,
+                                                         int pathlen, bool anchor, auth_cfg_t *auth)
+{
+       cert_validator_t *validator;
+       enumerator_t *enumerator;
+
+       enumerator = this->validators->create_enumerator(this->validators);
+       while (enumerator->enumerate(enumerator, &validator))
+       {
+               if (validator->validate_online &&
+                       !validator->validate_online(validator, subject, issuer,
+                                                                               pathlen, anchor, auth))
                {
                        enumerator->destroy(enumerator);
                        return FALSE;
@@ -788,9 +810,7 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                                break;
                        }
                }
-               /* don't do online verification here */
-               if (!check_certificate(this, current, issuer, FALSE,
-                                                          pathlen, is_anchor, auth))
+               if (!check_certificate(this, current, issuer, pathlen, is_anchor, auth))
                {
                        trusted = FALSE;
                        issuer->destroy(issuer);
@@ -828,8 +848,8 @@ static bool verify_trust_chain(private_credential_manager_t *this,
                {
                        if (rule == AUTH_RULE_CA_CERT || rule == AUTH_RULE_IM_CERT)
                        {
-                               if (!check_certificate(this, current, issuer, TRUE, pathlen++,
-                                                                          rule == AUTH_RULE_CA_CERT, auth))
+                               if (!check_certificate_online(this, current, issuer, pathlen++,
+                                                                                         rule == AUTH_RULE_CA_CERT, auth))
                                {
                                        trusted = FALSE;
                                        break;
index a46f11a92d0cc9e1374bc28c4fa6abb6edae4ad9..a9e116cc204d400712703b0512f20b0254f24144 100644 (file)
@@ -91,8 +91,7 @@ static void apply(private_acert_validator_t *this, ac_t *ac, auth_cfg_t *auth)
 
 METHOD(cert_validator_t, validate, bool,
        private_acert_validator_t *this, certificate_t *subject,
-       certificate_t *issuer, bool online, u_int pathlen, bool anchor,
-       auth_cfg_t *auth)
+       certificate_t *issuer, u_int pathlen, bool anchor, auth_cfg_t *auth)
 {
        /* for X.509 end entity certs only */
        if (pathlen == 0 && subject->get_type(subject) == CERT_X509)
index fd8390d6cf406b2f51ba73622486316513917821..0f074c4f5751136cc06546f967461d9344bef626 100644 (file)
@@ -655,8 +655,7 @@ static bool check_policy_constraints(x509_t *issuer, u_int pathlen,
 
 METHOD(cert_validator_t, validate, bool,
        private_constraints_validator_t *this, certificate_t *subject,
-       certificate_t *issuer, bool online, u_int pathlen, bool anchor,
-       auth_cfg_t *auth)
+       certificate_t *issuer, u_int pathlen, bool anchor, auth_cfg_t *auth)
 {
        if (issuer->get_type(issuer) == CERT_X509 &&
                subject->get_type(subject) == CERT_X509)
index b554f406f4ed994835bdeccfab4dfb448257a78e..7d867d57a18b3ff80305e4f5e24f8d03ebb493a4 100644 (file)
@@ -826,10 +826,9 @@ static cert_validation_t check_crl(x509_t *subject, x509_t *issuer,
        return valid;
 }
 
-METHOD(cert_validator_t, validate, bool,
+METHOD(cert_validator_t, validate_online, bool,
        private_revocation_validator_t *this, certificate_t *subject,
-       certificate_t *issuer, bool online, u_int pathlen, bool anchor,
-       auth_cfg_t *auth)
+       certificate_t *issuer, u_int pathlen, bool anchor, auth_cfg_t *auth)
 {
        bool enable_ocsp, enable_crl;
        u_int timeout;
@@ -840,7 +839,7 @@ METHOD(cert_validator_t, validate, bool,
        timeout = this->timeout;
        this->lock->unlock(this->lock);
 
-       if (online && (enable_ocsp || enable_crl) &&
+       if ((enable_ocsp || enable_crl) &&
                subject->get_type(subject) == CERT_X509 &&
                issuer->get_type(issuer) == CERT_X509)
        {
@@ -956,7 +955,7 @@ revocation_validator_t *revocation_validator_create()
 
        INIT(this,
                .public = {
-                       .validator.validate = _validate,
+                       .validator.validate_online = _validate_online,
                        .reload = _reload,
                        .destroy = _destroy,
                },