crl_reload_interval: Add CRL reloading support
This patch adds a new flag 'crl_reload_interval' to reload CRL periodically. This can be used to reload ca_cert file and the included CRL information on every new TLS session if difference between the last reload and the current time in seconds is greater than crl_reload_interval. This reloading is used for cases where check_crl is 1 or 2 and the CRL is included in the ca_file. Signed-off-by: Paresh Chaudhary <paresh.chaudhary@rockwellcollins.com> Signed-off-by: Jared Bents <jared.bents@rockwellcollins.com>
This commit is contained in:
parent
0eb34f8f28
commit
159a7fbdea
6 changed files with 90 additions and 2 deletions
|
@ -2505,6 +2505,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
|||
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, "crl_reload_interval") == 0) {
|
||||
bss->crl_reload_interval = 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) {
|
||||
|
|
|
@ -922,7 +922,8 @@ eap_server=0
|
|||
# valid CRL signed by the CA is required to be included in the ca_cert file.
|
||||
# This can be done by using PEM format for CA certificate and CRL and
|
||||
# concatenating these into one file. Whenever CRL changes, hostapd needs to be
|
||||
# restarted to take the new CRL into use.
|
||||
# restarted to take the new CRL into use. Alternatively, crl_reload_interval can
|
||||
# be used to configure periodic updating of the loaded CRL information.
|
||||
# 0 = do not verify CRLs (default)
|
||||
# 1 = check the CRL of the user certificate
|
||||
# 2 = check all CRLs in the certificate path
|
||||
|
@ -935,6 +936,16 @@ eap_server=0
|
|||
# 1 = do not ignore errors (default)
|
||||
#check_crl_strict=1
|
||||
|
||||
# CRL reload interval in seconds
|
||||
# This can be used to reload ca_cert file and the included CRL on every new TLS
|
||||
# session if difference between last reload and the current reload time in
|
||||
# seconds is greater than crl_reload_interval.
|
||||
# Note: If interval time is very short, CPU overhead may be negatively affected
|
||||
# and it is advised to not go below 300 seconds.
|
||||
# This is applicable only with check_crl values 1 and 2.
|
||||
# 0 = do not reload CRLs (default)
|
||||
# crl_reload_interval = 300
|
||||
|
||||
# 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.
|
||||
|
|
|
@ -392,6 +392,7 @@ struct hostapd_bss_config {
|
|||
char *private_key_passwd;
|
||||
int check_crl;
|
||||
int check_crl_strict;
|
||||
unsigned int crl_reload_interval;
|
||||
unsigned int tls_session_lifetime;
|
||||
unsigned int tls_flags;
|
||||
char *ocsp_stapling_response;
|
||||
|
|
|
@ -201,6 +201,16 @@ int authsrv_init(struct hostapd_data *hapd)
|
|||
|
||||
os_memset(&conf, 0, sizeof(conf));
|
||||
conf.tls_session_lifetime = hapd->conf->tls_session_lifetime;
|
||||
if (hapd->conf->crl_reload_interval > 0 &&
|
||||
hapd->conf->check_crl <= 0) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"Cannot enable CRL reload functionality - it depends on check_crl being set");
|
||||
} else if (hapd->conf->crl_reload_interval > 0) {
|
||||
conf.crl_reload_interval =
|
||||
hapd->conf->crl_reload_interval;
|
||||
wpa_printf(MSG_INFO,
|
||||
"Enabled CRL reload functionality");
|
||||
}
|
||||
conf.tls_flags = hapd->conf->tls_flags;
|
||||
conf.event_cb = authsrv_tls_event;
|
||||
conf.cb_ctx = hapd;
|
||||
|
|
|
@ -82,6 +82,7 @@ struct tls_config {
|
|||
int cert_in_cb;
|
||||
const char *openssl_ciphers;
|
||||
unsigned int tls_session_lifetime;
|
||||
unsigned int crl_reload_interval;
|
||||
unsigned int tls_flags;
|
||||
|
||||
void (*event_cb)(void *ctx, enum tls_event ev,
|
||||
|
|
|
@ -214,7 +214,11 @@ static struct tls_context *tls_global = NULL;
|
|||
struct tls_data {
|
||||
SSL_CTX *ssl;
|
||||
unsigned int tls_session_lifetime;
|
||||
int check_crl;
|
||||
int check_crl_strict;
|
||||
char *ca_cert;
|
||||
unsigned int crl_reload_interval;
|
||||
struct os_reltime crl_last_reload;
|
||||
};
|
||||
|
||||
struct tls_connection {
|
||||
|
@ -305,6 +309,37 @@ static void tls_show_errors(int level, const char *func, const char *txt)
|
|||
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||
|
||||
|
||||
static X509_STORE * tls_crl_cert_reload(const char *ca_cert, int check_crl)
|
||||
{
|
||||
int flags;
|
||||
X509_STORE *store;
|
||||
|
||||
store = X509_STORE_new();
|
||||
if (!store) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"OpenSSL: %s - failed to allocate new certificate store",
|
||||
__func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ca_cert && X509_STORE_load_locations(store, ca_cert, NULL) != 1) {
|
||||
tls_show_errors(MSG_WARNING, __func__,
|
||||
"Failed to load root certificates");
|
||||
X509_STORE_free(store);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (check_crl)
|
||||
flags = X509_V_FLAG_CRL_CHECK;
|
||||
if (check_crl == 2)
|
||||
flags |= X509_V_FLAG_CRL_CHECK_ALL;
|
||||
|
||||
X509_STORE_set_flags(store, flags);
|
||||
|
||||
return store;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_NATIVE_WINDOWS
|
||||
|
||||
/* Windows CryptoAPI and access to certificate stores */
|
||||
|
@ -993,8 +1028,10 @@ void * tls_init(const struct tls_config *conf)
|
|||
return NULL;
|
||||
}
|
||||
data->ssl = ssl;
|
||||
if (conf)
|
||||
if (conf) {
|
||||
data->tls_session_lifetime = conf->tls_session_lifetime;
|
||||
data->crl_reload_interval = conf->crl_reload_interval;
|
||||
}
|
||||
|
||||
SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv2);
|
||||
SSL_CTX_set_options(ssl, SSL_OP_NO_SSLv3);
|
||||
|
@ -1076,6 +1113,7 @@ void tls_deinit(void *ssl_ctx)
|
|||
os_free(context);
|
||||
if (data->tls_session_lifetime > 0)
|
||||
SSL_CTX_flush_sessions(ssl, 0);
|
||||
os_free(data->ca_cert);
|
||||
SSL_CTX_free(ssl);
|
||||
|
||||
tls_openssl_ref_count--;
|
||||
|
@ -1471,8 +1509,28 @@ struct tls_connection * tls_connection_init(void *ssl_ctx)
|
|||
SSL_CTX *ssl = data->ssl;
|
||||
struct tls_connection *conn;
|
||||
long options;
|
||||
X509_STORE *new_cert_store;
|
||||
struct os_reltime now;
|
||||
struct tls_context *context = SSL_CTX_get_app_data(ssl);
|
||||
|
||||
/* Replace X509 store if it is time to update CRL. */
|
||||
if (data->crl_reload_interval > 0 && os_get_reltime(&now) == 0 &&
|
||||
os_reltime_expired(&now, &data->crl_last_reload,
|
||||
data->crl_reload_interval)) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"OpenSSL: Flushing X509 store with ca_cert file");
|
||||
new_cert_store = tls_crl_cert_reload(data->ca_cert,
|
||||
data->check_crl);
|
||||
if (!new_cert_store) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"OpenSSL: Error replacing X509 store with ca_cert file");
|
||||
} else {
|
||||
/* Replace old store */
|
||||
SSL_CTX_set_cert_store(ssl, new_cert_store);
|
||||
data->crl_last_reload = now;
|
||||
}
|
||||
}
|
||||
|
||||
conn = os_zalloc(sizeof(*conn));
|
||||
if (conn == NULL)
|
||||
return NULL;
|
||||
|
@ -2393,6 +2451,9 @@ static int tls_global_ca_cert(struct tls_data *data, const char *ca_cert)
|
|||
SSL_CTX_set_client_CA_list(ssl_ctx,
|
||||
SSL_load_client_CA_file(ca_cert));
|
||||
#endif /* OPENSSL_NO_STDIO */
|
||||
|
||||
os_free(data->ca_cert);
|
||||
data->ca_cert = os_strdup(ca_cert);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2417,7 +2478,9 @@ int tls_global_set_verify(void *ssl_ctx, int check_crl, int strict)
|
|||
flags |= X509_V_FLAG_CRL_CHECK_ALL;
|
||||
X509_STORE_set_flags(cs, flags);
|
||||
|
||||
data->check_crl = check_crl;
|
||||
data->check_crl_strict = strict;
|
||||
os_get_reltime(&data->crl_last_reload);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue