]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Add configuration option check_crl_strict
authorSam Voss <sam.voss@rockwellcollins.com>
Mon, 7 Aug 2017 16:26:33 +0000 (11:26 -0500)
committerJouni Malinen <j@w1.fi>
Mon, 31 Dec 2018 10:51:51 +0000 (12:51 +0200)
Add the ability to ignore time-based CRL errors from OpenSSL by
specifying a new configuration parameter, check_crl_strict=0.

This causes the following:

- This setting does nothing when CRL checking is not enabled.

- When CRL is enabled, "strict mode" will cause CRL time errors to not
  be ignored and will continue behaving as it currently does.

- When CRL is enabled, disabling strict mode will cause CRL time
  errors to be ignored and will allow connections.

By default, check_crl_strict is set to 1, or strict mode, to keep
current functionality.

Signed-off-by: Sam Voss <sam.voss@rockwellcollins.com>
12 files changed:
eap_example/eap_example_server.c
hostapd/config_file.c
hostapd/hostapd.conf
src/ap/ap_config.c
src/ap/ap_config.h
src/ap/authsrv.c
src/crypto/tls.h
src/crypto/tls_gnutls.c
src/crypto/tls_internal.c
src/crypto/tls_none.c
src/crypto/tls_openssl.c
src/crypto/tls_wolfssl.c

index 05240969423ffad9e8711d90206924b9aca16447..145bb9f7ebda8f5a718ee07be6dc98db6d476dd9 100644 (file)
@@ -88,7 +88,7 @@ static int eap_example_server_init_tls(void)
                return -1;
        }
 
-       if (tls_global_set_verify(eap_ctx.tls_ctx, 0)) {
+       if (tls_global_set_verify(eap_ctx.tls_ctx, 0, 1)) {
                printf("Failed to set check_crl\n");
                return -1;
        }
index b0d92ba38f6e689a6f739c26a0adfb1ceeebcbd2..cb8d26fce818aeb9a60da727e0d61d6f8ff5eda7 100644 (file)
@@ -2489,6 +2489,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                bss->private_key_passwd = os_strdup(pos);
        } else if (os_strcmp(buf, "check_crl") == 0) {
                bss->check_crl = atoi(pos);
+       } else if (os_strcmp(buf, "check_crl_strict") == 0) {
+               bss->check_crl_strict = atoi(pos);
        } else if (os_strcmp(buf, "tls_session_lifetime") == 0) {
                bss->tls_session_lifetime = atoi(pos);
        } else if (os_strcmp(buf, "tls_flags") == 0) {
index 613455984bc1c442cbb860d7077cb9bf874d5574..e934b9f34e88f00edd8de001c1dc867708d9c4a8 100644 (file)
@@ -904,6 +904,13 @@ eap_server=0
 # 2 = check all CRLs in the certificate path
 #check_crl=1
 
+# Specify whether to ignore certificate CRL validity time mismatches with
+# errors X509_V_ERR_CERT_HAS_EXPIRED and X509_V_ERR_CERT_NOT_YET_VALID.
+#
+# 0 = ignore errors
+# 1 = do not ignore errors (default)
+#check_crl_strict=1
+
 # TLS Session Lifetime in seconds
 # This can be used to allow TLS sessions to be cached and resumed with an
 # abbreviated handshake when using EAP-TLS/TTLS/PEAP.
index 0cfba4562558139b2d8834c3bc6c2d0fd2954d31..68abb8e32830f7389e1665d9b78decb328864bef 100644 (file)
@@ -137,6 +137,9 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
 #ifdef CONFIG_HS20
        bss->hs20_release = (HS20_VERSION >> 4) + 1;
 #endif /* CONFIG_HS20 */
+
+       /* Default to strict CRL checking. */
+       bss->check_crl_strict = 1;
 }
 
 
index fbcfe8dee027b494c37e961eca24e00957295441..f0645dcf9d5d00bd0fffa47a3cff03f8971da7c0 100644 (file)
@@ -389,6 +389,7 @@ struct hostapd_bss_config {
        char *private_key;
        char *private_key_passwd;
        int check_crl;
+       int check_crl_strict;
        unsigned int tls_session_lifetime;
        unsigned int tls_flags;
        char *ocsp_stapling_response;
index b887608e7d20f57986a2399efc6d6c8867316162..d93b967508641cee0baeaf335368838e24fca97c 100644 (file)
@@ -231,7 +231,8 @@ int authsrv_init(struct hostapd_data *hapd)
                }
 
                if (tls_global_set_verify(hapd->ssl_ctx,
-                                         hapd->conf->check_crl)) {
+                                         hapd->conf->check_crl,
+                                         hapd->conf->check_crl_strict)) {
                        wpa_printf(MSG_ERROR, "Failed to enable check_crl");
                        authsrv_deinit(hapd);
                        return -1;
index d6c581d03b6ba828b8164f033c3a2406e8a6476a..dd67cff4370d79bd7d3266ccfdc72425a7b1977d 100644 (file)
@@ -324,9 +324,11 @@ int __must_check tls_global_set_params(
  * @tls_ctx: TLS context data from tls_init()
  * @check_crl: 0 = do not verify CRLs, 1 = verify CRL for the user certificate,
  * 2 = verify CRL for all certificates
+ * @strict: 0 = allow CRL time errors, 1 = do not allow CRL time errors
  * Returns: 0 on success, -1 on failure
  */
-int __must_check tls_global_set_verify(void *tls_ctx, int check_crl);
+int __must_check tls_global_set_verify(void *tls_ctx, int check_crl,
+                                      int strict);
 
 /**
  * tls_connection_set_verify - Set certificate verification options
index 5b52adb42ff88dee6b183d400486e50278e2920f..527d01ecfd16e127431cfde704458cd53f524c28 100644 (file)
@@ -848,7 +848,7 @@ fail:
 }
 
 
-int tls_global_set_verify(void *ssl_ctx, int check_crl)
+int tls_global_set_verify(void *ssl_ctx, int check_crl, int strict)
 {
        /* TODO */
        return 0;
index 3d2dcbbb19c09b2bf3b82c713b5d16c728628f1c..9c57ab25c59539776d9a9936d776238dbd448d0c 100644 (file)
@@ -359,7 +359,7 @@ int tls_global_set_params(void *tls_ctx,
 }
 
 
-int tls_global_set_verify(void *tls_ctx, int check_crl)
+int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
 {
        struct tls_global *global = tls_ctx;
        global->check_crl = check_crl;
index 5d0c6bda15479faa332092bd7cff1da5c4843ff8..108e9aa2e47e18d40a5a5aee1663d9d99648d1b6 100644 (file)
@@ -72,7 +72,7 @@ int tls_global_set_params(void *tls_ctx,
 }
 
 
-int tls_global_set_verify(void *tls_ctx, int check_crl)
+int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
 {
        return -1;
 }
index 808eb577260e5093dfc0625ba2c6adf76700506d..d41f68a0020f1fd794b04ec106598898c3cf3372 100644 (file)
@@ -214,10 +214,12 @@ static struct tls_context *tls_global = NULL;
 struct tls_data {
        SSL_CTX *ssl;
        unsigned int tls_session_lifetime;
+       int check_crl_strict;
 };
 
 struct tls_connection {
        struct tls_context *context;
+       struct tls_data *data;
        SSL_CTX *ssl_ctx;
        SSL *ssl;
        BIO *ssl_in, *ssl_out;
@@ -1474,6 +1476,7 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
        conn = os_zalloc(sizeof(*conn));
        if (conn == NULL)
                return NULL;
+       conn->data = data;
        conn->ssl_ctx = ssl;
        conn->ssl = SSL_new(ssl);
        if (conn->ssl == NULL) {
@@ -1993,6 +1996,13 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
                           "time mismatch");
                preverify_ok = 1;
        }
+       if (!preverify_ok && !conn->data->check_crl_strict &&
+           (err == X509_V_ERR_CRL_HAS_EXPIRED ||
+            err == X509_V_ERR_CRL_NOT_YET_VALID)) {
+               wpa_printf(MSG_DEBUG,
+                          "OpenSSL: Ignore certificate validity CRL time mismatch");
+               preverify_ok = 1;
+       }
 
        err_str = X509_verify_cert_error_string(err);
 
@@ -2389,7 +2399,7 @@ static int tls_global_ca_cert(struct tls_data *data, const char *ca_cert)
 }
 
 
-int tls_global_set_verify(void *ssl_ctx, int check_crl)
+int tls_global_set_verify(void *ssl_ctx, int check_crl, int strict)
 {
        int flags;
 
@@ -2406,6 +2416,8 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl)
                if (check_crl == 2)
                        flags |= X509_V_FLAG_CRL_CHECK_ALL;
                X509_STORE_set_flags(cs, flags);
+
+               data->check_crl_strict = strict;
        }
        return 0;
 }
index f86557e0291ce93bd4e9778835c73355b06d9249..b59622e5e7ec7a7f2fd7403479386e7758d235f1 100644 (file)
@@ -1549,7 +1549,7 @@ int tls_global_set_params(void *tls_ctx,
 }
 
 
-int tls_global_set_verify(void *tls_ctx, int check_crl)
+int tls_global_set_verify(void *tls_ctx, int check_crl, int strict)
 {
        wpa_printf(MSG_DEBUG, "SSL: global set verify: %d", check_crl);