]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OpenSSL: Allow two server certificates/keys to be configured on server
authorJouni Malinen <j@w1.fi>
Fri, 12 Jul 2019 15:11:53 +0000 (18:11 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 12 Jul 2019 15:13:10 +0000 (18:13 +0300)
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>
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_openssl.c

index 3a294386f21c033c06137d46fc6b7fd379462311..df41f142434a97157c406c90fe37eb081f8aa0e7 100644 (file)
@@ -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'",
index d67a405734ec043a1996e551598a8e3b201e4178..f2d5873885b05eb38ab0e7df5fa27f1df2a8e31b 100644 (file)
@@ -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.
index 6a2deb6dea848771f27ddf33dc52a10e6dbf2351..a061bd863e118b2f3166a97779dfc8c4784b0847 100644 (file)
@@ -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);
index b1007622cd82f15adc296e0801aa37c369af6769..eebf8981db82994e286683148867e4d71d0c6a5c 100644 (file)
@@ -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;
index 3dd6b7bee1c97453ad3737ba7f8a718a89584adb..b3d910742e50f5567fd28038df72f6dc70f7dd2b 100644 (file)
@@ -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;
index a9ba7d11ae563cf0ddc5dc3f395cb5108a5ff298..c8b1a824ed54d830b11b022ae18cc8428c5d4560 100644 (file)
@@ -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;
index 48b48e9bc0642f318fe774f19e492adb9c09d27a..d45543e664895d95e3bf0487fd3620d8f46f23e2 100644 (file)
@@ -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;