aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2019-07-12 15:11:53 (GMT)
committerJouni Malinen <j@w1.fi>2019-07-12 15:13:10 (GMT)
commite2722bf81db3463b698e61908a5e9380184ce13d (patch)
treef10faa85b7670159a66a3fb2315b295f35dd4fb0
parent857edf4bf43e8e9e5e2a42cb0d2789f96f4becfa (diff)
downloadhostap-e2722bf81db3463b698e61908a5e9380184ce13d.zip
hostap-e2722bf81db3463b698e61908a5e9380184ce13d.tar.gz
hostap-e2722bf81db3463b698e61908a5e9380184ce13d.tar.bz2
OpenSSL: Allow two server certificates/keys to be configured on server
hostapd EAP server can now be configured with two separate server certificates/keys to enable parallel operations using both RSA and ECC public keys. The server will pick which one to use based on the client preferences for the cipher suite (in the TLS ClientHello message). It should be noted that number of deployed EAP peer implementations do not filter out the cipher suite list based on their local configuration and as such, configuration of alternative types of certificates on the server may result in interoperability issues. Signed-off-by: Jouni Malinen <j@w1.fi>
-rw-r--r--hostapd/config_file.c9
-rw-r--r--hostapd/hostapd.conf17
-rw-r--r--src/ap/ap_config.c3
-rw-r--r--src/ap/ap_config.h3
-rw-r--r--src/ap/authsrv.c6
-rw-r--r--src/crypto/tls.h3
-rw-r--r--src/crypto/tls_openssl.c3
7 files changed, 43 insertions, 1 deletions
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index 3a29438..df41f14 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -2589,12 +2589,21 @@ static int hostapd_config_fill(struct hostapd_config *conf,
} else if (os_strcmp(buf, "server_cert") == 0) {
os_free(bss->server_cert);
bss->server_cert = os_strdup(pos);
+ } else if (os_strcmp(buf, "server_cert2") == 0) {
+ os_free(bss->server_cert2);
+ bss->server_cert2 = os_strdup(pos);
} else if (os_strcmp(buf, "private_key") == 0) {
os_free(bss->private_key);
bss->private_key = os_strdup(pos);
+ } else if (os_strcmp(buf, "private_key2") == 0) {
+ os_free(bss->private_key2);
+ bss->private_key2 = os_strdup(pos);
} else if (os_strcmp(buf, "private_key_passwd") == 0) {
os_free(bss->private_key_passwd);
bss->private_key_passwd = os_strdup(pos);
+ } else if (os_strcmp(buf, "private_key_passwd2") == 0) {
+ os_free(bss->private_key_passwd2);
+ bss->private_key_passwd2 = os_strdup(pos);
} else if (os_strcmp(buf, "check_cert_subject") == 0) {
if (!pos[0]) {
wpa_printf(MSG_ERROR, "Line %d: unknown check_cert_subject '%s'",
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index d67a405..f2d5873 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -977,6 +977,23 @@ eap_server=0
# Passphrase for private key
#private_key_passwd=secret passphrase
+# An alternative server certificate and private key can be configured with the
+# following parameters (with values just like the parameters above without the
+# '2' suffix). The ca_cert file (in PEM encoding) is used to add the trust roots
+# for both server certificates and/or client certificates).
+#
+# The main use case for this alternative server certificate configuration is to
+# enable both RSA and ECC public keys. The server will pick which one to use
+# based on the client preferences for the cipher suite (in the TLS ClientHello
+# message). It should be noted that number of deployed EAP peer implementations
+# do not filter out the cipher suite list based on their local configuration and
+# as such, configuration of alternative types of certificates on the server may
+# result in interoperability issues.
+#server_cert2=/etc/hostapd.server-ecc.pem
+#private_key2=/etc/hostapd.server-ecc.prv
+#private_key_passwd2=secret passphrase
+
+
# Server identity
# EAP methods that provide mechanism for authenticated server identity delivery
# use this value. If not set, "hostapd" is used as a default.
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 6a2deb6..a061bd8 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -629,8 +629,11 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->ctrl_interface);
os_free(conf->ca_cert);
os_free(conf->server_cert);
+ os_free(conf->server_cert2);
os_free(conf->private_key);
+ os_free(conf->private_key2);
os_free(conf->private_key_passwd);
+ os_free(conf->private_key_passwd2);
os_free(conf->check_cert_subject);
os_free(conf->ocsp_stapling_response);
os_free(conf->ocsp_stapling_response_multi);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index b100762..eebf898 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -403,8 +403,11 @@ struct hostapd_bss_config {
char *ca_cert;
char *server_cert;
+ char *server_cert2;
char *private_key;
+ char *private_key2;
char *private_key_passwd;
+ char *private_key_passwd2;
char *check_cert_subject;
int check_crl;
int check_crl_strict;
diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index 3dd6b7b..b3d9107 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -197,7 +197,8 @@ int authsrv_init(struct hostapd_data *hapd)
#ifdef EAP_TLS_FUNCS
if (hapd->conf->eap_server &&
(hapd->conf->ca_cert || hapd->conf->server_cert ||
- hapd->conf->private_key || hapd->conf->dh_file)) {
+ hapd->conf->private_key || hapd->conf->dh_file ||
+ hapd->conf->server_cert2 || hapd->conf->private_key2)) {
struct tls_config conf;
struct tls_connection_params params;
@@ -226,8 +227,11 @@ int authsrv_init(struct hostapd_data *hapd)
os_memset(&params, 0, sizeof(params));
params.ca_cert = hapd->conf->ca_cert;
params.client_cert = hapd->conf->server_cert;
+ params.client_cert2 = hapd->conf->server_cert2;
params.private_key = hapd->conf->private_key;
+ params.private_key2 = hapd->conf->private_key2;
params.private_key_passwd = hapd->conf->private_key_passwd;
+ params.private_key_passwd2 = hapd->conf->private_key_passwd2;
params.dh_file = hapd->conf->dh_file;
params.openssl_ciphers = hapd->conf->openssl_ciphers;
params.openssl_ecdh_curves = hapd->conf->openssl_ecdh_curves;
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index a9ba7d1..c8b1a82 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -188,12 +188,15 @@ struct tls_connection_params {
const char *suffix_match;
const char *domain_match;
const char *client_cert;
+ const char *client_cert2;
const u8 *client_cert_blob;
size_t client_cert_blob_len;
const char *private_key;
+ const char *private_key2;
const u8 *private_key_blob;
size_t private_key_blob_len;
const char *private_key_passwd;
+ const char *private_key_passwd2;
const char *dh_file;
const u8 *dh_blob;
size_t dh_blob_len;
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 48b48e9..d45543e 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -5228,6 +5228,9 @@ int tls_global_set_params(void *tls_ctx,
tls_global_client_cert(data, params->client_cert) ||
tls_global_private_key(data, params->private_key,
params->private_key_passwd) ||
+ tls_global_client_cert(data, params->client_cert2) ||
+ tls_global_private_key(data, params->private_key2,
+ params->private_key_passwd2) ||
tls_global_dh(data, params->dh_file)) {
wpa_printf(MSG_INFO, "TLS: Failed to set global parameters");
return -1;