Handle certificates being on hold in a CRL
authorThomas Egerer <thomas.egerer@secunet.com>
Fri, 4 Nov 2011 08:25:05 +0000 (09:25 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 4 Nov 2011 10:11:17 +0000 (11:11 +0100)
Certificates which are set on hold in a CRL might be removed from any
subsequent CRL. Hence you cannot conclude that a certificate is revoked
for good in this case, you would try to retrieve an update CRL to see if
the certificate on hold is still on it or not.

src/libstrongswan/credentials/certificates/certificate.c
src/libstrongswan/credentials/certificates/certificate.h
src/libstrongswan/plugins/revocation/revocation_validator.c

index 661b69e..33ba4e9 100644 (file)
@@ -38,6 +38,7 @@ ENUM(cert_validation_names, VALIDATION_GOOD, VALIDATION_REVOKED,
        "SKIPPED",
        "STALE",
        "FAILED",
+       "ON_HOLD",
        "REVOKED",
 );
 
index 330cfe1..2f471da 100644 (file)
@@ -77,6 +77,8 @@ enum cert_validation_t {
        VALIDATION_STALE,
        /** validation failed due to a processing error */
        VALIDATION_FAILED,
+       /** certificate is on hold (i.e. temporary revokation) */
+       VALIDATION_ON_HOLD,
        /** certificate has been revoked */
        VALIDATION_REVOKED,
 };
index def1692..34f347d 100644 (file)
@@ -404,7 +404,15 @@ static certificate_t *get_better_crl(certificate_t *cand, certificate_t *best,
                {
                        DBG1(DBG_CFG, "certificate was revoked on %T, reason: %N",
                                 &revocation, TRUE, crl_reason_names, reason);
-                       *valid = VALIDATION_REVOKED;
+                       if (reason != CRL_REASON_CERTIFICATE_HOLD)
+                       {
+                               *valid = VALIDATION_REVOKED;
+                       }
+                       else
+                       {
+                               /* if the cert is on hold, a newer CRL might not contain it */
+                               *valid = VALIDATION_ON_HOLD;
+                       }
                        enumerator->destroy(enumerator);
                        DESTROY_IF(best);
                        return cand;
@@ -681,6 +689,7 @@ METHOD(cert_validator_t, validate, bool,
                                DBG1(DBG_CFG, "certificate status is good");
                                return TRUE;
                        case VALIDATION_REVOKED:
+                       case VALIDATION_ON_HOLD:
                                /* has already been logged */
                                return FALSE;
                        case VALIDATION_SKIPPED:
@@ -700,6 +709,7 @@ METHOD(cert_validator_t, validate, bool,
                                DBG1(DBG_CFG, "certificate status is good");
                                return TRUE;
                        case VALIDATION_REVOKED:
+                       case VALIDATION_ON_HOLD:
                                /* has already been logged */
                                return FALSE;
                        case VALIDATION_FAILED: