aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ap/authsrv.c12
-rw-r--r--src/ap/eap_user_db.c16
-rw-r--r--src/ap/hw_features.h5
-rw-r--r--src/ap/ieee802_11_ht.c22
-rw-r--r--src/ap/ieee802_1x.c12
-rw-r--r--src/common/defs.h1
-rw-r--r--src/common/wpa_common.c34
-rw-r--r--src/crypto/crypto_openssl.c50
-rw-r--r--src/crypto/ms_funcs.c5
-rw-r--r--src/crypto/ms_funcs.h2
-rw-r--r--src/crypto/sha1-tlsprf.c5
-rw-r--r--src/crypto/sha1-tprf.c2
-rw-r--r--src/crypto/sha256-kdf.c3
-rw-r--r--src/crypto/tls.h18
-rw-r--r--src/crypto/tls_gnutls.c12
-rw-r--r--src/crypto/tls_internal.c72
-rw-r--r--src/crypto/tls_none.c9
-rw-r--r--src/crypto/tls_openssl.c155
-rw-r--r--src/drivers/driver_wext.c117
-rw-r--r--src/eap_common/eap_fast_common.c41
-rw-r--r--src/eap_common/eap_pwd_common.c17
-rw-r--r--src/eap_common/eap_pwd_common.h13
-rw-r--r--src/eap_peer/eap.c2
-rw-r--r--src/eap_peer/eap_pwd.c66
-rw-r--r--src/eap_peer/eap_tls_common.c48
-rw-r--r--src/eap_server/eap.h3
-rw-r--r--src/eap_server/eap_server.c22
-rw-r--r--src/eap_server/eap_server_mschapv2.c13
-rw-r--r--src/eap_server/eap_server_peap.c49
-rw-r--r--src/eap_server/eap_server_pwd.c34
-rw-r--r--src/eap_server/eap_server_tls_common.c36
-rw-r--r--src/eap_server/eap_server_ttls.c18
-rw-r--r--src/radius/radius_server.c6
-rw-r--r--src/rsn_supp/wpa_ie.c3
-rw-r--r--src/tls/tlsv1_client.c2
-rw-r--r--src/tls/tlsv1_server.c2
-rw-r--r--src/utils/common.c25
-rw-r--r--src/utils/common.h2
-rw-r--r--src/utils/http_curl.c14
39 files changed, 664 insertions, 304 deletions
diff --git a/src/ap/authsrv.c b/src/ap/authsrv.c
index bd1778e4..f10e1b72 100644
--- a/src/ap/authsrv.c
+++ b/src/ap/authsrv.c
@@ -55,10 +55,11 @@ static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
{
const struct hostapd_eap_user *eap_user;
int i;
+ int rv = -1;
eap_user = hostapd_get_eap_user(ctx, identity, identity_len, phase2);
if (eap_user == NULL)
- return -1;
+ goto out;
if (user == NULL)
return 0;
@@ -72,7 +73,7 @@ static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
if (eap_user->password) {
user->password = os_malloc(eap_user->password_len);
if (user->password == NULL)
- return -1;
+ goto out;
os_memcpy(user->password, eap_user->password,
eap_user->password_len);
user->password_len = eap_user->password_len;
@@ -83,8 +84,13 @@ static int hostapd_radius_get_eap_user(void *ctx, const u8 *identity,
user->ttls_auth = eap_user->ttls_auth;
user->remediation = eap_user->remediation;
user->accept_attr = eap_user->accept_attr;
+ rv = 0;
- return 0;
+out:
+ if (rv)
+ wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
+
+ return rv;
}
diff --git a/src/ap/eap_user_db.c b/src/ap/eap_user_db.c
index 559d77f9..082d0f53 100644
--- a/src/ap/eap_user_db.c
+++ b/src/ap/eap_user_db.c
@@ -138,8 +138,12 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity,
char id_str[256], cmd[300];
size_t i;
- if (identity_len >= sizeof(id_str))
+ if (identity_len >= sizeof(id_str)) {
+ wpa_printf(MSG_DEBUG, "%s: identity len too big: %d >= %d",
+ __func__, (int) identity_len,
+ (int) (sizeof(id_str)));
return NULL;
+ }
os_memcpy(id_str, identity, identity_len);
id_str[identity_len] = '\0';
for (i = 0; i < identity_len; i++) {
@@ -182,7 +186,9 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity,
wpa_printf(MSG_DEBUG, "DB: %s", cmd);
if (sqlite3_exec(db, cmd, get_user_cb, &hapd->tmp_eap_user, NULL) !=
SQLITE_OK) {
- wpa_printf(MSG_DEBUG, "DB: Failed to complete SQL operation");
+ wpa_printf(MSG_DEBUG,
+ "DB: Failed to complete SQL operation: %s db: %s",
+ sqlite3_errmsg(db), hapd->conf->eap_user_sqlite);
} else if (hapd->tmp_eap_user.next)
user = &hapd->tmp_eap_user;
@@ -192,8 +198,10 @@ eap_user_sqlite_get(struct hostapd_data *hapd, const u8 *identity,
wpa_printf(MSG_DEBUG, "DB: %s", cmd);
if (sqlite3_exec(db, cmd, get_wildcard_cb, &hapd->tmp_eap_user,
NULL) != SQLITE_OK) {
- wpa_printf(MSG_DEBUG, "DB: Failed to complete SQL "
- "operation");
+ wpa_printf(MSG_DEBUG,
+ "DB: Failed to complete SQL operation: %s db: %s",
+ sqlite3_errmsg(db),
+ hapd->conf->eap_user_sqlite);
} else if (hapd->tmp_eap_user.next) {
user = &hapd->tmp_eap_user;
os_free(user->identity);
diff --git a/src/ap/hw_features.h b/src/ap/hw_features.h
index 0f67ab8e..ca7f22ba 100644
--- a/src/ap/hw_features.h
+++ b/src/ap/hw_features.h
@@ -36,6 +36,11 @@ static inline int hostapd_get_hw_features(struct hostapd_iface *iface)
return -1;
}
+static inline int hostapd_acs_completed(struct hostapd_iface *iface, int err)
+{
+ return -1;
+}
+
static inline int hostapd_select_hw_mode(struct hostapd_iface *iface)
{
return -100;
diff --git a/src/ap/ieee802_11_ht.c b/src/ap/ieee802_11_ht.c
index 4b0653de..9dad8e34 100644
--- a/src/ap/ieee802_11_ht.c
+++ b/src/ap/ieee802_11_ht.c
@@ -209,7 +209,7 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
struct hostapd_iface *iface = hapd->iface;
struct ieee80211_2040_bss_coex_ie *bc_ie;
struct ieee80211_2040_intol_chan_report *ic_report;
- int is_ht_allowed = 1;
+ int is_ht40_allowed = 1;
int i;
const u8 *start = (const u8 *) mgmt;
const u8 *data = start + IEEE80211_HDRLEN + 2;
@@ -242,7 +242,7 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"20 MHz BSS width request bit is set in BSS coexistence information field");
- is_ht_allowed = 0;
+ is_ht40_allowed = 0;
}
if (bc_ie->coex_param & WLAN_20_40_BSS_COEX_40MHZ_INTOL) {
@@ -250,7 +250,7 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"40 MHz intolerant bit is set in BSS coexistence information field");
- is_ht_allowed = 0;
+ is_ht40_allowed = 0;
}
if (start + len - data >= 3 &&
@@ -276,13 +276,13 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
HOSTAPD_LEVEL_DEBUG,
"20_40_INTOLERANT channel %d reported",
chan);
- is_ht_allowed = 0;
+ is_ht40_allowed = 0;
}
}
- wpa_printf(MSG_DEBUG, "is_ht_allowed=%d num_sta_ht40_intolerant=%d",
- is_ht_allowed, iface->num_sta_ht40_intolerant);
+ wpa_printf(MSG_DEBUG, "is_ht40_allowed=%d num_sta_ht40_intolerant=%d",
+ is_ht40_allowed, iface->num_sta_ht40_intolerant);
- if (!is_ht_allowed &&
+ if (!is_ht40_allowed &&
(iface->drv_flags & WPA_DRIVER_FLAGS_HT_2040_COEX)) {
if (iface->conf->secondary_channel) {
hostapd_logger(hapd, mgmt->sa,
@@ -312,10 +312,14 @@ void hostapd_2040_coex_action(struct hostapd_data *hapd,
u16 copy_sta_ht_capab(struct hostapd_data *hapd, struct sta_info *sta,
const u8 *ht_capab, size_t ht_capab_len)
{
- /* Disable HT caps for STAs associated to no-HT BSSes. */
+ /*
+ * Disable HT caps for STAs associated to no-HT BSSes, or for stations
+ * that did not specify a valid WMM IE in the (Re)Association Request
+ * frame.
+ */
if (!ht_capab ||
ht_capab_len < sizeof(struct ieee80211_ht_capabilities) ||
- hapd->conf->disable_11n) {
+ !(sta->flags & WLAN_STA_WMM) || hapd->conf->disable_11n) {
sta->flags &= ~WLAN_STA_HT;
os_free(sta->ht_capabilities);
sta->ht_capabilities = NULL;
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index 79dc0f95..7e17ef4f 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -1926,10 +1926,11 @@ static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
struct hostapd_data *hapd = ctx;
const struct hostapd_eap_user *eap_user;
int i;
+ int rv = -1;
eap_user = hostapd_get_eap_user(hapd, identity, identity_len, phase2);
if (eap_user == NULL)
- return -1;
+ goto out;
os_memset(user, 0, sizeof(*user));
user->phase2 = phase2;
@@ -1941,7 +1942,7 @@ static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
if (eap_user->password) {
user->password = os_malloc(eap_user->password_len);
if (user->password == NULL)
- return -1;
+ goto out;
os_memcpy(user->password, eap_user->password,
eap_user->password_len);
user->password_len = eap_user->password_len;
@@ -1951,8 +1952,13 @@ static int ieee802_1x_get_eap_user(void *ctx, const u8 *identity,
user->macacl = eap_user->macacl;
user->ttls_auth = eap_user->ttls_auth;
user->remediation = eap_user->remediation;
+ rv = 0;
- return 0;
+out:
+ if (rv)
+ wpa_printf(MSG_DEBUG, "%s: Failed to find user", __func__);
+
+ return rv;
}
diff --git a/src/common/defs.h b/src/common/defs.h
index b5f4f801..24f80ad4 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -310,6 +310,7 @@ enum wpa_ctrl_req_type {
WPA_CTRL_REQ_EAP_OTP,
WPA_CTRL_REQ_EAP_PASSPHRASE,
WPA_CTRL_REQ_SIM,
+ WPA_CTRL_REQ_PSK_PASSPHRASE,
NUM_WPA_CTRL_REQS
};
diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c
index 5534eab4..03689048 100644
--- a/src/common/wpa_common.c
+++ b/src/common/wpa_common.c
@@ -486,6 +486,8 @@ static int rsn_key_mgmt_to_bitfield(const u8 *s)
return WPA_KEY_MGMT_IEEE8021X_SUITE_B;
if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_802_1X_SUITE_B_192)
return WPA_KEY_MGMT_IEEE8021X_SUITE_B_192;
+ if (RSN_SELECTOR_GET(s) == RSN_AUTH_KEY_MGMT_OSEN)
+ return WPA_KEY_MGMT_OSEN;
return 0;
}
@@ -520,7 +522,6 @@ int wpa_cipher_valid_mgmt_group(int cipher)
int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
struct wpa_ie_data *data)
{
- const struct rsn_ie_hdr *hdr;
const u8 *pos;
int left;
int i, count;
@@ -550,18 +551,29 @@ int wpa_parse_wpa_ie_rsn(const u8 *rsn_ie, size_t rsn_ie_len,
return -1;
}
- hdr = (const struct rsn_ie_hdr *) rsn_ie;
+ if (rsn_ie_len >= 6 && rsn_ie[1] >= 4 &&
+ rsn_ie[1] == rsn_ie_len - 2 &&
+ WPA_GET_BE32(&rsn_ie[2]) == OSEN_IE_VENDOR_TYPE) {
+ pos = rsn_ie + 6;
+ left = rsn_ie_len - 6;
- if (hdr->elem_id != WLAN_EID_RSN ||
- hdr->len != rsn_ie_len - 2 ||
- WPA_GET_LE16(hdr->version) != RSN_VERSION) {
- wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
- __func__);
- return -2;
- }
+ data->proto = WPA_PROTO_OSEN;
+ } else {
+ const struct rsn_ie_hdr *hdr;
- pos = (const u8 *) (hdr + 1);
- left = rsn_ie_len - sizeof(*hdr);
+ hdr = (const struct rsn_ie_hdr *) rsn_ie;
+
+ if (hdr->elem_id != WLAN_EID_RSN ||
+ hdr->len != rsn_ie_len - 2 ||
+ WPA_GET_LE16(hdr->version) != RSN_VERSION) {
+ wpa_printf(MSG_DEBUG, "%s: malformed ie or unknown version",
+ __func__);
+ return -2;
+ }
+
+ pos = (const u8 *) (hdr + 1);
+ left = rsn_ie_len - sizeof(*hdr);
+ }
if (left >= RSN_SELECTOR_LEN) {
data->group_cipher = rsn_selector_to_bitfield(pos);
diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c
index f158ef43..9834b25c 100644
--- a/src/crypto/crypto_openssl.c
+++ b/src/crypto/crypto_openssl.c
@@ -324,6 +324,56 @@ int aes_unwrap(const u8 *kek, size_t kek_len, int n, const u8 *cipher,
}
+int aes_128_cbc_encrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
+{
+ EVP_CIPHER_CTX ctx;
+ int clen, len;
+ u8 buf[16];
+
+ EVP_CIPHER_CTX_init(&ctx);
+ if (EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+ return -1;
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ clen = data_len;
+ if (EVP_EncryptUpdate(&ctx, data, &clen, data, data_len) != 1 ||
+ clen != (int) data_len)
+ return -1;
+
+ len = sizeof(buf);
+ if (EVP_EncryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
+ return -1;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ return 0;
+}
+
+
+int aes_128_cbc_decrypt(const u8 *key, const u8 *iv, u8 *data, size_t data_len)
+{
+ EVP_CIPHER_CTX ctx;
+ int plen, len;
+ u8 buf[16];
+
+ EVP_CIPHER_CTX_init(&ctx);
+ if (EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv) != 1)
+ return -1;
+ EVP_CIPHER_CTX_set_padding(&ctx, 0);
+
+ plen = data_len;
+ if (EVP_DecryptUpdate(&ctx, data, &plen, data, data_len) != 1 ||
+ plen != (int) data_len)
+ return -1;
+
+ len = sizeof(buf);
+ if (EVP_DecryptFinal_ex(&ctx, buf, &len) != 1 || len != 0)
+ return -1;
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ return 0;
+}
+
+
int crypto_mod_exp(const u8 *base, size_t base_len,
const u8 *power, size_t power_len,
const u8 *modulus, size_t modulus_len,
diff --git a/src/crypto/ms_funcs.c b/src/crypto/ms_funcs.c
index 49a5c1c2..5f576560 100644
--- a/src/crypto/ms_funcs.c
+++ b/src/crypto/ms_funcs.c
@@ -78,9 +78,8 @@ static int utf8_to_ucs2(const u8 *utf8_string, size_t utf8_string_len,
* @challenge: 8-octet Challenge (OUT)
* Returns: 0 on success, -1 on failure
*/
-static int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
- const u8 *username, size_t username_len,
- u8 *challenge)
+int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
+ const u8 *username, size_t username_len, u8 *challenge)
{
u8 hash[SHA1_MAC_LEN];
const unsigned char *addr[3];
diff --git a/src/crypto/ms_funcs.h b/src/crypto/ms_funcs.h
index bd9bfee9..b5b5918e 100644
--- a/src/crypto/ms_funcs.h
+++ b/src/crypto/ms_funcs.h
@@ -33,6 +33,8 @@ int nt_challenge_response(const u8 *challenge, const u8 *password,
void challenge_response(const u8 *challenge, const u8 *password_hash,
u8 *response);
+int challenge_hash(const u8 *peer_challenge, const u8 *auth_challenge,
+ const u8 *username, size_t username_len, u8 *challenge);
int nt_password_hash(const u8 *password, size_t password_len,
u8 *password_hash);
int hash_nt_password_hash(const u8 *password_hash, u8 *password_hash_hash);
diff --git a/src/crypto/sha1-tlsprf.c b/src/crypto/sha1-tlsprf.c
index 0effd9b7..f9bc0ebf 100644
--- a/src/crypto/sha1-tlsprf.c
+++ b/src/crypto/sha1-tlsprf.c
@@ -95,5 +95,10 @@ int tls_prf_sha1_md5(const u8 *secret, size_t secret_len, const char *label,
SHA1_pos++;
}
+ os_memset(A_MD5, 0, MD5_MAC_LEN);
+ os_memset(P_MD5, 0, MD5_MAC_LEN);
+ os_memset(A_SHA1, 0, SHA1_MAC_LEN);
+ os_memset(P_SHA1, 0, SHA1_MAC_LEN);
+
return 0;
}
diff --git a/src/crypto/sha1-tprf.c b/src/crypto/sha1-tprf.c
index a5294946..562510f8 100644
--- a/src/crypto/sha1-tprf.c
+++ b/src/crypto/sha1-tprf.c
@@ -66,5 +66,7 @@ int sha1_t_prf(const u8 *key, size_t key_len, const char *label,
len[0] = SHA1_MAC_LEN;
}
+ os_memset(hash, 0, SHA1_MAC_LEN);
+
return 0;
}
diff --git a/src/crypto/sha256-kdf.c b/src/crypto/sha256-kdf.c
index d8a1beb3..e7509ce4 100644
--- a/src/crypto/sha256-kdf.c
+++ b/src/crypto/sha256-kdf.c
@@ -61,6 +61,7 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len,
if (iter == 255) {
os_memset(out, 0, outlen);
+ os_memset(T, 0, SHA256_MAC_LEN);
return -1;
}
iter++;
@@ -68,9 +69,11 @@ int hmac_sha256_kdf(const u8 *secret, size_t secret_len,
if (hmac_sha256_vector(secret, secret_len, 4, addr, len, T) < 0)
{
os_memset(out, 0, outlen);
+ os_memset(T, 0, SHA256_MAC_LEN);
return -1;
}
}
+ os_memset(T, 0, SHA256_MAC_LEN);
return 0;
}
diff --git a/src/crypto/tls.h b/src/crypto/tls.h
index 9ae95a66..f9e2e10e 100644
--- a/src/crypto/tls.h
+++ b/src/crypto/tls.h
@@ -12,8 +12,6 @@
struct tls_connection;
struct tls_keys {
- const u8 *master_key; /* TLS master secret */
- size_t master_key_len;
const u8 *client_random;
size_t client_random_len;
const u8 *server_random;
@@ -308,10 +306,10 @@ int __must_check tls_connection_set_verify(void *tls_ctx,
int verify_peer);
/**
- * tls_connection_get_keys - Get master key and random data from TLS connection
+ * tls_connection_get_keys - Get random data from TLS connection
* @tls_ctx: TLS context data from tls_init()
* @conn: Connection context data from tls_connection_init()
- * @keys: Structure of key/random data (filled on success)
+ * @keys: Structure of client/server random data (filled on success)
* Returns: 0 on success, -1 on failure
*/
int __must_check tls_connection_get_keys(void *tls_ctx,
@@ -325,6 +323,7 @@ int __must_check tls_connection_get_keys(void *tls_ctx,
* @label: Label (e.g., description of the key) for PRF
* @server_random_first: seed is 0 = client_random|server_random,
* 1 = server_random|client_random
+ * @skip_keyblock: Skip TLS key block from the beginning of PRF output
* @out: Buffer for output data from TLS-PRF
* @out_len: Length of the output buffer
* Returns: 0 on success, -1 on failure
@@ -342,6 +341,7 @@ int __must_check tls_connection_prf(void *tls_ctx,
struct tls_connection *conn,
const char *label,
int server_random_first,
+ int skip_keyblock,
u8 *out, size_t out_len);
/**
@@ -528,16 +528,6 @@ int tls_connection_get_write_alerts(void *tls_ctx,
struct tls_connection *conn);
/**
- * tls_connection_get_keyblock_size - Get TLS key_block size
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * Returns: Size of the key_block for the negotiated cipher suite or -1 on
- * failure
- */
-int tls_connection_get_keyblock_size(void *tls_ctx,
- struct tls_connection *conn);
-
-/**
* tls_capabilities - Get supported TLS capabilities
* @tls_ctx: TLS context data from tls_init()
* Returns: Bit field of supported TLS capabilities (TLS_CAPABILITY_*)
diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c
index 65db6fcc..c7f6464b 100644
--- a/src/crypto/tls_gnutls.c
+++ b/src/crypto/tls_gnutls.c
@@ -747,9 +747,9 @@ int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
const char *label, int server_random_first,
- u8 *out, size_t out_len)
+ int skip_keyblock, u8 *out, size_t out_len)
{
- if (conn == NULL || conn->session == NULL)
+ if (conn == NULL || conn->session == NULL || skip_keyblock)
return -1;
return gnutls_prf(conn->session, os_strlen(label), label,
@@ -1476,14 +1476,6 @@ int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
}
-int tls_connection_get_keyblock_size(void *tls_ctx,
- struct tls_connection *conn)
-{
- /* TODO */
- return -1;
-}
-
-
unsigned int tls_capabilities(void *tls_ctx)
{
return 0;
diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c
index 0c955da2..afd46953 100644
--- a/src/crypto/tls_internal.c
+++ b/src/crypto/tls_internal.c
@@ -192,26 +192,31 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
if (params->subject_match) {
wpa_printf(MSG_INFO, "TLS: subject_match not supported");
+ tlsv1_cred_free(cred);
return -1;
}
if (params->altsubject_match) {
wpa_printf(MSG_INFO, "TLS: altsubject_match not supported");
+ tlsv1_cred_free(cred);
return -1;
}
if (params->suffix_match) {
wpa_printf(MSG_INFO, "TLS: suffix_match not supported");
+ tlsv1_cred_free(cred);
return -1;
}
if (params->domain_match) {
wpa_printf(MSG_INFO, "TLS: domain_match not supported");
+ tlsv1_cred_free(cred);
return -1;
}
if (params->openssl_ciphers) {
- wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported");
+ wpa_printf(MSG_INFO, "TLS: openssl_ciphers not supported");
+ tlsv1_cred_free(cred);
return -1;
}
@@ -348,25 +353,57 @@ int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
}
+static int tls_get_keyblock_size(struct tls_connection *conn)
+{
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_get_keyblock_size(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_get_keyblock_size(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
+}
+
+
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
const char *label, int server_random_first,
- u8 *out, size_t out_len)
-{
+ int skip_keyblock, u8 *out, size_t out_len)
+{
+ int ret = -1, skip = 0;
+ u8 *tmp_out = NULL;
+ u8 *_out = out;
+
+ if (skip_keyblock) {
+ skip = tls_get_keyblock_size(conn);
+ if (skip < 0)
+ return -1;
+ tmp_out = os_malloc(skip + out_len);
+ if (!tmp_out)
+ return -1;
+ _out = tmp_out;
+ }
+
#ifdef CONFIG_TLS_INTERNAL_CLIENT
if (conn->client) {
- return tlsv1_client_prf(conn->client, label,
- server_random_first,
- out, out_len);
+ ret = tlsv1_client_prf(conn->client, label,
+ server_random_first,
+ _out, out_len);
}
#endif /* CONFIG_TLS_INTERNAL_CLIENT */
#ifdef CONFIG_TLS_INTERNAL_SERVER
if (conn->server) {
- return tlsv1_server_prf(conn->server, label,
- server_random_first,
- out, out_len);
+ ret = tlsv1_server_prf(conn->server, label,
+ server_random_first,
+ _out, out_len);
}
#endif /* CONFIG_TLS_INTERNAL_SERVER */
- return -1;
+ if (ret == 0 && skip_keyblock)
+ os_memcpy(out, _out + skip, out_len);
+ bin_clear_free(tmp_out, skip);
+
+ return ret;
}
@@ -637,21 +674,6 @@ int tls_connection_get_write_alerts(void *tls_ctx,
}
-int tls_connection_get_keyblock_size(void *tls_ctx,
- struct tls_connection *conn)
-{
-#ifdef CONFIG_TLS_INTERNAL_CLIENT
- if (conn->client)
- return tlsv1_client_get_keyblock_size(conn->client);
-#endif /* CONFIG_TLS_INTERNAL_CLIENT */
-#ifdef CONFIG_TLS_INTERNAL_SERVER
- if (conn->server)
- return tlsv1_server_get_keyblock_size(conn->server);
-#endif /* CONFIG_TLS_INTERNAL_SERVER */
- return -1;
-}
-
-
unsigned int tls_capabilities(void *tls_ctx)
{
return 0;
diff --git a/src/crypto/tls_none.c b/src/crypto/tls_none.c
index a6d210af..1b1ba569 100644
--- a/src/crypto/tls_none.c
+++ b/src/crypto/tls_none.c
@@ -87,7 +87,7 @@ int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
const char *label, int server_random_first,
- u8 *out, size_t out_len)
+ int skip_keyblock, u8 *out, size_t out_len)
{
return -1;
}
@@ -181,13 +181,6 @@ int tls_connection_get_write_alerts(void *tls_ctx,
}
-int tls_connection_get_keyblock_size(void *tls_ctx,
- struct tls_connection *conn)
-{
- return -1;
-}
-
-
unsigned int tls_capabilities(void *tls_ctx)
{
return 0;
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 52db8fc0..935add5a 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -26,6 +26,7 @@
#include "common.h"
#include "crypto.h"
+#include "sha1.h"
#include "tls.h"
#if defined(SSL_CTX_get_app_data) && defined(SSL_CTX_set_app_data)
@@ -2632,8 +2633,6 @@ int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
return -1;
os_memset(keys, 0, sizeof(*keys));
- keys->master_key = ssl->session->master_key;
- keys->master_key_len = ssl->session->master_key_length;
keys->client_random = ssl->s3->client_random;
keys->client_random_len = SSL3_RANDOM_SIZE;
keys->server_random = ssl->s3->server_random;
@@ -2644,16 +2643,122 @@ int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
}
+static int openssl_get_keyblock_size(SSL *ssl)
+{
+ const EVP_CIPHER *c;
+ const EVP_MD *h;
+ int md_size;
+
+ if (ssl->enc_read_ctx == NULL || ssl->enc_read_ctx->cipher == NULL ||
+ ssl->read_hash == NULL)
+ return -1;
+
+ c = ssl->enc_read_ctx->cipher;
+#if OPENSSL_VERSION_NUMBER >= 0x00909000L
+ h = EVP_MD_CTX_md(ssl->read_hash);
+#else
+ h = conn->ssl->read_hash;
+#endif
+ if (h)
+ md_size = EVP_MD_size(h);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ else if (ssl->s3)
+ md_size = ssl->s3->tmp.new_mac_secret_size;
+#endif
+ else
+ return -1;
+
+ wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
+ "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
+ EVP_CIPHER_iv_length(c));
+ return 2 * (EVP_CIPHER_key_length(c) +
+ md_size +
+ EVP_CIPHER_iv_length(c));
+}
+
+
+static int openssl_tls_prf(void *tls_ctx, struct tls_connection *conn,
+ const char *label, int server_random_first,
+ int skip_keyblock, u8 *out, size_t out_len)
+{
+#ifdef CONFIG_FIPS
+ wpa_printf(MSG_ERROR, "OpenSSL: TLS keys cannot be exported in FIPS "
+ "mode");
+ return -1;
+#else /* CONFIG_FIPS */
+ SSL *ssl;
+ u8 *rnd;
+ int ret = -1;
+ int skip = 0;
+ u8 *tmp_out = NULL;
+ u8 *_out = out;
+
+ /*
+ * TLS library did not support key generation, so get the needed TLS
+ * session parameters and use an internal implementation of TLS PRF to
+ * derive the key.
+ */
+
+ if (conn == NULL)
+ return -1;
+ ssl = conn->ssl;
+ if (ssl == NULL || ssl->s3 == NULL || ssl->session == NULL ||
+ ssl->s3->client_random == NULL || ssl->s3->server_random == NULL ||
+ ssl->session->master_key == NULL)
+ return -1;
+
+ if (skip_keyblock) {
+ skip = openssl_get_keyblock_size(ssl);
+ if (skip < 0)
+ return -1;
+ tmp_out = os_malloc(skip + out_len);
+ if (!tmp_out)
+ return -1;
+ _out = tmp_out;
+ }
+
+ rnd = os_malloc(2 * SSL3_RANDOM_SIZE);
+ if (rnd == NULL)
+ return -1;
+ if (server_random_first) {
+ os_memcpy(rnd, ssl->s3->server_random, SSL3_RANDOM_SIZE);
+ os_memcpy(rnd + SSL3_RANDOM_SIZE, ssl->s3->client_random,
+ SSL3_RANDOM_SIZE);
+ } else {
+ os_memcpy(rnd, ssl->s3->client_random, SSL3_RANDOM_SIZE);
+ os_memcpy(rnd + SSL3_RANDOM_SIZE, ssl->s3->server_random,
+ SSL3_RANDOM_SIZE);
+ }
+
+ /* TODO: TLSv1.2 may need another PRF. This could use something closer
+ * to SSL_export_keying_material() design. */
+ if (tls_prf_sha1_md5(ssl->session->master_key,
+ ssl->session->master_key_length,
+ label, rnd, 2 * SSL3_RANDOM_SIZE,
+ _out, skip + out_len) == 0)
+ ret = 0;
+ os_free(rnd);
+ if (ret == 0 && skip_keyblock)
+ os_memcpy(out, _out + skip, out_len);
+ bin_clear_free(tmp_out, skip);
+
+ return ret;
+#endif /* CONFIG_FIPS */
+}
+
+
int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
const char *label, int server_random_first,
- u8 *out, size_t out_len)
+ int skip_keyblock, u8 *out, size_t out_len)
{
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
SSL *ssl;
if (conn == NULL)
return -1;
- if (server_random_first)
- return -1;
+ if (server_random_first || skip_keyblock)
+ return openssl_tls_prf(tls_ctx, conn, label,
+ server_random_first, skip_keyblock,
+ out, out_len);
ssl = conn->ssl;
if (SSL_export_keying_material(ssl, out, out_len, label,
os_strlen(label), NULL, 0, 0) == 1) {
@@ -2661,7 +2766,8 @@ int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
return 0;
}
#endif
- return -1;
+ return openssl_tls_prf(tls_ctx, conn, label, server_random_first,
+ skip_keyblock, out, out_len);
}
@@ -3514,43 +3620,6 @@ int tls_global_set_params(void *tls_ctx,
}
-int tls_connection_get_keyblock_size(void *tls_ctx,
- struct tls_connection *conn)
-{
- const EVP_CIPHER *c;
- const EVP_MD *h;
- int md_size;
-
- if (conn == NULL || conn->ssl == NULL ||
- conn->ssl->enc_read_ctx == NULL ||
- conn->ssl->enc_read_ctx->cipher == NULL ||
- conn->ssl->read_hash == NULL)
- return -1;
-
- c = conn->ssl->enc_read_ctx->cipher;
-#if OPENSSL_VERSION_NUMBER >= 0x00909000L
- h = EVP_MD_CTX_md(conn->ssl->read_hash);
-#else
- h = conn->ssl->read_hash;
-#endif
- if (h)
- md_size = EVP_MD_size(h);
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- else if (conn->ssl->s3)
- md_size = conn->ssl->s3->tmp.new_mac_secret_size;
-#endif
- else
- return -1;
-
- wpa_printf(MSG_DEBUG, "OpenSSL: keyblock size: key_len=%d MD_size=%d "
- "IV_len=%d", EVP_CIPHER_key_length(c), md_size,
- EVP_CIPHER_iv_length(c));
- return 2 * (EVP_CIPHER_key_length(c) +
- md_size +
- EVP_CIPHER_iv_length(c));
-}
-
-
unsigned int tls_capabilities(void *tls_ctx)
{
return 0;
diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c
index a1581b8c..22e11840 100644
--- a/src/drivers/driver_wext.c
+++ b/src/drivers/driver_wext.c
@@ -1,6 +1,6 @@
/*
* Driver interaction with generic Linux Wireless Extensions
- * Copyright (c) 2003-2010, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -18,6 +18,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <net/if_arp.h>
+#include <dirent.h>
#include "linux_wext.h"
#include "common.h"
@@ -874,6 +875,105 @@ static void wpa_driver_wext_send_rfkill(void *eloop_ctx, void *timeout_ctx)
}
+static int wext_hostap_ifname(struct wpa_driver_wext_data *drv,
+ const char *ifname)
+{
+ char buf[200], *res;
+ int type;
+ FILE *f;
+
+ if (strcmp(ifname, ".") == 0 || strcmp(ifname, "..") == 0)
+ return -1;
+
+ snprintf(buf, sizeof(buf), "/sys/class/net/%s/device/net/%s/type",
+ drv->ifname, ifname);
+
+ f = fopen(buf, "r");
+ if (!f)
+ return -1;
+ res = fgets(buf, sizeof(buf), f);
+ fclose(f);
+
+ type = res ? atoi(res) : -1;
+ wpa_printf(MSG_DEBUG, "WEXT: hostap ifname %s type %d", ifname, type);
+
+ if (type == ARPHRD_IEEE80211) {
+ wpa_printf(MSG_DEBUG,
+ "WEXT: Found hostap driver wifi# interface (%s)",
+ ifname);
+ wpa_driver_wext_alternative_ifindex(drv, ifname);
+ return 0;
+ }
+ return -1;
+}
+
+
+static int wext_add_hostap(struct wpa_driver_wext_data *drv)
+{
+ char buf[200];
+ int n;
+ struct dirent **names;
+ int ret = -1;
+
+ snprintf(buf, sizeof(buf), "/sys/class/net/%s/device/net", drv->ifname);
+ n = scandir(buf, &names, NULL, alphasort);
+ if (n < 0)
+ return -1;
+
+ while (n--) {
+ if (ret < 0 && wext_hostap_ifname(drv, names[n]->d_name) == 0)
+ ret = 0;
+ free(names[n]);
+ }
+ free(names);
+
+ return ret;
+}
+
+
+static void wext_check_hostap(struct wpa_driver_wext_data *drv)
+{
+ char buf[200], *pos;
+ ssize_t res;
+
+ /*
+ * Host AP driver may use both wlan# and wifi# interface in wireless
+ * events. Since some of the versions included WE-18 support, let's add
+ * the alternative ifindex also from driver_wext.c for the time being.
+ * This may be removed at some point once it is believed that old
+ * versions of the driver are not in use anymore. However, it looks like
+ * the wifi# interface is still used in the current kernel tree, so it
+ * may not really be possible to remove this before the Host AP driver
+ * gets removed from the kernel.
+ */
+
+ /* First, try to see if driver information is available from sysfs */
+ snprintf(buf, sizeof(buf), "/sys/class/net/%s/device/driver",
+ drv->ifname);
+ res = readlink(buf, buf, sizeof(buf) - 1);
+ if (res > 0) {
+ buf[res] = '\0';
+ pos = strrchr(buf, '/');
+ if (pos)
+ pos++;
+ else
+ pos = buf;
+ wpa_printf(MSG_DEBUG, "WEXT: Driver: %s", pos);
+ if (os_strncmp(pos, "hostap", 6) == 0 &&
+ wext_add_hostap(drv) == 0)
+ return;
+ }
+
+ /* Second, use the old design with hardcoded ifname */
+ if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
+ char ifname2[IFNAMSIZ + 1];
+ os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
+ os_memcpy(ifname2, "wifi", 4);
+ wpa_driver_wext_alternative_ifindex(drv, ifname2);
+ }
+}
+
+
static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
{
int send_rfkill_event = 0;
@@ -914,20 +1014,7 @@ static int wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv)
drv->ifindex = if_nametoindex(drv->ifname);
- if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
- /*
- * Host AP driver may use both wlan# and wifi# interface in
- * wireless events. Since some of the versions included WE-18
- * support, let's add the alternative ifindex also from
- * driver_wext.c for the time being. This may be removed at
- * some point once it is believed that old versions of the
- * driver are not in use anymore.
- */
- char ifname2[IFNAMSIZ + 1];
- os_strlcpy(ifname2, drv->ifname, sizeof(ifname2));
- os_memcpy(ifname2, "wifi", 4);
- wpa_driver_wext_alternative_ifindex(drv, ifname2);
- }
+ wext_check_hostap(drv);
netlink_send_oper_ifla(drv->netlink, drv->ifindex,
1, IF_OPER_DORMANT);
diff --git a/src/eap_common/eap_fast_common.c b/src/eap_common/eap_fast_common.c
index fceb1b0a..151cc785 100644
--- a/src/eap_common/eap_fast_common.c
+++ b/src/eap_common/eap_fast_common.c
@@ -96,49 +96,18 @@ void eap_fast_derive_master_secret(const u8 *pac_key, const u8 *server_random,
u8 * eap_fast_derive_key(void *ssl_ctx, struct tls_connection *conn,
const char *label, size_t len)
{
- struct tls_keys keys;
- u8 *rnd = NULL, *out;
- int block_size;
+ u8 *out;
- block_size = tls_connection_get_keyblock_size(ssl_ctx, conn);
- if (block_size < 0)
- return NULL;
-
- out = os_malloc(block_size + len);
+ out = os_malloc(len);
if (out == NULL)
return NULL;
- if (tls_connection_prf(ssl_ctx, conn, label, 1, out, block_size + len)
- == 0) {
- os_memmove(out, out + block_size, len);
- return out;
+ if (tls_connection_prf(ssl_ctx, conn, label, 1, 1, out, len)) {
+ os_free(out);
+ return NULL;
}
- if (tls_connection_get_keys(ssl_ctx, conn, &keys))
- goto fail;
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
-
- os_memcpy(rnd, keys.server_random, keys.server_random_len);
- os_memcpy(rnd + keys.server_random_len, keys.client_random,
- keys.client_random_len);
-
- wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: master_secret for key "
- "expansion", keys.master_key, keys.master_key_len);
- if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, block_size + len))
- goto fail;
- os_free(rnd);
- os_memmove(out, out + block_size, len);
return out;
-
-fail:
- os_free(rnd);
- os_free(out);
- return NULL;
}
diff --git a/src/eap_common/eap_pwd_common.c b/src/eap_common/eap_pwd_common.c
index 631c363f..4d27623f 100644
--- a/src/eap_common/eap_pwd_common.c
+++ b/src/eap_common/eap_pwd_common.c
@@ -86,9 +86,10 @@ static int eap_pwd_kdf(const u8 *key, size_t keylen, const u8 *label,
* on the password and identities.
*/
int compute_password_element(EAP_PWD_group *grp, u16 num,
- u8 *password, int password_len,
- u8 *id_server, int id_server_len,
- u8 *id_peer, int id_peer_len, u8 *token)
+ const u8 *password, size_t password_len,
+ const u8 *id_server, size_t id_server_len,
+ const u8 *id_peer, size_t id_peer_len,
+ const u8 *token)
{
BIGNUM *x_candidate = NULL, *rnd = NULL, *cofactor = NULL;
struct crypto_hash *hash;
@@ -283,10 +284,10 @@ int compute_password_element(EAP_PWD_group *grp, u16 num,
}
-int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
- BIGNUM *peer_scalar, BIGNUM *server_scalar,
- u8 *confirm_peer, u8 *confirm_server,
- u32 *ciphersuite, u8 *msk, u8 *emsk, u8 *session_id)
+int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, const BIGNUM *k,
+ const BIGNUM *peer_scalar, const BIGNUM *server_scalar,
+ const u8 *confirm_peer, const u8 *confirm_server,
+ const u32 *ciphersuite, u8 *msk, u8 *emsk, u8 *session_id)
{
struct crypto_hash *hash;
u8 mk[SHA256_MAC_LEN], *cruft;
@@ -306,7 +307,7 @@ int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, BIGNUM *k,
os_free(cruft);
return -1;
}
- eap_pwd_h_update(hash, (u8 *) ciphersuite, sizeof(u32));
+ eap_pwd_h_update(hash, (const u8 *) ciphersuite, sizeof(u32));
offset = BN_num_bytes(grp->order) - BN_num_bytes(peer_scalar);
os_memset(cruft, 0, BN_num_bytes(grp->prime));
BN_bn2bin(peer_scalar, cruft + offset);
diff --git a/src/eap_common/eap_pwd_common.h b/src/eap_common/eap_pwd_common.h
index c54c4414..a0d717ed 100644
--- a/src/eap_common/eap_pwd_common.h
+++ b/src/eap_common/eap_pwd_common.h
@@ -56,10 +56,15 @@ struct eap_pwd_id {
} STRUCT_PACKED;
/* common routines */
-int compute_password_element(EAP_PWD_group *, u16, u8 *, int, u8 *, int, u8 *,
- int, u8 *);
-int compute_keys(EAP_PWD_group *, BN_CTX *, BIGNUM *, BIGNUM *, BIGNUM *,
- u8 *, u8 *, u32 *, u8 *, u8 *, u8 *);
+int compute_password_element(EAP_PWD_group *grp, u16 num,
+ const u8 *password, size_t password_len,
+ const u8 *id_server, size_t id_server_len,
+ const u8 *id_peer, size_t id_peer_len,
+ const u8 *token);
+int compute_keys(EAP_PWD_group *grp, BN_CTX *bnctx, const BIGNUM *k,
+ const BIGNUM *peer_scalar, const BIGNUM *server_scalar,
+ const u8 *confirm_peer, const u8 *confirm_server,
+ const u32 *ciphersuite, u8 *msk, u8 *emsk, u8 *session_id);
struct crypto_hash * eap_pwd_h_init(void);
void eap_pwd_h_update(struct crypto_hash *hash, const u8 *data, size_t len);
void eap_pwd_h_final(struct crypto_hash *hash, u8 *digest);
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index 35433f3b..fc4af953 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -2400,7 +2400,7 @@ static int eap_allowed_phase2_type(int vendor, int type)
u32 eap_get_phase2_type(const char *name, int *vendor)
{
int v;
- u8 type = eap_peer_get_type(name, &v);
+ u32 type = eap_peer_get_type(name, &v);
if (eap_allowed_phase2_type(v, type)) {
*vendor = v;
return type;
diff --git a/src/eap_peer/eap_pwd.c b/src/eap_peer/eap_pwd.c
index 059bbeec..f2b09266 100644
--- a/src/eap_peer/eap_pwd.c
+++ b/src/eap_peer/eap_pwd.c
@@ -10,6 +10,7 @@
#include "common.h"
#include "crypto/sha256.h"
+#include "crypto/ms_funcs.h"
#include "eap_peer/eap_i.h"
#include "eap_common/eap_pwd_common.h"
@@ -25,6 +26,7 @@ struct eap_pwd_data {
size_t id_server_len;
u8 *password;
size_t password_len;
+ int password_hash;
u16 group_num;
EAP_PWD_group *grp;
@@ -86,8 +88,9 @@ static void * eap_pwd_init(struct eap_sm *sm)
const u8 *identity, *password;
size_t identity_len, password_len;
int fragment_size;
+ int pwhash;
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (password == NULL) {
wpa_printf(MSG_INFO, "EAP-PWD: No password configured!");
return NULL;
@@ -129,6 +132,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
}
os_memcpy(data->password, password, password_len);
data->password_len = password_len;
+ data->password_hash = pwhash;
data->out_frag_pos = data->in_frag_pos = 0;
data->inbuf = data->outbuf = NULL;
@@ -216,6 +220,10 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
struct eap_pwd_id *id;
+ const u8 *password;
+ size_t password_len;
+ u8 pwhashhash[16];
+ int res;
if (data->state != PWD_ID_Req) {
ret->ignore = TRUE;
@@ -231,6 +239,9 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
id = (struct eap_pwd_id *) payload;
data->group_num = be_to_host16(id->group_num);
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Server EAP-pwd-ID proposal: group=%u random=%u prf=%u prep=%u",
+ data->group_num, id->random_function, id->prf, id->prep);
if ((id->random_function != EAP_PWD_DEFAULT_RAND_FUNC) ||
(id->prf != EAP_PWD_DEFAULT_PRF)) {
ret->ignore = TRUE;
@@ -238,6 +249,22 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
return;
}
+ if (id->prep != EAP_PWD_PREP_NONE &&
+ id->prep != EAP_PWD_PREP_MS) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Unsupported password pre-processing technique (Prep=%u)",
+ id->prep);
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
+ if (id->prep == EAP_PWD_PREP_NONE && data->password_hash) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-PWD: Unhashed password not available");
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
wpa_printf(MSG_DEBUG, "EAP-PWD (peer): using group %d",
data->group_num);
@@ -260,12 +287,39 @@ eap_pwd_perform_id_exchange(struct eap_sm *sm, struct eap_pwd_data *data,
return;
}
+ if (id->prep == EAP_PWD_PREP_MS) {
+ if (data->password_hash) {
+ res = hash_nt_password_hash(data->password, pwhashhash);
+ } else {
+ u8 pwhash[16];
+
+ res = nt_password_hash(data->password,
+ data->password_len, pwhash);
+ if (res == 0)
+ res = hash_nt_password_hash(pwhash, pwhashhash);
+ os_memset(pwhash, 0, sizeof(pwhash));
+ }
+
+ if (res) {
+ eap_pwd_state(data, FAILURE);
+ return;
+ }
+
+ password = pwhashhash;
+ password_len = sizeof(pwhashhash);
+ } else {
+ password = data->password;
+ password_len = data->password_len;
+ }
+
/* compute PWE */
- if (compute_password_element(data->grp, data->group_num,
- data->password, data->password_len,
- data->id_server, data->id_server_len,
- data->id_peer, data->id_peer_len,
- id->token)) {
+ res = compute_password_element(data->grp, data->group_num,
+ password, password_len,
+ data->id_server, data->id_server_len,
+ data->id_peer, data->id_peer_len,
+ id->token);
+ os_memset(pwhashhash, 0, sizeof(pwhashhash));
+ if (res) {
wpa_printf(MSG_INFO, "EAP-PWD (peer): unable to compute PWE");
eap_pwd_state(data, FAILURE);
return;
diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c
index 87107816..15c1bac5 100644
--- a/src/eap_peer/eap_tls_common.c
+++ b/src/eap_peer/eap_tls_common.c
@@ -313,53 +313,19 @@ void eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
u8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
const char *label, size_t len)
{
-#ifndef CONFIG_FIPS
- struct tls_keys keys;
-#endif /* CONFIG_FIPS */
- u8 *rnd = NULL, *out;
+ u8 *out;
out = os_malloc(len);
if (out == NULL)
return NULL;
- /* First, try to use TLS library function for PRF, if available. */
- if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, out, len)
- == 0)
- return out;
-
-#ifndef CONFIG_FIPS
- /*
- * TLS library did not support key generation, so get the needed TLS
- * session parameters and use an internal implementation of TLS PRF to
- * derive the key.
- */
- if (tls_connection_get_keys(data->ssl_ctx, data->conn, &keys))
- goto fail;
-
- if (keys.client_random == NULL || keys.server_random == NULL ||
- keys.master_key == NULL)
- goto fail;
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
- os_memcpy(rnd, keys.client_random, keys.client_random_len);
- os_memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
- goto fail;
+ if (tls_connection_prf(data->ssl_ctx, data->conn, label, 0, 0,
+ out, len)) {
+ os_free(out);
+ return NULL;
+ }
- os_free(rnd);
return out;
-
-fail:
-#endif /* CONFIG_FIPS */
- os_free(out);
- os_free(rnd);
- return NULL;
}
@@ -1032,7 +998,7 @@ int eap_peer_select_phase2_methods(struct eap_peer_config *config,
{
char *start, *pos, *buf;
struct eap_method_type *methods = NULL, *_methods;
- u8 method;
+ u32 method;
size_t num_methods = 0, prefix_len;
if (config == NULL || config->phase2 == NULL)
diff --git a/src/eap_server/eap.h b/src/eap_server/eap.h
index 9de6cb62..b825e18f 100644
--- a/src/eap_server/eap.h
+++ b/src/eap_server/eap.h
@@ -149,5 +149,8 @@ int eap_sm_method_pending(struct eap_sm *sm);
const u8 * eap_get_identity(struct eap_sm *sm, size_t *len);
struct eap_eapol_interface * eap_get_interface(struct eap_sm *sm);
void eap_server_clear_identity(struct eap_sm *sm);
+void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source,
+ const u8 *username, size_t username_len,
+ const u8 *challenge, const u8 *response);
#endif /* EAP_H */
diff --git a/src/eap_server/eap_server.c b/src/eap_server/eap_server.c
index bd919e57..693debe8 100644
--- a/src/eap_server/eap_server.c
+++ b/src/eap_server/eap_server.c
@@ -1979,3 +1979,25 @@ void eap_server_clear_identity(struct eap_sm *sm)
os_free(sm->identity);
sm->identity = NULL;
}
+
+
+#ifdef CONFIG_TESTING_OPTIONS
+void eap_server_mschap_rx_callback(struct eap_sm *sm, const char *source,
+ const u8 *username, size_t username_len,
+ const u8 *challenge, const u8 *response)
+{
+ char hex_challenge[30], hex_response[90], user[100];
+
+ /* Print out Challenge and Response in format supported by asleap. */
+ if (username)
+ printf_encode(user, sizeof(user), username, username_len);
+ else
+ user[0] = '\0';
+ wpa_snprintf_hex_sep(hex_challenge, sizeof(hex_challenge),
+ challenge, sizeof(challenge), ':');
+ wpa_snprintf_hex_sep(hex_response, sizeof(hex_response), response, 24,
+ ':');
+ wpa_printf(MSG_DEBUG, "[%s/user=%s] asleap -C %s -R %s",
+ source, user, hex_challenge, hex_response);
+}
+#endif /* CONFIG_TESTING_OPTIONS */
diff --git a/src/eap_server/eap_server_mschapv2.c b/src/eap_server/eap_server_mschapv2.c
index 05848d2e..98d74e0d 100644
--- a/src/eap_server/eap_server_mschapv2.c
+++ b/src/eap_server/eap_server_mschapv2.c
@@ -360,6 +360,19 @@ static void eap_mschapv2_process_response(struct eap_sm *sm,
}
}
+#ifdef CONFIG_TESTING_OPTIONS
+ {
+ u8 challenge[8];
+
+ if (challenge_hash(peer_challenge, data->auth_challenge,
+ username, username_len, challenge) == 0) {
+ eap_server_mschap_rx_callback(sm, "EAP-MSCHAPV2",
+ username, username_len,
+ challenge, nt_response);
+ }
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
+
if (username_len != user_len ||
os_memcmp(username, user, username_len) != 0) {
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Mismatch in user names");
diff --git a/src/eap_server/eap_server_peap.c b/src/eap_server/eap_server_peap.c
index faa0fd2f..3848f308 100644
--- a/src/eap_server/eap_server_peap.c
+++ b/src/eap_server/eap_server_peap.c
@@ -539,15 +539,14 @@ static Boolean eap_peap_check(struct eap_sm *sm, void *priv,
static int eap_peap_phase2_init(struct eap_sm *sm, struct eap_peap_data *data,
- EapType eap_type)
+ int vendor, EapType eap_type)
{
if (data->phase2_priv && data->phase2_method) {
data->phase2_method->reset(sm, data->phase2_priv);
data->phase2_method = NULL;
data->phase2_priv = NULL;
}
- data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
- eap_type);
+ data->phase2_method = eap_server_get_eap_method(vendor, eap_type);
if (!data->phase2_method)
return -1;
@@ -737,7 +736,7 @@ static void eap_peap_process_phase2_soh(struct eap_sm *sm,
const u8 *soh_tlv = NULL;
size_t soh_tlv_len = 0;
int tlv_type, mandatory, tlv_len, vtlv_len;
- u8 next_type;
+ u32 next_type;
u32 vendor_id;
pos = eap_hdr_validate(EAP_VENDOR_MICROSOFT, 0x21, in_data, &left);
@@ -852,8 +851,9 @@ auth_method:
eap_peap_state(data, PHASE2_METHOD);
next_type = sm->user->methods[0].method;
sm->user_eap_method_index = 1;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
- eap_peap_phase2_init(sm, data, next_type);
+ wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type %d",
+ sm->user->methods[0].vendor, next_type);
+ eap_peap_phase2_init(sm, data, sm->user->methods[0].vendor, next_type);
}
#endif /* EAP_SERVER_TNC */
@@ -862,7 +862,8 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
struct eap_peap_data *data,
struct wpabuf *in_data)
{
- u8 next_type = EAP_TYPE_NONE;
+ int next_vendor = EAP_VENDOR_IETF;
+ u32 next_type = EAP_TYPE_NONE;
const struct eap_hdr *hdr;
const u8 *pos;
size_t left;
@@ -894,17 +895,23 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
"allowed types", pos + 1, left - 1);
eap_sm_process_nak(sm, pos + 1, left - 1);
if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
- sm->user->methods[sm->user_eap_method_index].method !=
- EAP_TYPE_NONE) {
+ (sm->user->methods[sm->user_eap_method_index].vendor !=
+ EAP_VENDOR_IETF ||
+ sm->user->methods[sm->user_eap_method_index].method !=
+ EAP_TYPE_NONE)) {
+ next_vendor = sm->user->methods[
+ sm->user_eap_method_index].vendor;
next_type = sm->user->methods[
sm->user_eap_method_index++].method;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d",
- next_type);
+ wpa_printf(MSG_DEBUG,
+ "EAP-PEAP: try EAP vendor %d type 0x%x",
+ next_vendor, next_type);
} else {
eap_peap_req_failure(sm, data);
+ next_vendor = EAP_VENDOR_IETF;
next_type = EAP_TYPE_NONE;
}
- eap_peap_phase2_init(sm, data, next_type);
+ eap_peap_phase2_init(sm, data, next_vendor, next_type);
return;
}
@@ -929,8 +936,9 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
if (!data->phase2_method->isSuccess(sm, data->phase2_priv)) {
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 method failed");
eap_peap_req_failure(sm, data);
+ next_vendor = EAP_VENDOR_IETF;
next_type = EAP_TYPE_NONE;
- eap_peap_phase2_init(sm, data, next_type);
+ eap_peap_phase2_init(sm, data, next_vendor, next_type);
return;
}
@@ -942,7 +950,8 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase2 getKey "
"failed");
eap_peap_req_failure(sm, data);
- eap_peap_phase2_init(sm, data, EAP_TYPE_NONE);
+ eap_peap_phase2_init(sm, data, EAP_VENDOR_IETF,
+ EAP_TYPE_NONE);
return;
}
}
@@ -957,6 +966,7 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
"database",
sm->identity, sm->identity_len);
eap_peap_req_failure(sm, data);
+ next_vendor = EAP_VENDOR_IETF;
next_type = EAP_TYPE_NONE;
break;
}
@@ -967,18 +977,22 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
eap_peap_state(data, PHASE2_SOH);
wpa_printf(MSG_DEBUG, "EAP-PEAP: Try to initialize "
"TNC (NAP SOH)");
+ next_vendor = EAP_VENDOR_IETF;
next_type = EAP_TYPE_NONE;
break;
}
#endif /* EAP_SERVER_TNC */
eap_peap_state(data, PHASE2_METHOD);
+ next_vendor = sm->user->methods[0].vendor;
next_type = sm->user->methods[0].method;
sm->user_eap_method_index = 1;
- wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP type %d", next_type);
+ wpa_printf(MSG_DEBUG, "EAP-PEAP: try EAP vendor %d type 0x%x",
+ next_vendor, next_type);
break;
case PHASE2_METHOD:
eap_peap_req_success(sm, data);
+ next_vendor = EAP_VENDOR_IETF;
next_type = EAP_TYPE_NONE;
break;
case FAILURE:
@@ -989,7 +1003,7 @@ static void eap_peap_process_phase2_response(struct eap_sm *sm,
break;
}
- eap_peap_phase2_init(sm, data, next_type);
+ eap_peap_phase2_init(sm, data, next_vendor, next_type);
}
@@ -1133,7 +1147,8 @@ static void eap_peap_process_msg(struct eap_sm *sm, void *priv,
break;
case PHASE2_START:
eap_peap_state(data, PHASE2_ID);
- eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY);
+ eap_peap_phase2_init(sm, data, EAP_VENDOR_IETF,
+ EAP_TYPE_IDENTITY);
break;
case PHASE1_ID2:
case PHASE2_ID:
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index 943af0d1..66bd5d2e 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -10,6 +10,7 @@
#include "common.h"
#include "crypto/sha256.h"
+#include "crypto/ms_funcs.h"
#include "eap_server/eap_i.h"
#include "eap_common/eap_pwd_common.h"
@@ -24,6 +25,7 @@ struct eap_pwd_data {
size_t id_server_len;
u8 *password;
size_t password_len;
+ int password_hash;
u32 token;
u16 group_num;
EAP_PWD_group *grp;
@@ -112,6 +114,7 @@ static void * eap_pwd_init(struct eap_sm *sm)
}
data->password_len = sm->user->password_len;
os_memcpy(data->password, sm->user->password, data->password_len);
+ data->password_hash = sm->user->password_hash;
data->bnctx = BN_CTX_new();
if (data->bnctx == NULL) {
@@ -181,7 +184,8 @@ static void eap_pwd_build_id_req(struct eap_sm *sm, struct eap_pwd_data *data,
wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_RAND_FUNC);
wpabuf_put_u8(data->outbuf, EAP_PWD_DEFAULT_PRF);
wpabuf_put_data(data->outbuf, &data->token, sizeof(data->token));
- wpabuf_put_u8(data->outbuf, EAP_PWD_PREP_NONE);
+ wpabuf_put_u8(data->outbuf, data->password_hash ? EAP_PWD_PREP_MS :
+ EAP_PWD_PREP_NONE);
wpabuf_put_data(data->outbuf, data->id_server, data->id_server_len);
}
@@ -579,6 +583,10 @@ static void eap_pwd_process_id_resp(struct eap_sm *sm,
const u8 *payload, size_t payload_len)
{
struct eap_pwd_id *id;
+ const u8 *password;
+ size_t password_len;
+ u8 pwhashhash[16];
+ int res;
if (payload_len < sizeof(struct eap_pwd_id)) {
wpa_printf(MSG_INFO, "EAP-pwd: Invalid ID response");
@@ -610,11 +618,25 @@ static void eap_pwd_process_id_resp(struct eap_sm *sm,
"group");
return;
}
- if (compute_password_element(data->grp, data->group_num,
- data->password, data->password_len,
- data->id_server, data->id_server_len,
- data->id_peer, data->id_peer_len,
- (u8 *) &data->token)) {
+
+ if (data->password_hash) {
+ res = hash_nt_password_hash(data->password, pwhashhash);
+ if (res)
+ return;
+ password = pwhashhash;
+ password_len = sizeof(pwhashhash);
+ } else {
+ password = data->password;
+ password_len = data->password_len;
+ }
+
+ res = compute_password_element(data->grp, data->group_num,
+ password, password_len,
+ data->id_server, data->id_server_len,
+ data->id_peer, data->id_peer_len,
+ (u8 *) &data->token);
+ os_memset(pwhashhash, 0, sizeof(pwhashhash));
+ if (res) {
wpa_printf(MSG_INFO, "EAP-PWD (server): unable to compute "
"PWE");
return;
diff --git a/src/eap_server/eap_server_tls_common.c b/src/eap_server/eap_server_tls_common.c
index 56916c45..23498c99 100644
--- a/src/eap_server/eap_server_tls_common.c
+++ b/src/eap_server/eap_server_tls_common.c
@@ -100,43 +100,19 @@ void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data)
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
char *label, size_t len)
{
- struct tls_keys keys;
- u8 *rnd = NULL, *out;
+ u8 *out;
out = os_malloc(len);
if (out == NULL)
return NULL;
- if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) ==
- 0)
- return out;
-
- if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
- goto fail;
-
- if (keys.client_random == NULL || keys.server_random == NULL ||
- keys.master_key == NULL)
- goto fail;
-
- rnd = os_malloc(keys.client_random_len + keys.server_random_len);
- if (rnd == NULL)
- goto fail;
- os_memcpy(rnd, keys.client_random, keys.client_random_len);
- os_memcpy(rnd + keys.client_random_len, keys.server_random,
- keys.server_random_len);
-
- if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len,
- label, rnd, keys.client_random_len +
- keys.server_random_len, out, len))
- goto fail;
+ if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, 0,
+ out, len)) {
+ os_free(out);
+ return NULL;
+ }
- os_free(rnd);
return out;
-
-fail:
- os_free(out);
- os_free(rnd);
- return NULL;
}
diff --git a/src/eap_server/eap_server_ttls.c b/src/eap_server/eap_server_ttls.c
index 12a31b07..31c67e8f 100644
--- a/src/eap_server/eap_server_ttls.c
+++ b/src/eap_server/eap_server_ttls.c
@@ -618,6 +618,12 @@ static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
return;
}
+#ifdef CONFIG_TESTING_OPTIONS
+ eap_server_mschap_rx_callback(sm, "TTLS-MSCHAP",
+ sm->identity, sm->identity_len,
+ challenge, response + 2 + 24);
+#endif /* CONFIG_TESTING_OPTIONS */
+
if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
!= 0 ||
response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
@@ -740,6 +746,18 @@ static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
}
rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
+#ifdef CONFIG_TESTING_OPTIONS
+ {
+ u8 challenge2[8];
+
+ if (challenge_hash(peer_challenge, auth_challenge,
+ username, username_len, challenge2) == 0) {
+ eap_server_mschap_rx_callback(sm, "TTLS-MSCHAPV2",
+ username, username_len,
+ challenge2, rx_resp);
+ }
+ }
+#endif /* CONFIG_TESTING_OPTIONS */
if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
"NT-Response");
diff --git a/src/radius/radius_server.c b/src/radius/radius_server.c
index 85a485e9..3f881cf3 100644
--- a/src/radius/radius_server.c
+++ b/src/radius/radius_server.c
@@ -2035,6 +2035,12 @@ static int radius_server_get_eap_user(void *ctx, const u8 *identity,
sess->remediation = user->remediation;
sess->macacl = user->macacl;
}
+
+ if (ret) {
+ RADIUS_DEBUG("%s: User-Name not found from user database",
+ __func__);
+ }
+
return ret;
}
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index cb334df6..0d96216d 100644
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
@@ -30,6 +30,9 @@ int wpa_parse_wpa_ie(const u8 *wpa_ie, size_t wpa_ie_len,
{
if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
+ if (wpa_ie_len >= 6 && wpa_ie[0] == WLAN_EID_VENDOR_SPECIFIC &&
+ wpa_ie[1] >= 4 && WPA_GET_BE32(&wpa_ie[2]) == OSEN_IE_VENDOR_TYPE)
+ return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
else
return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
}
diff --git a/src/tls/tlsv1_client.c b/src/tls/tlsv1_client.c
index facdd659..533286c1 100644
--- a/src/tls/tlsv1_client.c
+++ b/src/tls/tlsv1_client.c
@@ -731,8 +731,6 @@ int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys)
if (conn->state != SERVER_HELLO) {
keys->server_random = conn->server_random;
keys->server_random_len = TLS_RANDOM_LEN;
- keys->master_key = conn->master_secret;
- keys->master_key_len = TLS_MASTER_SECRET_LEN;
}
return 0;
diff --git a/src/tls/tlsv1_server.c b/src/tls/tlsv1_server.c
index 93ae4888..4df756f7 100644
--- a/src/tls/tlsv1_server.c
+++ b/src/tls/tlsv1_server.c
@@ -627,8 +627,6 @@ int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
if (conn->state != SERVER_HELLO) {
keys->server_random = conn->server_random;
keys->server_random_len = TLS_RANDOM_LEN;
- keys->master_key = conn->master_secret;
- keys->master_key_len = TLS_MASTER_SECRET_LEN;
}
return 0;
diff --git a/src/utils/common.c b/src/utils/common.c
index 5fd795f3..0bdc38db 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -277,6 +277,31 @@ int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...)
return ret;
}
+
+int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len,
+ char sep)
+{
+ size_t i;
+ char *pos = buf, *end = buf + buf_size;
+ int ret;
+
+ if (buf_size == 0)
+ return 0;
+
+ for (i = 0; i < len; i++) {
+ ret = os_snprintf(pos, end - pos, "%02x%c",
+ data[i], sep);
+ if (os_snprintf_error(end - pos, ret)) {
+ end[-1] = '\0';
+ return pos - buf;
+ }
+ pos += ret;
+ }
+ pos[-1] = '\0';
+ return pos - buf;
+}
+
+
static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
size_t len, int uppercase)
{
diff --git a/src/utils/common.h b/src/utils/common.h
index 576e8e7e..a0eda4a2 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -480,6 +480,8 @@ int hexstr2bin(const char *hex, u8 *buf, size_t len);
void inc_byte_array(u8 *counter, size_t len);
void wpa_get_ntp_timestamp(u8 *buf);
int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...);
+int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len,
+ char sep);
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len);
diff --git a/src/utils/http_curl.c b/src/utils/http_curl.c
index b38cf796..653eb541 100644
--- a/src/utils/http_curl.c
+++ b/src/utils/http_curl.c
@@ -855,8 +855,10 @@ static int validate_server_cert(struct http_ctx *ctx, X509 *cert)
struct http_cert hcert;
int ret;
- if (ctx->cert_cb == NULL)
+ if (ctx->cert_cb == NULL) {
+ wpa_printf(MSG_DEBUG, "%s: no cert_cb configured", __func__);
return 0;
+ }
if (0) {
BIO *out;
@@ -950,7 +952,8 @@ static int curl_cb_ssl_verify(int preverify_ok, X509_STORE_CTX *x509_ctx)
ssl_ctx = ssl->ctx;
ctx = SSL_CTX_get_app_data(ssl_ctx);
- wpa_printf(MSG_DEBUG, "curl_cb_ssl_verify");
+ wpa_printf(MSG_DEBUG, "curl_cb_ssl_verify, preverify_ok: %d",
+ preverify_ok);
err = X509_STORE_CTX_get_error(x509_ctx);
err_str = X509_verify_cert_error_string(err);
@@ -1249,9 +1252,14 @@ static CURL * setup_curl_post(struct http_ctx *ctx, const char *address,
const char *client_key)
{
CURL *curl;
+#ifdef EAP_TLS_OPENSSL
+ const char *extra = " tls=openssl";
+#else /* EAP_TLS_OPENSSL */
+ const char *extra = "";
+#endif /* EAP_TLS_OPENSSL */
wpa_printf(MSG_DEBUG, "Start HTTP client: address=%s ca_fname=%s "
- "username=%s", address, ca_fname, username);
+ "username=%s%s", address, ca_fname, username, extra);
curl = curl_easy_init();
if (curl == NULL)