]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
TLS: Use separate TLS library context for tunneled TLS
authorJouni Malinen <j@w1.fi>
Sat, 7 Apr 2012 17:57:02 +0000 (20:57 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 7 Apr 2012 17:57:02 +0000 (20:57 +0300)
OpenSSL wrapper was using the same certificate store for both Phase 1
and Phase 2 TLS exchange in case of EAP-PEAP/TLS, EAP-TTLS/TLS, and
EAP-FAST/TLS. This would be fine if the same CA certificates were used
in both phases, but does not work properly if different CA certificates
are used. Enforce full separation of TLS state between the phases by
using a separate TLS library context in EAP peer implementation.

Signed-hostap: Jouni Malinen <j@w1.fi>

src/eap_peer/eap.c
src/eap_peer/eap_i.h
src/eap_peer/eap_tls.c
src/eap_peer/eap_tls_common.c
src/eap_peer/eap_tls_common.h

index 6a885895a07ff942dcb83bb33598280d8eb4920b..f13d2e3b988decd6df4e8b6658943d62922fef49 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * EAP peer state machines (RFC 4137)
- * Copyright (c) 2004-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -1321,6 +1321,13 @@ struct eap_sm * eap_peer_sm_init(void *eapol_ctx,
                return NULL;
        }
 
+       sm->ssl_ctx2 = tls_init(&tlsconf);
+       if (sm->ssl_ctx2 == NULL) {
+               wpa_printf(MSG_INFO, "SSL: Failed to initialize TLS "
+                          "context (2).");
+               /* Run without separate TLS context within TLS tunnel */
+       }
+
        return sm;
 }
 
@@ -1338,6 +1345,8 @@ void eap_peer_sm_deinit(struct eap_sm *sm)
                return;
        eap_deinit_prev_method(sm, "EAP deinit");
        eap_sm_abort(sm);
+       if (sm->ssl_ctx2)
+               tls_deinit(sm->ssl_ctx2);
        tls_deinit(sm->ssl_ctx);
        os_free(sm);
 }
index 06d6db62162b1ef34c014f7496944b16e3755da8..3318b81151d90d146a6f4905da345504a02e8e4e 100644 (file)
@@ -317,6 +317,7 @@ struct eap_sm {
        void *msg_ctx;
        void *scard_ctx;
        void *ssl_ctx;
+       void *ssl_ctx2;
 
        unsigned int workaround;
 
index a3067fa646394ea52a4c6153b26f0d773b285f83..ed52fb690fd98887d13846a263da772bd08abea2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * EAP peer method: EAP-TLS (RFC 2716)
- * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2008, 2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -21,6 +21,7 @@ static void eap_tls_deinit(struct eap_sm *sm, void *priv);
 struct eap_tls_data {
        struct eap_ssl_data ssl;
        u8 *key_data;
+       void *ssl_ctx;
 };
 
 
@@ -40,6 +41,9 @@ static void * eap_tls_init(struct eap_sm *sm)
        if (data == NULL)
                return NULL;
 
+       data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
+               sm->ssl_ctx;
+
        if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) {
                wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL.");
                eap_tls_deinit(sm, data);
@@ -165,7 +169,7 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
                return eap_tls_failure(sm, data, ret, res, resp, id);
        }
 
-       if (tls_connection_established(sm->ssl_ctx, data->ssl.conn))
+       if (tls_connection_established(data->ssl_ctx, data->ssl.conn))
                eap_tls_success(sm, data, ret);
 
        if (res == 1) {
@@ -180,7 +184,7 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv,
 static Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv)
 {
        struct eap_tls_data *data = priv;
-       return tls_connection_established(sm->ssl_ctx, data->ssl.conn);
+       return tls_connection_established(data->ssl_ctx, data->ssl.conn);
 }
 
 
index 52549f448e8ce5d8c7634f5552cf95f8c91727f9..69e83d9ba52fcce952862c2378598381052b725c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -136,14 +136,14 @@ static int eap_tls_init_connection(struct eap_sm *sm,
 {
        int res;
 
-       data->conn = tls_connection_init(sm->ssl_ctx);
+       data->conn = tls_connection_init(data->ssl_ctx);
        if (data->conn == NULL) {
                wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS "
                           "connection");
                return -1;
        }
 
-       res = tls_connection_set_params(sm->ssl_ctx, data->conn, params);
+       res = tls_connection_set_params(data->ssl_ctx, data->conn, params);
        if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) {
                /*
                 * At this point with the pkcs11 engine the PIN might be wrong.
@@ -162,13 +162,13 @@ static int eap_tls_init_connection(struct eap_sm *sm,
                config->pin = NULL;
                eap_sm_request_pin(sm);
                sm->ignore = TRUE;
-               tls_connection_deinit(sm->ssl_ctx, data->conn);
+               tls_connection_deinit(data->ssl_ctx, data->conn);
                data->conn = NULL;
                return -1;
        } else if (res) {
                wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection "
                           "parameters");
-               tls_connection_deinit(sm->ssl_ctx, data->conn);
+               tls_connection_deinit(data->ssl_ctx, data->conn);
                data->conn = NULL;
                return -1;
        }
@@ -197,6 +197,8 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
 
        data->eap = sm;
        data->phase2 = sm->init_phase2;
+       data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 :
+               sm->ssl_ctx;
        if (eap_tls_params_from_conf(sm, data, &params, config, data->phase2) <
            0)
                return -1;
@@ -234,7 +236,7 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
  */
 void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
 {
-       tls_connection_deinit(sm->ssl_ctx, data->conn);
+       tls_connection_deinit(data->ssl_ctx, data->conn);
        eap_peer_tls_reset_input(data);
        eap_peer_tls_reset_output(data);
 }
@@ -265,8 +267,8 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
                return NULL;
 
        /* First, try to use TLS library function for PRF, if available. */
-       if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
-           0)
+       if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len)
+           == 0)
                return out;
 
        /*
@@ -274,7 +276,7 @@ u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
         * session parameters and use an internal implementation of TLS PRF to
         * derive the key.
         */
-       if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
+       if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys))
                goto fail;
 
        if (keys.client_random == NULL || keys.server_random == NULL ||
@@ -441,14 +443,14 @@ static int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data,
                WPA_ASSERT(data->tls_out == NULL);
        }
        appl_data = NULL;
-       data->tls_out = tls_connection_handshake(sm->ssl_ctx, data->conn,
+       data->tls_out = tls_connection_handshake(data->ssl_ctx, data->conn,
                                                 msg, &appl_data);
 
        eap_peer_tls_reset_input(data);
 
        if (appl_data &&
-           tls_connection_established(sm->ssl_ctx, data->conn) &&
-           !tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
+           tls_connection_established(data->ssl_ctx, data->conn) &&
+           !tls_connection_get_failed(data->ssl_ctx, data->conn)) {
                wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data",
                                    appl_data);
                *out_data = appl_data;
@@ -616,7 +618,7 @@ int eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data,
                return -1;
        }
 
-       if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) {
+       if (tls_connection_get_failed(data->ssl_ctx, data->conn)) {
                /* TLS processing has failed - return error */
                wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to "
                           "report error");
@@ -675,7 +677,7 @@ int eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data)
 {
        eap_peer_tls_reset_input(data);
        eap_peer_tls_reset_output(data);
-       return tls_connection_shutdown(sm->ssl_ctx, data->conn);
+       return tls_connection_shutdown(data->ssl_ctx, data->conn);
 }
 
 
@@ -694,7 +696,8 @@ int eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data,
        char name[128];
        int len = 0, ret;
 
-       if (tls_get_cipher(sm->ssl_ctx, data->conn, name, sizeof(name)) == 0) {
+       if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) == 0)
+       {
                ret = os_snprintf(buf + len, buflen - len,
                                  "EAP TLS cipher=%s\n", name);
                if (ret < 0 || (size_t) ret >= buflen - len)
@@ -741,7 +744,7 @@ const u8 * eap_peer_tls_process_init(struct eap_sm *sm,
        size_t left;
        unsigned int tls_msg_len;
 
-       if (tls_get_errors(sm->ssl_ctx)) {
+       if (tls_get_errors(data->ssl_ctx)) {
                wpa_printf(MSG_INFO, "SSL: TLS errors detected");
                ret->ignore = TRUE;
                return NULL;
@@ -849,7 +852,7 @@ int eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data,
        if (msg == NULL)
                return need_more_input ? 1 : -1;
 
-       *in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->conn, msg);
+       *in_decrypted = tls_connection_decrypt(data->ssl_ctx, data->conn, msg);
        eap_peer_tls_reset_input(data);
        if (*in_decrypted == NULL) {
                wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data");
@@ -877,8 +880,8 @@ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data,
 {
        if (in_data) {
                eap_peer_tls_reset_output(data);
-               data->tls_out = tls_connection_encrypt(sm->ssl_ctx, data->conn,
-                                                      in_data);
+               data->tls_out = tls_connection_encrypt(data->ssl_ctx,
+                                                      data->conn, in_data);
                if (data->tls_out == NULL) {
                        wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 "
                                   "data (in_len=%lu)",
index 7426467cd4d22b17c92f7f54319ae4dda993d74f..771385bc80df3249a79d1c4fb7ab07d69cbb52c6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions
- * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2009, 2012, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -63,6 +63,11 @@ struct eap_ssl_data {
         * eap - EAP state machine allocated with eap_peer_sm_init()
         */
        struct eap_sm *eap;
+
+       /**
+        * ssl_ctx - TLS library context to use for the connection
+        */
+       void *ssl_ctx;
 };