[v1,1/3] HostAPD: Add option 'check_crl_strict'

Message ID 1538417575-35315-1-git-send-email-jared.bents@rockwellcollins.com
State New
Headers show
Series
  • [v1,1/3] HostAPD: Add option 'check_crl_strict'
Related show

Commit Message

Jared Bents Oct. 1, 2018, 6:12 p.m.
Add the ability to ignore time-based errors from openssl by specifying a
new configuration parameter, "check_crl_strict".

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>
Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>
---
 hostapd/config_file.c    |  2 ++
 hostapd/hostapd.conf     |  8 ++++++++
 src/ap/ap_config.c       |  3 +++
 src/ap/ap_config.h       |  1 +
 src/ap/authsrv.c         |  3 ++-
 src/crypto/tls.h         |  3 ++-
 src/crypto/tls_openssl.c | 21 ++++++++++++++++++++-
 7 files changed, 38 insertions(+), 3 deletions(-)

Patch

diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 5079f69..7b7b33f 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2131,6 +2131,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, "ocsp_stapling_response") == 0) {
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index fa9a855..bc56f8d 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -795,6 +795,14 @@  eap_server=0
 # 2 = check all CRLs in the certificate path
 #check_crl=1
 
+# Specifiy whether or not to ignore certificate validity time missmatches 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=0
+
+
 # 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.
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 228de2b..2e3797b 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -95,6 +95,9 @@  void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
 	bss->radius_das_time_window = 300;
 
 	bss->sae_anti_clogging_threshold = 5;
+
+	/* Default to strict crl checking. */
+	bss->check_crl_strict = 1;
 }
 
 
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 8c8f7e2..6220185 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -352,6 +352,7 @@  struct hostapd_bss_config {
 	char *private_key;
 	char *private_key_passwd;
 	int check_crl;
+	int check_crl_strict;
 	unsigned int tls_session_lifetime;
 	char *ocsp_stapling_response;
 	char *ocsp_stapling_response_multi;
diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index cdb49cd..62ddc87 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -183,7 +183,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;
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 11d504a..bb497ce 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -303,9 +303,10 @@  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 time errors, 1 = do not allow 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
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 23ac64b..990c938 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -188,6 +188,7 @@  struct tls_context {
 	void *cb_ctx;
 	int cert_in_cb;
 	char *ocsp_stapling_response;
+	int check_crl_strict;
 };
 
 static struct tls_context *tls_global = NULL;
@@ -227,6 +228,7 @@  struct tls_connection {
 
 	unsigned int flags;
 
+
 	X509 *peer_cert;
 	X509 *peer_issuer;
 	X509 *peer_issuer_issuer;
@@ -1820,6 +1822,13 @@  static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
 			   "time mismatch");
 		preverify_ok = 1;
 	}
+	if (!preverify_ok && (!tls_global->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);
 
@@ -2185,9 +2194,11 @@  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;
+	SSL *ssl;
+	struct tls_connection *conn;
 
 	if (check_crl) {
 		struct tls_data *data = ssl_ctx;
@@ -2202,6 +2213,14 @@  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);
+
+		if (NULL == tls_global) {
+			tls_show_errors(MSG_INFO, __func__, "Failed setting "
+					"strict mode in tls_global context.");
+		} else {
+			tls_global->check_crl_strict = strict;
+		}
+
 	}
 	return 0;
 }