[pkg-wpa-devel] r880 - in /wpasupplicant/trunk: debian/ debian/patches/ patches/ src/common/ src/crypto/ src/drivers/ src/eap_common/ src/eap_peer/ src/eap_server/ src/l2_packet/ src/radius/ src/rsn_supp/ src/tls/ src/utils/ wpa_supplicant/ wpa_supplicant/doc/ wpa_supplicant/doc/docbook/ wpa_supplicant/tests/
kelmo-guest at users.alioth.debian.org
kelmo-guest at users.alioth.debian.org
Sat Nov 3 11:46:49 UTC 2007
Author: kelmo-guest
Date: Sat Nov 3 11:46:49 2007
New Revision: 880
URL: http://svn.debian.org/wsvn/pkg-wpa/?sc=1&rev=880
Log:
* New upstream git snapshot.
* Build depend on docbook and docbook-utils to generate upstream manpages
from sgml source.a
* Upstream wpa_cli(8) is no longer incorrect with regard to CONNECTED and
DISCONNECTED signal events. (Closes: #432904)
Added:
wpasupplicant/trunk/patches/openssl-0.9.8g-tls-extensions.patch
- copied unchanged from r879, wpasupplicant/branches/upstream/current/patches/openssl-0.9.8g-tls-extensions.patch
wpasupplicant/trunk/patches/openssl-0.9.9-session-ticket.patch
- copied unchanged from r879, wpasupplicant/branches/upstream/current/patches/openssl-0.9.9-session-ticket.patch
wpasupplicant/trunk/src/drivers/Apple80211.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/drivers/Apple80211.h
wpasupplicant/trunk/src/drivers/MobileApple80211.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.c
wpasupplicant/trunk/src/drivers/MobileApple80211.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/drivers/MobileApple80211.h
wpasupplicant/trunk/src/drivers/driver_iphone.m
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/drivers/driver_iphone.m
wpasupplicant/trunk/src/drivers/driver_osx.m
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/drivers/driver_osx.m
wpasupplicant/trunk/src/eap_common/eap_fast_common.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/eap_common/eap_fast_common.h
wpasupplicant/trunk/src/eap_common/eap_tlv_common.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/eap_common/eap_tlv_common.h
wpasupplicant/trunk/src/eap_server/eap_fast.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/eap_server/eap_fast.c
wpasupplicant/trunk/src/tls/tlsv1_client_i.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_client_i.h
wpasupplicant/trunk/src/tls/tlsv1_client_read.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_client_read.c
wpasupplicant/trunk/src/tls/tlsv1_client_write.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_client_write.c
wpasupplicant/trunk/src/tls/tlsv1_cred.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_cred.c
wpasupplicant/trunk/src/tls/tlsv1_cred.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_cred.h
wpasupplicant/trunk/src/tls/tlsv1_record.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_record.c
wpasupplicant/trunk/src/tls/tlsv1_record.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_record.h
wpasupplicant/trunk/src/tls/tlsv1_server.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_server.c
wpasupplicant/trunk/src/tls/tlsv1_server.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_server.h
wpasupplicant/trunk/src/tls/tlsv1_server_i.h
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_i.h
wpasupplicant/trunk/src/tls/tlsv1_server_read.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_read.c
wpasupplicant/trunk/src/tls/tlsv1_server_write.c
- copied unchanged from r879, wpasupplicant/branches/upstream/current/src/tls/tlsv1_server_write.c
wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3_nist.sh
- copied unchanged from r879, wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_x509v3_nist.sh
wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3_nist2.sh
- copied unchanged from r879, wpasupplicant/branches/upstream/current/wpa_supplicant/tests/test_x509v3_nist2.sh
Removed:
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_background.8
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.8
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_passphrase.8
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.8
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_supplicant.conf.5
Modified:
wpasupplicant/trunk/debian/changelog
wpasupplicant/trunk/debian/control
wpasupplicant/trunk/debian/patches/00list
wpasupplicant/trunk/debian/rules
wpasupplicant/trunk/src/common/defs.h
wpasupplicant/trunk/src/common/wpa_common.c
wpasupplicant/trunk/src/common/wpa_common.h
wpasupplicant/trunk/src/crypto/aes_wrap.c
wpasupplicant/trunk/src/crypto/aes_wrap.h
wpasupplicant/trunk/src/crypto/crypto.h
wpasupplicant/trunk/src/crypto/crypto_internal.c
wpasupplicant/trunk/src/crypto/ms_funcs.c
wpasupplicant/trunk/src/crypto/ms_funcs.h
wpasupplicant/trunk/src/crypto/sha256.c
wpasupplicant/trunk/src/crypto/tls.h
wpasupplicant/trunk/src/crypto/tls_gnutls.c
wpasupplicant/trunk/src/crypto/tls_internal.c
wpasupplicant/trunk/src/crypto/tls_none.c
wpasupplicant/trunk/src/crypto/tls_openssl.c
wpasupplicant/trunk/src/crypto/tls_schannel.c
wpasupplicant/trunk/src/drivers/driver.h
wpasupplicant/trunk/src/drivers/driver_wext.c
wpasupplicant/trunk/src/drivers/drivers.c
wpasupplicant/trunk/src/eap_common/eap_gpsk_common.c
wpasupplicant/trunk/src/eap_common/eap_gpsk_common.h
wpasupplicant/trunk/src/eap_peer/eap.c
wpasupplicant/trunk/src/eap_peer/eap_fast.c
wpasupplicant/trunk/src/eap_peer/eap_fast_pac.h
wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
wpasupplicant/trunk/src/eap_peer/eap_gtc.c
wpasupplicant/trunk/src/eap_peer/eap_i.h
wpasupplicant/trunk/src/eap_peer/eap_leap.c
wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
wpasupplicant/trunk/src/eap_peer/eap_tlv.h
wpasupplicant/trunk/src/eap_peer/eap_ttls.c
wpasupplicant/trunk/src/eap_peer/tncc.c
wpasupplicant/trunk/src/eap_server/eap.c
wpasupplicant/trunk/src/eap_server/eap.h
wpasupplicant/trunk/src/eap_server/eap_gpsk.c
wpasupplicant/trunk/src/eap_server/eap_gtc.c
wpasupplicant/trunk/src/eap_server/eap_i.h
wpasupplicant/trunk/src/eap_server/eap_methods.c
wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
wpasupplicant/trunk/src/eap_server/eap_tlv.c
wpasupplicant/trunk/src/l2_packet/l2_packet_freebsd.c
wpasupplicant/trunk/src/radius/radius_client.c
wpasupplicant/trunk/src/radius/radius_server.c
wpasupplicant/trunk/src/radius/radius_server.h
wpasupplicant/trunk/src/rsn_supp/wpa_ft.c
wpasupplicant/trunk/src/tls/asn1.c
wpasupplicant/trunk/src/tls/tlsv1_client.c
wpasupplicant/trunk/src/tls/tlsv1_client.h
wpasupplicant/trunk/src/tls/tlsv1_common.c
wpasupplicant/trunk/src/tls/tlsv1_common.h
wpasupplicant/trunk/src/tls/x509v3.c
wpasupplicant/trunk/src/utils/common.h
wpasupplicant/trunk/src/utils/os_unix.c
wpasupplicant/trunk/wpa_supplicant/ChangeLog
wpasupplicant/trunk/wpa_supplicant/Makefile
wpasupplicant/trunk/wpa_supplicant/config.c
wpasupplicant/trunk/wpa_supplicant/config_ssid.h
wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c
wpasupplicant/trunk/wpa_supplicant/doc/ctrl_iface.doxygen
wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.sgml
wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
wpasupplicant/trunk/wpa_supplicant/eapol_test.c
wpasupplicant/trunk/wpa_supplicant/events.c
wpasupplicant/trunk/wpa_supplicant/mlme.c
wpasupplicant/trunk/wpa_supplicant/tests/test_aes.c
wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3.c
wpasupplicant/trunk/wpa_supplicant/todo.txt
wpasupplicant/trunk/wpa_supplicant/wpa_cli.c
wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf
wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h
Modified: wpasupplicant/trunk/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/changelog?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/changelog (original)
+++ wpasupplicant/trunk/debian/changelog Sat Nov 3 11:46:49 2007
@@ -1,5 +1,6 @@
-wpasupplicant (0.6.0-5) UNRELEASED; urgency=low
-
+wpasupplicant (0.6.1~git20071103-1) UNRELEASED; urgency=low
+
+ * New upstream git snapshot.
* Convert to non-cdbs traditional debhelper-centric debian/rules and remove
build dependency on cdbs. This converges with style of hostapd package.
* Correct poorly formatted debian/NEWS entry that was causing lintian to
@@ -23,8 +24,12 @@
/usr/share/dbus-1/system-service/. The filename reflects the service bus
name of "fi.epitest.hostap.WPASupplicant". In addition, the service must
be started by root user. Thanks to Michael Biebl. (Closes: #412179)
-
- -- Kel Modderman <kel at otaku42.de> Sat, 03 Nov 2007 17:03:52 +1000
+ * Build depend on docbook and docbook-utils to generate upstream manpages
+ from sgml source.a
+ * Upstream wpa_cli(8) is no longer incorrect with regard to CONNECTED and
+ DISCONNECTED signal events. (Closes: #432904)
+
+ -- Kel Modderman <kel at otaku42.de> Sat, 03 Nov 2007 20:39:25 +1000
wpasupplicant (0.6.0-4) unstable; urgency=low
Modified: wpasupplicant/trunk/debian/control
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/control?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/control (original)
+++ wpasupplicant/trunk/debian/control Sat Nov 3 11:46:49 2007
@@ -4,7 +4,7 @@
Maintainer: Debian/Ubuntu wpasupplicant Maintainers <pkg-wpa-devel at lists.alioth.debian.org>
Uploaders: Kyle McMartin <kyle at debian.org>, Reinhard Tartler <siretart at tauware.de>, Kel Modderman <kel at otaku42.de>
Standards-Version: 3.7.2
-Build-Depends: debhelper (>= 5), dpatch, libssl-dev, libreadline5-dev, libqt4-dev, libdbus-1-dev (>= 1.1.1-1)
+Build-Depends: debhelper (>= 5), dpatch, libssl-dev, libreadline5-dev, libqt4-dev, libdbus-1-dev (>= 1.1.1-1), docbook, docbook-utils
Vcs-Svn: svn://svn.debian.org/pkg-wpa/wpasupplicant/trunk
Vcs-Browser: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/
Homepage: http://w1.fi/wpa_supplicant/
Modified: wpasupplicant/trunk/debian/patches/00list
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/patches/00list?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/patches/00list (original)
+++ wpasupplicant/trunk/debian/patches/00list Sat Nov 3 11:46:49 2007
@@ -1,7 +1,4 @@
-10_fix_non_wpa_zero_len_ssid
20_madwifi_headers
30_dbus_policy
-40_debian_doc_examples
-50_fix_wext_tsf_stack_overflow
60_dbus_deprecated_get_fd
70_fix_deprecated_conversion_of_string_constant
Modified: wpasupplicant/trunk/debian/rules
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/debian/rules?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/debian/rules (original)
+++ wpasupplicant/trunk/debian/rules Sat Nov 3 11:46:49 2007
@@ -27,6 +27,9 @@
$(MAKE) -f debian/defconfig.mk DOTCONFIG=wpa_supplicant/.config
$(MAKE) -C wpa_supplicant
+ # manpages - docbook2man
+ $(MAKE) -C wpa_supplicant/doc/docbook man
+
# sanitise the example configuration
sed 's/^\([^#]\+=.*\|}\)/#\1/' < wpa_supplicant/wpa_supplicant.conf \
> README.wpa_supplicant.conf
@@ -43,6 +46,8 @@
rm -f build-stamp
$(MAKE) -C wpa_supplicant clean
+
+ $(MAKE) -C wpa_supplicant/doc/docbook clean
if [ -f wpa_supplicant/$(WPAGUI)/Makefile ]; then \
$(MAKE) -C wpa_supplicant/$(WPAGUI) distclean ; \
Modified: wpasupplicant/trunk/src/common/defs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/defs.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/defs.h (original)
+++ wpasupplicant/trunk/src/common/defs.h Sat Nov 3 11:46:49 2007
@@ -50,7 +50,7 @@
typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP,
- WPA_ALG_IGTK } wpa_alg;
+ WPA_ALG_IGTK, WPA_ALG_PMK } wpa_alg;
typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP,
CIPHER_WEP104 } wpa_cipher;
typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
Modified: wpasupplicant/trunk/src/common/wpa_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/wpa_common.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/wpa_common.c (original)
+++ wpasupplicant/trunk/src/common/wpa_common.c Sat Nov 3 11:46:49 2007
@@ -396,7 +396,7 @@
/**
* wpa_derive_pmk_r0 - Derive PMK-R0 and PMKR0Name
*
- * IEEE 802.11r/D5.0 - 8.5.1.5.3
+ * IEEE 802.11r/D8.0 - 8.5.1.5.3
*/
void wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
const u8 *ssid, size_t ssid_len,
@@ -410,7 +410,7 @@
size_t len[2];
/*
- * R0-Key-Data = KDF-384(XXKey, "R0 Key Derivation",
+ * R0-Key-Data = KDF-384(XXKey, "FT-R0",
* SSIDlength || SSID || MDID || R0KHlength ||
* R0KH-ID || S0KH-ID)
* XXKey is either the second 256 bits of MSK or PSK.
@@ -431,15 +431,15 @@
os_memcpy(pos, s0kh_id, ETH_ALEN);
pos += ETH_ALEN;
- sha256_prf(xxkey, xxkey_len, "R0 Key Derivation", buf, pos - buf,
+ sha256_prf(xxkey, xxkey_len, "FT-R0", buf, pos - buf,
r0_key_data, sizeof(r0_key_data));
os_memcpy(pmk_r0, r0_key_data, PMK_LEN);
/*
- * PMKR0Name = Truncate-128(SHA-256("R0 Key Name" || PMK-R0Name-Salt)
+ * PMKR0Name = Truncate-128(SHA-256("FT-R0" || PMK-R0Name-Salt)
*/
- addr[0] = (const u8 *) "R0 Key Name";
- len[0] = 11;
+ addr[0] = (const u8 *) "FT-R0";
+ len[0] = 5;
addr[1] = r0_key_data + PMK_LEN;
len[1] = 16;
@@ -451,7 +451,7 @@
/**
* wpa_derive_pmk_r1_name - Derive PMKR1Name
*
- * IEEE 802.11r/D5.0 - 8.5.1.5.4
+ * IEEE 802.11r/D8.0 - 8.5.1.5.4
*/
void wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
const u8 *s1kh_id, u8 *pmk_r1_name)
@@ -461,11 +461,11 @@
size_t len[4];
/*
- * PMKR1Name = Truncate-128(SHA-256("R1 Key Name" || PMKR0Name ||
+ * PMKR1Name = Truncate-128(SHA-256("FT-R1" || PMKR0Name ||
* R1KH-ID || S1KH-ID))
*/
- addr[0] = (const u8 *) "R1 Key Name";
- len[0] = 11;
+ addr[0] = (const u8 *) "FT-R1";
+ len[0] = 5;
addr[1] = pmk_r0_name;
len[1] = WPA_PMK_NAME_LEN;
addr[2] = r1kh_id;
@@ -481,7 +481,7 @@
/**
* wpa_derive_pmk_r1 - Derive PMK-R1 and PMKR1Name from PMK-R0
*
- * IEEE 802.11r/D5.0 - 8.5.1.5.4
+ * IEEE 802.11r/D8.0 - 8.5.1.5.4
*/
void wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name,
const u8 *r1kh_id, const u8 *s1kh_id,
@@ -490,15 +490,14 @@
u8 buf[FT_R1KH_ID_LEN + ETH_ALEN];
u8 *pos;
- /* PMK-R1 = KDF-256(PMK-R0, "R1 Key Derivation", R1KH-ID || S1KH-ID) */
+ /* PMK-R1 = KDF-256(PMK-R0, "FT-R1", R1KH-ID || S1KH-ID) */
pos = buf;
os_memcpy(pos, r1kh_id, FT_R1KH_ID_LEN);
pos += FT_R1KH_ID_LEN;
os_memcpy(pos, s1kh_id, ETH_ALEN);
pos += ETH_ALEN;
- sha256_prf(pmk_r0, PMK_LEN, "R1 Key Derivation", buf, pos - buf,
- pmk_r1, PMK_LEN);
+ sha256_prf(pmk_r0, PMK_LEN, "FT-R1", buf, pos - buf, pmk_r1, PMK_LEN);
wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, pmk_r1_name);
}
@@ -507,7 +506,7 @@
/**
* wpa_pmk_r1_to_ptk - Derive PTK and PTKName from PMK-R1
*
- * IEEE 802.11r/D5.0 - 8.5.1.5.5
+ * IEEE 802.11r/D8.0 - 8.5.1.5.5
*/
void wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
const u8 *sta_addr, const u8 *bssid,
@@ -520,7 +519,7 @@
size_t len[6];
/*
- * PTK = KDF-PTKLen(PMK-R1, "PTK Key derivation", SNonce || ANonce ||
+ * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
* BSSID || STA-ADDR)
*/
pos = buf;
@@ -533,17 +532,16 @@
os_memcpy(pos, sta_addr, ETH_ALEN);
pos += ETH_ALEN;
- sha256_prf(pmk_r1, PMK_LEN, "PTK Key derivation", buf, pos - buf,
- ptk, ptk_len);
+ sha256_prf(pmk_r1, PMK_LEN, "FT-PTK", buf, pos - buf, ptk, ptk_len);
/*
- * PTKName = Truncate-128(SHA-256(PMKR1Name || "PTK Name" || SNonce ||
+ * PTKName = Truncate-128(SHA-256(PMKR1Name || "FT-PTK" || SNonce ||
* ANonce || BSSID || STA-ADDR))
*/
addr[0] = pmk_r1_name;
len[0] = WPA_PMK_NAME_LEN;
- addr[1] = (const u8 *) "PTK Name";
- len[1] = 8;
+ addr[1] = (const u8 *) "FT-PTK";
+ len[1] = 6;
addr[2] = snonce;
len[2] = WPA_NONCE_LEN;
addr[3] = anonce;
Modified: wpasupplicant/trunk/src/common/wpa_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/common/wpa_common.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/common/wpa_common.h (original)
+++ wpasupplicant/trunk/src/common/wpa_common.h Sat Nov 3 11:46:49 2007
@@ -281,9 +281,8 @@
u8 ft_capab;
} STRUCT_PACKED;
-#define RSN_FT_CAPAB_FT_OVER_AIR BIT(0)
-#define RSN_FT_CAPAB_FT_OVER_DS BIT(1)
-#define RSN_FT_CAPAB_FT_RESOURCE_REQ_SUPP BIT(2)
+#define RSN_FT_CAPAB_FT_OVER_DS BIT(0)
+#define RSN_FT_CAPAB_FT_RESOURCE_REQ_SUPP BIT(1)
struct rsn_ftie {
u8 mic_control[2];
Modified: wpasupplicant/trunk/src/crypto/aes_wrap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/aes_wrap.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/aes_wrap.c (original)
+++ wpasupplicant/trunk/src/crypto/aes_wrap.c Sat Nov 3 11:46:49 2007
@@ -7,7 +7,7 @@
* - AES-128 EAX mode encryption/decryption
* - AES-128 CBC
*
- * Copyright (c) 2003-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2003-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -29,10 +29,11 @@
/**
* aes_wrap - Wrap keys with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
- * @kek: Key encryption key (KEK)
- * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
- * @plain: Plaintext key to be wrapped, n * 64 bit
- * @cipher: Wrapped key, (n + 1) * 64 bit
+ * @kek: 16-octet Key encryption key (KEK)
+ * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
+ * bytes
+ * @plain: Plaintext key to be wrapped, n * 64 bits
+ * @cipher: Wrapped key, (n + 1) * 64 bits
* Returns: 0 on success, -1 on failure
*/
int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher)
@@ -88,9 +89,10 @@
/**
* aes_unwrap - Unwrap key with AES Key Wrap Algorithm (128-bit KEK) (RFC3394)
* @kek: Key encryption key (KEK)
- * @n: Length of the wrapped key in 64-bit units; e.g., 2 = 128-bit = 16 bytes
- * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bit
- * @plain: Plaintext key, n * 64 bit
+ * @n: Length of the plaintext key in 64-bit units; e.g., 2 = 128-bit = 16
+ * bytes
+ * @cipher: Wrapped key to be unwrapped, (n + 1) * 64 bits
+ * @plain: Plaintext key, n * 64 bits
* Returns: 0 on success, -1 on failure (e.g., integrity verification failed)
*/
int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain)
@@ -162,10 +164,11 @@
/**
- * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
+ * omac1_aes_128_vector - One-Key CBC MAC (OMAC1) hash with AES-128
* @key: 128-bit key for the hash operation
- * @data: Data buffer for which a MAC is determined
- * @data: Length of data buffer in bytes
+ * @num_elem: Number of elements in the data vector
+ * @addr: Pointers to the data areas
+ * @len: Lengths of the data blocks
* @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
* Returns: 0 on success, -1 on failure
*
@@ -173,21 +176,37 @@
* OMAC1 was standardized with the name CMAC by NIST in a Special Publication
* (SP) 800-38B.
*/
-int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac)
{
void *ctx;
u8 cbc[BLOCK_SIZE], pad[BLOCK_SIZE];
- const u8 *pos = data;
- size_t i, left = data_len;
+ const u8 *pos, *end;
+ size_t i, e, left, total_len;
ctx = aes_encrypt_init(key, 16);
if (ctx == NULL)
return -1;
os_memset(cbc, 0, BLOCK_SIZE);
+ total_len = 0;
+ for (e = 0; e < num_elem; e++)
+ total_len += len[e];
+ left = total_len;
+
+ e = 0;
+ pos = addr[0];
+ end = pos + len[0];
+
while (left >= BLOCK_SIZE) {
- for (i = 0; i < BLOCK_SIZE; i++)
+ for (i = 0; i < BLOCK_SIZE; i++) {
cbc[i] ^= *pos++;
+ if (pos >= end) {
+ e++;
+ pos = addr[e];
+ end = pos + len[e];
+ }
+ }
if (left > BLOCK_SIZE)
aes_encrypt(ctx, cbc, cbc);
left -= BLOCK_SIZE;
@@ -197,9 +216,15 @@
aes_encrypt(ctx, pad, pad);
gf_mulx(pad);
- if (left || data_len == 0) {
- for (i = 0; i < left; i++)
+ if (left || total_len == 0) {
+ for (i = 0; i < left; i++) {
cbc[i] ^= *pos++;
+ if (pos >= end) {
+ e++;
+ pos = addr[e];
+ end = pos + len[e];
+ }
+ }
cbc[left] ^= 0x80;
gf_mulx(pad);
}
@@ -209,6 +234,24 @@
aes_encrypt(ctx, pad, mac);
aes_encrypt_deinit(ctx);
return 0;
+}
+
+
+/**
+ * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
+ * @key: 128-bit key for the hash operation
+ * @data: Data buffer for which a MAC is determined
+ * @data_len: Length of data buffer in bytes
+ * @mac: Buffer for MAC (128 bits, i.e., 16 bytes)
+ * Returns: 0 on success, -1 on failure
+ *
+ * This is a mode for using block cipher (AES in this case) for authentication.
+ * OMAC1 was standardized with the name CMAC by NIST in a Special Publication
+ * (SP) 800-38B.
+ */
+int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac)
+{
+ return omac1_aes_128_vector(key, 1, &data, &data_len, mac);
}
#endif /* CONFIG_NO_AES_OMAC1 */
Modified: wpasupplicant/trunk/src/crypto/aes_wrap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/aes_wrap.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/aes_wrap.h (original)
+++ wpasupplicant/trunk/src/crypto/aes_wrap.h Sat Nov 3 11:46:49 2007
@@ -7,7 +7,7 @@
* - AES-128 EAX mode encryption/decryption
* - AES-128 CBC
*
- * Copyright (c) 2003-2005, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2003-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -24,6 +24,8 @@
int aes_wrap(const u8 *kek, int n, const u8 *plain, u8 *cipher);
int aes_unwrap(const u8 *kek, int n, const u8 *cipher, u8 *plain);
+int omac1_aes_128_vector(const u8 *key, size_t num_elem,
+ const u8 *addr[], const size_t *len, u8 *mac);
int omac1_aes_128(const u8 *key, const u8 *data, size_t data_len, u8 *mac);
int aes_128_encrypt_block(const u8 *key, const u8 *in, u8 *out);
int aes_128_ctr_encrypt(const u8 *key, const u8 *nonce,
Modified: wpasupplicant/trunk/src/crypto/crypto.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/crypto.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/crypto.h (original)
+++ wpasupplicant/trunk/src/crypto/crypto.h Sat Nov 3 11:46:49 2007
@@ -316,6 +316,23 @@
int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
const u8 *in, size_t inlen,
u8 *out, size_t *outlen);
+
+/**
+ * crypto_private_key_decrypt_pkcs1_v15 - Private key decryption (PKCS #1 v1.5)
+ * @key: Private key
+ * @in: Encrypted buffer
+ * @inlen: Length of encrypted buffer in bytes
+ * @out: Output buffer for encrypted data
+ * @outlen: Length of output buffer in bytes; set to used length on success
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is only used with internal TLSv1 implementation
+ * (CONFIG_TLS=internal). If that is not used, the crypto wrapper does not need
+ * to implement this.
+ */
+int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
+ const u8 *in, size_t inlen,
+ u8 *out, size_t *outlen);
/**
* crypto_private_key_sign_pkcs1 - Sign with private key (PKCS #1)
Modified: wpasupplicant/trunk/src/crypto/crypto_internal.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/crypto_internal.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/crypto_internal.c (original)
+++ wpasupplicant/trunk/src/crypto/crypto_internal.c Sat Nov 3 11:46:49 2007
@@ -539,6 +539,39 @@
}
+int crypto_private_key_decrypt_pkcs1_v15(struct crypto_private_key *key,
+ const u8 *in, size_t inlen,
+ u8 *out, size_t *outlen)
+{
+ struct crypto_rsa_key *rkey = (struct crypto_rsa_key *) key;
+ int res;
+ u8 *pos, *end;
+
+ res = crypto_rsa_exptmod(in, inlen, out, outlen, rkey, 1);
+ if (res)
+ return res;
+
+ if (*outlen < 2 || out[0] != 0 || out[1] != 2)
+ return -1;
+
+ /* Skip PS (pseudorandom non-zero octets) */
+ pos = out + 2;
+ end = out + *outlen;
+ while (*pos && pos < end)
+ pos++;
+ if (pos == end)
+ return -1;
+ pos++;
+
+ *outlen -= pos - out;
+
+ /* Strip PKCS #1 header */
+ os_memmove(out, pos, *outlen);
+
+ return 0;
+}
+
+
int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
const u8 *in, size_t inlen,
u8 *out, size_t *outlen)
@@ -576,21 +609,39 @@
* PKCS #1 v1.5, 8.1:
*
* EB = 00 || BT || PS || 00 || D
- * BT = 01
- * PS = k-3-||D|| times FF
+ * BT = 00 or 01
+ * PS = k-3-||D|| times (00 if BT=00) or (FF if BT=01)
* k = length of modulus in octets
*/
if (len < 3 + 8 + 16 /* min hash len */ ||
- plain[0] != 0x00 || plain[1] != 0x01 || plain[2] != 0xff) {
+ plain[0] != 0x00 || (plain[1] != 0x00 && plain[1] != 0x01)) {
wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature EB "
"structure");
return -1;
}
pos = plain + 3;
- while (pos < plain + len && *pos == 0xff)
- pos++;
+ if (plain[1] == 0x00) {
+ /* BT = 00 */
+ if (plain[2] != 0x00) {
+ wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
+ "PS (BT=00)");
+ return -1;
+ }
+ while (pos + 1 < plain + len && *pos == 0x00 && pos[1] == 0x00)
+ pos++;
+ } else {
+ /* BT = 01 */
+ if (plain[2] != 0xff) {
+ wpa_printf(MSG_INFO, "LibTomCrypt: Invalid signature "
+ "PS (BT=01)");
+ return -1;
+ }
+ while (pos < plain + len && *pos == 0xff)
+ pos++;
+ }
+
if (pos - plain - 2 < 8) {
/* PKCS #1 v1.5, 8.1: At least eight octets long PS */
wpa_printf(MSG_INFO, "LibTomCrypt: Too short signature "
Modified: wpasupplicant/trunk/src/crypto/ms_funcs.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/ms_funcs.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/ms_funcs.c (original)
+++ wpasupplicant/trunk/src/crypto/ms_funcs.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -411,9 +411,8 @@
* @block: 16-octet Block (IN)
* @cypher: 16-octer Cypher (OUT)
*/
-static void nt_password_hash_encrypted_with_block(const u8 *password_hash,
- const u8 *block,
- u8 *cypher)
+void nt_password_hash_encrypted_with_block(const u8 *password_hash,
+ const u8 *block, u8 *cypher)
{
des_encrypt(password_hash, block, cypher);
des_encrypt(password_hash + 8, block + 7, cypher + 8);
Modified: wpasupplicant/trunk/src/crypto/ms_funcs.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/ms_funcs.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/ms_funcs.h (original)
+++ wpasupplicant/trunk/src/crypto/ms_funcs.h Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / shared MSCHAPV2 helper functions / RFC 2433 / RFC 2759
- * Copyright (c) 2004-2005, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -47,10 +47,15 @@
void get_asymetric_start_key(const u8 *master_key, u8 *session_key,
size_t session_key_len, int is_send,
int is_server);
+int encrypt_pw_block_with_password_hash(
+ const u8 *password, size_t password_len,
+ const u8 *password_hash, u8 *pw_block);
void new_password_encrypted_with_old_nt_password_hash(
const u8 *new_password, size_t new_password_len,
const u8 *old_password, size_t old_password_len,
u8 *encrypted_pw_block);
+void nt_password_hash_encrypted_with_block(const u8 *password_hash,
+ const u8 *block, u8 *cypher);
void old_nt_password_hash_encrypted_with_new_nt_password_hash(
const u8 *new_password, size_t new_password_len,
const u8 *old_password, size_t old_password_len,
Modified: wpasupplicant/trunk/src/crypto/sha256.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/sha256.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/sha256.c (original)
+++ wpasupplicant/trunk/src/crypto/sha256.c Sat Nov 3 11:46:49 2007
@@ -107,7 +107,7 @@
/**
- * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5a.3)
+ * sha256_prf - SHA256-based Pseudo-Random Function (IEEE 802.11r, 8.5.1.5.2)
* @key: Key for PRF
* @key_len: Length of the key in bytes
* @label: A unique label for each purpose of the PRF
@@ -132,7 +132,7 @@
addr[0] = counter_le;
len[0] = 2;
addr[1] = (u8 *) label;
- len[1] = os_strlen(label) + 1;
+ len[1] = os_strlen(label);
addr[2] = data;
len[2] = data_len;
addr[3] = length_le;
Modified: wpasupplicant/trunk/src/crypto/tls.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls.h (original)
+++ wpasupplicant/trunk/src/crypto/tls.h Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / SSL/TLS interface definition
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -364,17 +364,6 @@
*/
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn);
-/**
- * tls_connection_set_master_key - Configure master secret for TLS connection
- * @tls_ctx: TLS context data from tls_init()
- * @conn: Connection context data from tls_connection_init()
- * @key: TLS pre-master-secret
- * @key_len: length of key in bytes
- * Returns: 0 on success, -1 on failure
- */
-int tls_connection_set_master_key(void *tls_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len);
-
enum {
TLS_CIPHER_NONE,
TLS_CIPHER_RC4_SHA /* 0x0005 */,
@@ -518,4 +507,13 @@
struct tls_connection *conn,
const u8 *key, size_t key_len);
+typedef int (*tls_session_ticket_cb)
+(void *ctx, const u8 *ticket, size_t len, const u8 *client_random,
+ const u8 *server_random, u8 *master_secret);
+
+int tls_connection_set_session_ticket_cb(void *tls_ctx,
+ struct tls_connection *conn,
+ tls_session_ticket_cb cb,
+ void *ctx);
+
#endif /* TLS_H */
Modified: wpasupplicant/trunk/src/crypto/tls_gnutls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_gnutls.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_gnutls.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_gnutls.c Sat Nov 3 11:46:49 2007
@@ -1157,14 +1157,6 @@
}
-int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len)
-{
- /* TODO */
- return -1;
-}
-
-
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
u8 *ciphers)
{
Modified: wpasupplicant/trunk/src/crypto/tls_internal.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_internal.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_internal.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_internal.c Sat Nov 3 11:46:49 2007
@@ -20,16 +20,20 @@
#include "common.h"
#include "tls.h"
#include "tls/tlsv1_client.h"
+#include "tls/tlsv1_server.h"
static int tls_ref_count = 0;
struct tls_global {
- int dummy;
+ int server;
+ struct tlsv1_credentials *server_cred;
+ int check_crl;
};
struct tls_connection {
struct tlsv1_client *client;
+ struct tlsv1_server *server;
};
@@ -38,8 +42,14 @@
struct tls_global *global;
if (tls_ref_count == 0) {
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
if (tlsv1_client_global_init())
return NULL;
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (tlsv1_server_global_init())
+ return NULL;
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
}
tls_ref_count++;
@@ -55,7 +65,13 @@
struct tls_global *global = ssl_ctx;
tls_ref_count--;
if (tls_ref_count == 0) {
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
tlsv1_client_global_deinit();
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ tlsv1_cred_free(global->server_cred);
+ tlsv1_server_global_deinit();
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
}
os_free(global);
}
@@ -70,16 +86,30 @@
struct tls_connection * tls_connection_init(void *tls_ctx)
{
struct tls_connection *conn;
+ struct tls_global *global = tls_ctx;
conn = os_zalloc(sizeof(*conn));
if (conn == NULL)
return NULL;
- conn->client = tlsv1_client_init();
- if (conn->client == NULL) {
- os_free(conn);
- return NULL;
- }
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (!global->server) {
+ conn->client = tlsv1_client_init();
+ if (conn->client == NULL) {
+ os_free(conn);
+ return NULL;
+ }
+ }
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (global->server) {
+ conn->server = tlsv1_server_init(global->server_cred);
+ if (conn->server == NULL) {
+ os_free(conn);
+ return NULL;
+ }
+ }
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
return conn;
}
@@ -89,74 +119,170 @@
{
if (conn == NULL)
return;
- tlsv1_client_deinit(conn->client);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ tlsv1_client_deinit(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ tlsv1_server_deinit(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
os_free(conn);
}
int tls_connection_established(void *tls_ctx, struct tls_connection *conn)
{
- return tlsv1_client_established(conn->client);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_established(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_established(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return 0;
}
int tls_connection_shutdown(void *tls_ctx, struct tls_connection *conn)
{
- return tlsv1_client_shutdown(conn->client);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_shutdown(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_shutdown(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
const struct tls_connection_params *params)
{
- if (tlsv1_client_set_ca_cert(conn->client, params->ca_cert,
- params->ca_cert_blob,
- params->ca_cert_blob_len,
- params->ca_path)) {
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ struct tlsv1_credentials *cred;
+
+ if (conn->client == NULL)
+ return -1;
+
+ cred = tlsv1_cred_alloc();
+ if (cred == NULL)
+ return -1;
+
+ if (tlsv1_set_ca_cert(cred, params->ca_cert,
+ params->ca_cert_blob, params->ca_cert_blob_len,
+ params->ca_path)) {
wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
"certificates");
- return -1;
- }
-
- if (tlsv1_client_set_client_cert(conn->client, params->client_cert,
- params->client_cert_blob,
- params->client_cert_blob_len)) {
+ tlsv1_cred_free(cred);
+ return -1;
+ }
+
+ if (tlsv1_set_cert(cred, params->client_cert,
+ params->client_cert_blob,
+ params->client_cert_blob_len)) {
wpa_printf(MSG_INFO, "TLS: Failed to configure client "
"certificate");
- return -1;
- }
-
- if (tlsv1_client_set_private_key(conn->client,
- params->private_key,
- params->private_key_passwd,
- params->private_key_blob,
- params->private_key_blob_len)) {
+ tlsv1_cred_free(cred);
+ return -1;
+ }
+
+ if (tlsv1_set_private_key(cred, params->private_key,
+ params->private_key_passwd,
+ params->private_key_blob,
+ params->private_key_blob_len)) {
wpa_printf(MSG_INFO, "TLS: Failed to load private key");
- return -1;
- }
-
- return 0;
+ tlsv1_cred_free(cred);
+ return -1;
+ }
+
+ if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
+ params->dh_blob_len)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
+ tlsv1_cred_free(cred);
+ return -1;
+ }
+
+ if (tlsv1_client_set_cred(conn->client, cred) < 0) {
+ tlsv1_cred_free(cred);
+ return -1;
+ }
+
+ return 0;
+#else /* CONFIG_TLS_INTERNAL_CLIENT */
+ return -1;
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
}
int tls_global_set_params(void *tls_ctx,
const struct tls_connection_params *params)
{
- wpa_printf(MSG_INFO, "TLS: not implemented - %s", __func__);
- return -1;
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ struct tls_global *global = tls_ctx;
+ struct tlsv1_credentials *cred;
+
+ /* Currently, global parameters are only set when running in server
+ * mode. */
+ global->server = 1;
+ tlsv1_cred_free(global->server_cred);
+ global->server_cred = cred = tlsv1_cred_alloc();
+ if (cred == NULL)
+ return -1;
+
+ if (tlsv1_set_ca_cert(cred, params->ca_cert, params->ca_cert_blob,
+ params->ca_cert_blob_len, params->ca_path)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to configure trusted CA "
+ "certificates");
+ return -1;
+ }
+
+ if (tlsv1_set_cert(cred, params->client_cert, params->client_cert_blob,
+ params->client_cert_blob_len)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to configure server "
+ "certificate");
+ return -1;
+ }
+
+ if (tlsv1_set_private_key(cred, params->private_key,
+ params->private_key_passwd,
+ params->private_key_blob,
+ params->private_key_blob_len)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load private key");
+ return -1;
+ }
+
+ if (tlsv1_set_dhparams(cred, params->dh_file, params->dh_blob,
+ params->dh_blob_len)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load DH parameters");
+ return -1;
+ }
+
+ return 0;
+#else /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
}
int tls_global_set_verify(void *tls_ctx, int check_crl)
{
- wpa_printf(MSG_INFO, "TLS: not implemented - %s", __func__);
- return -1;
+ struct tls_global *global = tls_ctx;
+ global->check_crl = check_crl;
+ return 0;
}
int tls_connection_set_verify(void *tls_ctx, struct tls_connection *conn,
int verify_peer)
{
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_set_verify(conn->server, verify_peer);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
return -1;
}
@@ -171,7 +297,15 @@
int tls_connection_get_keys(void *tls_ctx, struct tls_connection *conn,
struct tls_keys *keys)
{
- return tlsv1_client_get_keys(conn->client, keys);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_get_keys(conn->client, keys);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_get_keys(conn->server, keys);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
@@ -179,8 +313,21 @@
const char *label, int server_random_first,
u8 *out, size_t out_len)
{
- return tlsv1_client_prf(conn->client, label, server_random_first,
- out, out_len);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client) {
+ return 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);
+ }
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
@@ -189,6 +336,10 @@
size_t *out_len, u8 **appl_data,
size_t *appl_data_len)
{
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client == NULL)
+ return NULL;
+
if (appl_data)
*appl_data = NULL;
@@ -196,6 +347,9 @@
__func__, in_data, (unsigned long) in_len);
return tlsv1_client_handshake(conn->client, in_data, in_len, out_len,
appl_data, appl_data_len);
+#else /* CONFIG_TLS_INTERNAL_CLIENT */
+ return NULL;
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
}
@@ -204,8 +358,20 @@
const u8 *in_data, size_t in_len,
size_t *out_len)
{
- wpa_printf(MSG_INFO, "TLS: not implemented - %s", __func__);
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ u8 *out;
+ if (conn->server == NULL)
+ return NULL;
+
+ wpa_printf(MSG_DEBUG, "TLS: %s(in_data=%p in_len=%lu)",
+ __func__, in_data, (unsigned long) in_len);
+ out = tlsv1_server_handshake(conn->server, in_data, in_len, out_len);
+ if (out == NULL && tlsv1_server_established(conn->server))
+ out = os_malloc(1);
+ return out;
+#else /* CONFIG_TLS_INTERNAL_SERVER */
return NULL;
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
}
@@ -213,8 +379,19 @@
const u8 *in_data, size_t in_len,
u8 *out_data, size_t out_len)
{
- return tlsv1_client_encrypt(conn->client, in_data, in_len, out_data,
- out_len);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client) {
+ return tlsv1_client_encrypt(conn->client, in_data, in_len,
+ out_data, out_len);
+ }
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server) {
+ return tlsv1_server_encrypt(conn->server, in_data, in_len,
+ out_data, out_len);
+ }
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
@@ -222,28 +399,48 @@
const u8 *in_data, size_t in_len,
u8 *out_data, size_t out_len)
{
- return tlsv1_client_decrypt(conn->client, in_data, in_len, out_data,
- out_len);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client) {
+ return tlsv1_client_decrypt(conn->client, in_data, in_len,
+ out_data, out_len);
+ }
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server) {
+ return tlsv1_server_decrypt(conn->server, in_data, in_len,
+ out_data, out_len);
+ }
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
int tls_connection_resumed(void *tls_ctx, struct tls_connection *conn)
{
- return tlsv1_client_resumed(conn->client);
-}
-
-
-int tls_connection_set_master_key(void *tls_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len)
-{
- return tlsv1_client_set_master_key(conn->client, key, key_len);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_resumed(conn->client);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_resumed(conn->server);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
u8 *ciphers)
{
- return tlsv1_client_set_cipher_list(conn->client, ciphers);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_set_cipher_list(conn->client, ciphers);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_set_cipher_list(conn->server, ciphers);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
@@ -252,7 +449,15 @@
{
if (conn == NULL)
return -1;
- return tlsv1_client_get_cipher(conn->client, buf, buflen);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client)
+ return tlsv1_client_get_cipher(conn->client, buf, buflen);
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server)
+ return tlsv1_server_get_cipher(conn->server, buf, buflen);
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
}
@@ -267,7 +472,13 @@
int ext_type, const u8 *data,
size_t data_len)
{
- return tlsv1_client_hello_ext(conn->client, ext_type, data, data_len);
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client) {
+ return tlsv1_client_hello_ext(conn->client, ext_type,
+ data, data_len);
+ }
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+ return -1;
}
@@ -293,7 +504,15 @@
int tls_connection_get_keyblock_size(void *tls_ctx,
struct tls_connection *conn)
{
- return tlsv1_client_get_keyblock_size(conn->client);
+#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;
}
@@ -325,3 +544,24 @@
{
return -1;
}
+
+
+int tls_connection_set_session_ticket_cb(void *tls_ctx,
+ struct tls_connection *conn,
+ tls_session_ticket_cb cb,
+ void *ctx)
+{
+#ifdef CONFIG_TLS_INTERNAL_CLIENT
+ if (conn->client) {
+ tlsv1_client_set_session_ticket_cb(conn->client, cb, ctx);
+ return 0;
+ }
+#endif /* CONFIG_TLS_INTERNAL_CLIENT */
+#ifdef CONFIG_TLS_INTERNAL_SERVER
+ if (conn->server) {
+ tlsv1_server_set_session_ticket_cb(conn->server, cb, ctx);
+ return 0;
+ }
+#endif /* CONFIG_TLS_INTERNAL_SERVER */
+ return -1;
+}
Modified: wpasupplicant/trunk/src/crypto/tls_none.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_none.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_none.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_none.c Sat Nov 3 11:46:49 2007
@@ -147,13 +147,6 @@
}
-int tls_connection_set_master_key(void *tls_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len)
-{
- return -1;
-}
-
-
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
u8 *ciphers)
{
Modified: wpasupplicant/trunk/src/crypto/tls_openssl.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_openssl.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_openssl.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_openssl.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* WPA Supplicant / SSL/TLS interface functions for openssl
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -49,8 +49,12 @@
char *subject_match, *altsubject_match;
int read_alerts, write_alerts, failed;
- u8 *pre_shared_secret;
- size_t pre_shared_secret_len;
+ tls_session_ticket_cb session_ticket_cb;
+ void *session_ticket_cb_ctx;
+
+ /* SessionTicket received from OpenSSL hello_extension_cb (server) */
+ u8 *session_ticket;
+ size_t session_ticket_len;
};
@@ -919,11 +923,11 @@
{
if (conn == NULL)
return;
- os_free(conn->pre_shared_secret);
SSL_free(conn->ssl);
tls_engine_deinit(conn);
os_free(conn->subject_match);
os_free(conn->altsubject_match);
+ os_free(conn->session_ticket);
os_free(conn);
}
@@ -1760,6 +1764,80 @@
}
+static int tls_global_dh(SSL_CTX *ssl_ctx, const char *dh_file)
+{
+#ifdef OPENSSL_NO_DH
+ if (dh_file == NULL)
+ return 0;
+ wpa_printf(MSG_ERROR, "TLS: openssl does not include DH support, but "
+ "dh_file specified");
+ return -1;
+#else /* OPENSSL_NO_DH */
+ DH *dh;
+ BIO *bio;
+
+ /* TODO: add support for dh_blob */
+ if (dh_file == NULL)
+ return 0;
+ if (ssl_ctx == NULL)
+ return -1;
+
+ bio = BIO_new_file(dh_file, "r");
+ if (bio == NULL) {
+ wpa_printf(MSG_INFO, "TLS: Failed to open DH file '%s': %s",
+ dh_file, ERR_error_string(ERR_get_error(), NULL));
+ return -1;
+ }
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+#ifndef OPENSSL_NO_DSA
+ while (dh == NULL) {
+ DSA *dsa;
+ wpa_printf(MSG_DEBUG, "TLS: Failed to parse DH file '%s': %s -"
+ " trying to parse as DSA params", dh_file,
+ ERR_error_string(ERR_get_error(), NULL));
+ bio = BIO_new_file(dh_file, "r");
+ if (bio == NULL)
+ break;
+ dsa = PEM_read_bio_DSAparams(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ if (!dsa) {
+ wpa_printf(MSG_DEBUG, "TLS: Failed to parse DSA file "
+ "'%s': %s", dh_file,
+ ERR_error_string(ERR_get_error(), NULL));
+ break;
+ }
+
+ wpa_printf(MSG_DEBUG, "TLS: DH file in DSA param format");
+ dh = DSA_dup_DH(dsa);
+ DSA_free(dsa);
+ if (dh == NULL) {
+ wpa_printf(MSG_INFO, "TLS: Failed to convert DSA "
+ "params into DH params");
+ break;
+ }
+ break;
+ }
+#endif /* !OPENSSL_NO_DSA */
+ if (dh == NULL) {
+ wpa_printf(MSG_INFO, "TLS: Failed to read/parse DH/DSA file "
+ "'%s'", dh_file);
+ return -1;
+ }
+
+ if (SSL_CTX_set_tmp_dh(ssl_ctx, dh) != 1) {
+ wpa_printf(MSG_INFO, "TLS: Failed to set DH params from '%s': "
+ "%s", dh_file,
+ ERR_error_string(ERR_get_error(), NULL));
+ DH_free(dh);
+ return -1;
+ }
+ DH_free(dh);
+ return 0;
+#endif /* OPENSSL_NO_DH */
+}
+
+
int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
struct tls_keys *keys)
{
@@ -1998,57 +2076,6 @@
{
return conn ? conn->ssl->hit : 0;
}
-
-
-#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC)
-/* Pre-shared secred requires a patch to openssl, so this function is
- * commented out unless explicitly needed for EAP-FAST in order to be able to
- * build this file with unmodified openssl. */
-
-static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
- STACK_OF(SSL_CIPHER) *peer_ciphers,
- SSL_CIPHER **cipher, void *arg)
-{
- struct tls_connection *conn = arg;
-
- if (conn == NULL || conn->pre_shared_secret == 0)
- return 0;
-
- os_memcpy(secret, conn->pre_shared_secret,
- conn->pre_shared_secret_len);
- *secret_len = conn->pre_shared_secret_len;
-
- return 1;
-}
-
-
-int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len)
-{
- if (conn == NULL || key_len > SSL_MAX_MASTER_KEY_LENGTH)
- return -1;
-
- os_free(conn->pre_shared_secret);
- conn->pre_shared_secret = NULL;
- conn->pre_shared_secret_len = 0;
-
- if (key) {
- conn->pre_shared_secret = os_malloc(key_len);
- if (conn->pre_shared_secret) {
- os_memcpy(conn->pre_shared_secret, key, key_len);
- conn->pre_shared_secret_len = key_len;
- }
- if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
- conn) != 1)
- return -1;
- } else {
- if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
- return -1;
- }
-
- return 0;
-}
-#endif /* EAP_FAST || EAP_FAST_DYNAMIC */
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
@@ -2255,6 +2282,12 @@
params->private_key_passwd))
return -1;
+ if (tls_global_dh(ssl_ctx, params->dh_file)) {
+ wpa_printf(MSG_INFO, "TLS: Failed to load DH file '%s'",
+ params->dh_file);
+ return -1;
+ }
+
return 0;
}
@@ -2272,7 +2305,11 @@
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
return 2 * (EVP_CIPHER_key_length(c) +
EVP_MD_size(h) +
@@ -2315,3 +2352,131 @@
{
return -1;
}
+
+
+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC)
+/* Pre-shared secred requires a patch to openssl, so this function is
+ * commented out unless explicitly needed for EAP-FAST in order to be able to
+ * build this file with unmodified openssl. */
+
+static int tls_sess_sec_cb(SSL *s, void *secret, int *secret_len,
+ STACK_OF(SSL_CIPHER) *peer_ciphers,
+ SSL_CIPHER **cipher, void *arg)
+{
+ struct tls_connection *conn = arg;
+ int ret;
+
+ if (conn == NULL || conn->session_ticket_cb == NULL)
+ return 0;
+
+ ret = conn->session_ticket_cb(conn->session_ticket_cb_ctx,
+ conn->session_ticket,
+ conn->session_ticket_len,
+ s->s3->client_random,
+ s->s3->server_random, secret);
+ os_free(conn->session_ticket);
+ conn->session_ticket = NULL;
+
+ if (ret <= 0)
+ return 0;
+
+ *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
+ return 1;
+}
+
+
+#ifdef SSL_OP_NO_TICKET
+static void tls_hello_ext_cb(SSL *s, int client_server, int type,
+ unsigned char *data, int len, void *arg)
+{
+ struct tls_connection *conn = arg;
+
+ if (conn == NULL || conn->session_ticket_cb == NULL)
+ return;
+
+ wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
+ type, len);
+
+ if (type == TLSEXT_TYPE_session_ticket && !client_server) {
+ os_free(conn->session_ticket);
+ conn->session_ticket = NULL;
+
+ wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
+ "extension", data, len);
+ conn->session_ticket = os_malloc(len);
+ if (conn->session_ticket == NULL)
+ return;
+
+ os_memcpy(conn->session_ticket, data, len);
+ conn->session_ticket_len = len;
+ }
+}
+#else /* SSL_OP_NO_TICKET */
+static int tls_hello_ext_cb(SSL *s, TLS_EXTENSION *ext, void *arg)
+{
+ struct tls_connection *conn = arg;
+
+ if (conn == NULL || conn->session_ticket_cb == NULL)
+ return 0;
+
+ wpa_printf(MSG_DEBUG, "OpenSSL: %s: type=%d length=%d", __func__,
+ ext->type, ext->length);
+
+ os_free(conn->session_ticket);
+ conn->session_ticket = NULL;
+
+ if (ext->type == 35) {
+ wpa_hexdump(MSG_DEBUG, "OpenSSL: ClientHello SessionTicket "
+ "extension", ext->data, ext->length);
+ conn->session_ticket = os_malloc(ext->length);
+ if (conn->session_ticket == NULL)
+ return SSL_AD_INTERNAL_ERROR;
+
+ os_memcpy(conn->session_ticket, ext->data, ext->length);
+ conn->session_ticket_len = ext->length;
+ }
+
+ return 0;
+}
+#endif /* SSL_OP_NO_TICKET */
+#endif /* EAP_FAST || EAP_FAST_DYNAMIC */
+
+
+int tls_connection_set_session_ticket_cb(void *tls_ctx,
+ struct tls_connection *conn,
+ tls_session_ticket_cb cb,
+ void *ctx)
+{
+#if defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC)
+ conn->session_ticket_cb = cb;
+ conn->session_ticket_cb_ctx = ctx;
+
+ if (cb) {
+ if (SSL_set_session_secret_cb(conn->ssl, tls_sess_sec_cb,
+ conn) != 1)
+ return -1;
+#ifdef SSL_OP_NO_TICKET
+ SSL_set_tlsext_debug_callback(conn->ssl, tls_hello_ext_cb);
+ SSL_set_tlsext_debug_arg(conn->ssl, conn);
+#else /* SSL_OP_NO_TICKET */
+ if (SSL_set_hello_extension_cb(conn->ssl, tls_hello_ext_cb,
+ conn) != 1)
+ return -1;
+#endif /* SSL_OP_NO_TICKET */
+ } else {
+ if (SSL_set_session_secret_cb(conn->ssl, NULL, NULL) != 1)
+ return -1;
+#ifdef SSL_OP_NO_TICKET
+ SSL_set_tlsext_debug_callback(conn->ssl, NULL);
+ SSL_set_tlsext_debug_arg(conn->ssl, conn);
+#else /* SSL_OP_NO_TICKET */
+ if (SSL_set_hello_extension_cb(conn->ssl, NULL, NULL) != 1)
+ return -1;
+#endif /* SSL_OP_NO_TICKET */
+ }
+
+ return 0;
+#else /* EAP_FAST || EAP_FAST_DYNAMIC */
+ return -1;
+#endif /* EAP_FAST || EAP_FAST_DYNAMIC */
+}
Modified: wpasupplicant/trunk/src/crypto/tls_schannel.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/crypto/tls_schannel.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/crypto/tls_schannel.c (original)
+++ wpasupplicant/trunk/src/crypto/tls_schannel.c Sat Nov 3 11:46:49 2007
@@ -654,13 +654,6 @@
}
-int tls_connection_set_master_key(void *ssl_ctx, struct tls_connection *conn,
- const u8 *key, size_t key_len)
-{
- return -1;
-}
-
-
int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
u8 *ciphers)
{
Modified: wpasupplicant/trunk/src/drivers/driver.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver.h (original)
+++ wpasupplicant/trunk/src/drivers/driver.h Sat Nov 3 11:46:49 2007
@@ -197,6 +197,14 @@
* mobility domain is currently active.
*/
const u8 *ft_md;
+
+ /**
+ * passphrase - RSN passphrase for PSK
+ *
+ * This value is made available only for WPA/WPA2-Personal (PSK) and
+ * only for drivers that set WPA_DRIVER_FLAGS_4WAY_HANDSHAKE.
+ */
+ const char *passphrase;
};
/**
@@ -227,6 +235,9 @@
#define WPA_DRIVER_FLAGS_DRIVER_IE 0x00000001
#define WPA_DRIVER_FLAGS_SET_KEYS_AFTER_ASSOC 0x00000002
#define WPA_DRIVER_FLAGS_USER_SPACE_MLME 0x00000004
+/* Driver takes care of RSN 4-way handshake internally; PMK is configured with
+ * struct wpa_driver_ops::set_key using alg = WPA_ALG_PMK */
+#define WPA_DRIVER_FLAGS_4WAY_HANDSHAKE 0x00000008
unsigned int flags;
};
@@ -347,7 +358,8 @@
* set_key - Configure encryption key
* @priv: private driver interface data
* @alg: encryption algorithm (%WPA_ALG_NONE, %WPA_ALG_WEP,
- * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_DHV);
+ * %WPA_ALG_TKIP, %WPA_ALG_CCMP, %WPA_ALG_IGTK, %WPA_ALG_DHV,
+ * %WPA_ALG_PMK);
* %WPA_ALG_NONE clears the key.
* @addr: address of the peer STA or ff:ff:ff:ff:ff:ff for
* broadcast/default keys
Modified: wpasupplicant/trunk/src/drivers/driver_wext.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/driver_wext.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/driver_wext.c (original)
+++ wpasupplicant/trunk/src/drivers/driver_wext.c Sat Nov 3 11:46:49 2007
@@ -1380,6 +1380,7 @@
wpa_printf(MSG_INFO, "Invalid TSF length (%d)", bytes);
return;
}
+ bytes /= 2;
hexstr2bin(spos, bin, bytes);
res->tsf += WPA_GET_BE64(bin);
}
Modified: wpasupplicant/trunk/src/drivers/drivers.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/drivers/drivers.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/drivers/drivers.c (original)
+++ wpasupplicant/trunk/src/drivers/drivers.c Sat Nov 3 11:46:49 2007
@@ -58,6 +58,12 @@
#ifdef CONFIG_DRIVER_RALINK
extern struct wpa_driver_ops wpa_driver_ralink_ops; /* driver_ralink.c */
#endif /* CONFIG_DRIVER_RALINK */
+#ifdef CONFIG_DRIVER_OSX
+extern struct wpa_driver_ops wpa_driver_osx_ops; /* driver_osx.m */
+#endif /* CONFIG_DRIVER_OSX */
+#ifdef CONFIG_DRIVER_IPHONE
+extern struct wpa_driver_ops wpa_driver_iphone_ops; /* driver_iphone.m */
+#endif /* CONFIG_DRIVER_IPHONE */
struct wpa_driver_ops *wpa_supplicant_drivers[] =
@@ -104,5 +110,11 @@
#ifdef CONFIG_DRIVER_RALINK
&wpa_driver_ralink_ops,
#endif /* CONFIG_DRIVER_RALINK */
+#ifdef CONFIG_DRIVER_OSX
+ &wpa_driver_osx_ops,
+#endif /* CONFIG_DRIVER_OSX */
+#ifdef CONFIG_DRIVER_IPHONE
+ &wpa_driver_iphone_ops,
+#endif /* CONFIG_DRIVER_IPHONE */
NULL
};
Modified: wpasupplicant/trunk/src/eap_common/eap_gpsk_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_gpsk_common.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_gpsk_common.c (original)
+++ wpasupplicant/trunk/src/eap_common/eap_gpsk_common.c Sat Nov 3 11:46:49 2007
@@ -18,7 +18,9 @@
#include "eap_defs.h"
#include "aes_wrap.h"
#include "crypto.h"
+#ifdef EAP_GPSK_SHA256
#include "sha256.h"
+#endif /* EAP_GPSK_SHA256 */
#include "eap_gpsk_common.h"
@@ -42,31 +44,29 @@
}
-static int eap_gpsk_gkdf(const u8 *psk /* Y */, size_t psk_len,
- const u8 *data /* Z */, size_t data_len,
- u8 *buf, size_t len /* X */)
+static int eap_gpsk_gkdf_cmac(const u8 *psk /* Y */,
+ const u8 *data /* Z */, size_t data_len,
+ u8 *buf, size_t len /* X */)
{
u8 *opos;
size_t i, n, hashlen, left, clen;
- u8 ibuf[2], hash[SHA256_MAC_LEN];
- const u8 *addr[3];
- size_t vlen[3];
-
- hashlen = SHA256_MAC_LEN;
- /* M_i = Hash-Function (i || Y || Z); */
+ u8 ibuf[2], hash[16];
+ const u8 *addr[2];
+ size_t vlen[2];
+
+ hashlen = sizeof(hash);
+ /* M_i = MAC_Y (i || Z); (MAC = AES-CMAC-128) */
addr[0] = ibuf;
vlen[0] = sizeof(ibuf);
- addr[1] = psk;
- vlen[1] = psk_len;
- addr[2] = data;
- vlen[2] = data_len;
+ addr[1] = data;
+ vlen[1] = data_len;
opos = buf;
left = len;
n = (len + hashlen - 1) / hashlen;
for (i = 1; i <= n; i++) {
WPA_PUT_BE16(ibuf, i);
- sha256_vector(3, addr, vlen, hash);
+ omac1_aes_128_vector(psk, 2, addr, vlen, hash);
clen = left > hashlen ? hashlen : left;
os_memcpy(opos, hash, clen);
opos += clen;
@@ -77,7 +77,42 @@
}
-static int eap_gpsk_derive_keys_helper(u32 csuite_specified,
+#ifdef EAP_GPSK_SHA256
+static int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */,
+ const u8 *data /* Z */, size_t data_len,
+ u8 *buf, size_t len /* X */)
+{
+ u8 *opos;
+ size_t i, n, hashlen, left, clen;
+ u8 ibuf[2], hash[SHA256_MAC_LEN];
+ const u8 *addr[2];
+ size_t vlen[2];
+
+ hashlen = SHA256_MAC_LEN;
+ /* M_i = MAC_Y (i || Z); (MAC = HMAC-SHA256) */
+ addr[0] = ibuf;
+ vlen[0] = sizeof(ibuf);
+ addr[1] = data;
+ vlen[1] = data_len;
+
+ opos = buf;
+ left = len;
+ n = (len + hashlen - 1) / hashlen;
+ for (i = 1; i <= n; i++) {
+ WPA_PUT_BE16(ibuf, i);
+ hmac_sha256_vector(psk, 32, 2, addr, vlen, hash);
+ clen = left > hashlen ? hashlen : left;
+ os_memcpy(opos, hash, clen);
+ opos += clen;
+ left -= clen;
+ }
+
+ return 0;
+}
+#endif /* EAP_GPSK_SHA256 */
+
+
+static int eap_gpsk_derive_keys_helper(u32 csuite_specifier,
u8 *kdf_out, size_t kdf_out_len,
const u8 *psk, size_t psk_len,
const u8 *seed, size_t seed_len,
@@ -85,10 +120,28 @@
u8 *sk, size_t sk_len,
u8 *pk, size_t pk_len)
{
- u8 zero, mk[32], *pos, *data;
- size_t data_len;
-
- zero = 0;
+ u8 zero[32], mk[32], *pos, *data;
+ size_t data_len, mk_len;
+ int (*gkdf)(const u8 *psk, const u8 *data, size_t data_len,
+ u8 *buf, size_t len);
+
+ gkdf = NULL;
+ switch (csuite_specifier) {
+ case EAP_GPSK_CIPHER_AES:
+ gkdf = eap_gpsk_gkdf_cmac;
+ mk_len = 16;
+ break;
+#ifdef EAP_GPSK_SHA256
+ case EAP_GPSK_CIPHER_SHA256:
+ gkdf = eap_gpsk_gkdf_sha256;
+ mk_len = SHA256_MAC_LEN;
+ break;
+#endif /* EAP_GPSK_SHA256 */
+ default:
+ return -1;
+ }
+
+ os_memset(zero, 0, sizeof(zero));
data_len = 2 + psk_len + 6 + seed_len;
data = os_malloc(data_len);
@@ -99,23 +152,22 @@
pos += 2;
os_memcpy(pos, psk, psk_len);
pos += psk_len;
- WPA_PUT_BE24(pos, 0); /* CSuite/Vendor = IETF */
- pos += 3;
- WPA_PUT_BE24(pos, csuite_specified); /* CSuite/Specifier */
- pos += 3;
+ WPA_PUT_BE32(pos, EAP_GPSK_VENDOR_IETF); /* CSuite/Vendor = IETF */
+ pos += 4;
+ WPA_PUT_BE16(pos, csuite_specifier); /* CSuite/Specifier */
+ pos += 2;
os_memcpy(pos, seed, seed_len); /* inputString */
wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation",
data, data_len);
- if (eap_gpsk_gkdf(&zero, 1, data, data_len, mk, sizeof(mk)) < 0) {
+ if (gkdf(zero, data, data_len, mk, mk_len) < 0) {
os_free(data);
return -1;
}
os_free(data);
- wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, sizeof(mk));
-
- if (eap_gpsk_gkdf(mk, sizeof(mk), seed, seed_len,
- kdf_out, kdf_out_len) < 0)
+ wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, mk_len);
+
+ if (gkdf(mk, seed, seed_len, kdf_out, kdf_out_len) < 0)
return -1;
pos = kdf_out;
@@ -153,16 +205,15 @@
/*
* inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
* (= seed)
- * KS = 16, PL = psk_len, CSuite_Sel = 0x000000 0x000001
- * MK = GKDF-32 (0x00, PL || PSK || CSuite_Sel || inputString)
+ * KS = 16, PL = psk_len, CSuite_Sel = 0x00000000 0x0001
+ * zero = 0x00 || 0x00 || ... || 0x00 (16 times)
+ * MK = GKDF-16 (zero, PL || PSK || CSuite_Sel || inputString)
* MSK = GKDF-160 (MK, inputString)[0..63]
* EMSK = GKDF-160 (MK, inputString)[64..127]
* SK = GKDF-160 (MK, inputString)[128..143]
* PK = GKDF-160 (MK, inputString)[144..159]
- * MID = GKDF-16(0x00, "Method ID" || EAP_Method_Type || CSuite_Sel ||
- * inputString)
- * Hash-Function = SHA256 (see [RFC4634])
- * hashlen = 32 octets (256 bits)
+ * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
+ * CSuite_Sel || inputString)
*/
*sk_len = EAP_GPSK_SK_LEN_AES;
@@ -190,15 +241,14 @@
/*
* inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
* (= seed)
- * KS = 32, PL = psk_len, CSuite_Sel = 0x000000 0x000002
- * MK = GKDF-32 (0x00, PL || PSK || CSuite_Sel || inputString)
- * MSK = GKDF-192 (MK, inputString)[0..63]
- * EMSK = GKDF-192 (MK, inputString)[64..127]
- * SK = GKDF-192 (MK, inputString)[128..159]
- * MID = GKDF-16(0x00, "Method ID" || EAP_Method_Type || CSuite_Sel ||
- * inputString)
- * Hash-Function = SHA256 (see [RFC4634])
- * hashlen = 32 octets (256 bits)
+ * KS = 32, PL = psk_len, CSuite_Sel = 0x00000000 0x0002
+ * zero = 0x00 || 0x00 || ... || 0x00 (32 times)
+ * MK = GKDF-32 (zero, PL || PSK || CSuite_Sel || inputString)
+ * MSK = GKDF-160 (MK, inputString)[0..63]
+ * EMSK = GKDF-160 (MK, inputString)[64..127]
+ * SK = GKDF-160 (MK, inputString)[128..159]
+ * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
+ * CSuite_Sel || inputString)
*/
*sk_len = EAP_GPSK_SK_LEN_SHA256;
Modified: wpasupplicant/trunk/src/eap_common/eap_gpsk_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_common/eap_gpsk_common.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_common/eap_gpsk_common.h (original)
+++ wpasupplicant/trunk/src/eap_common/eap_gpsk_common.h Sat Nov 3 11:46:49 2007
@@ -32,7 +32,7 @@
#define EAP_GPSK_MAX_PK_LEN 32
#define EAP_GPSK_MAX_MIC_LEN 32
-#define EAP_GPSK_VENDOR_IETF 0x000000
+#define EAP_GPSK_VENDOR_IETF 0x00000000
#define EAP_GPSK_CIPHER_RESERVED 0x000000
#define EAP_GPSK_CIPHER_AES 0x000001
#define EAP_GPSK_CIPHER_SHA256 0x000002
@@ -43,8 +43,8 @@
#endif /* _MSC_VER */
struct eap_gpsk_csuite {
- u8 vendor[3];
- u8 specifier[3];
+ u8 vendor[4];
+ u8 specifier[2];
} STRUCT_PACKED;
#ifdef _MSC_VER
Modified: wpasupplicant/trunk/src/eap_peer/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* EAP peer state machines (RFC 4137)
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1788,6 +1788,27 @@
/**
+ * eap_get_config_password2 - Get password from the network configuration
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+ * @len: Buffer for the length of the password
+ * @hash: Buffer for returning whether the password is stored as a
+ * NtPasswordHash instead of plaintext password; can be %NULL if this
+ * information is not needed
+ * Returns: Pointer to the password or %NULL if not found
+ */
+const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash)
+{
+ struct wpa_ssid *config = eap_get_config(sm);
+ if (config == NULL)
+ return NULL;
+ *len = config->password_len;
+ if (hash)
+ *hash = !!(config->flags & WPA_CONFIG_FLAGS_PASSWORD_NTHASH);
+ return config->password;
+}
+
+
+/**
* eap_get_config_new_password - Get new password from network configuration
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
* @len: Buffer for the length of the new password
Modified: wpasupplicant/trunk/src/eap_peer/eap_fast.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_fast.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_fast.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_fast.c Sat Nov 3 11:46:49 2007
@@ -32,27 +32,8 @@
* - password change (pending mschapv2 packet; replay decrypted packet)
*/
-#define EAP_FAST_VERSION 1
-#define EAP_FAST_KEY_LEN 64
-#define EAP_FAST_SIMCK_LEN 40
-#define EAP_FAST_SKS_LEN 40
-
-#define TLS_EXT_PAC_OPAQUE 35
-
static void eap_fast_deinit(struct eap_sm *sm, void *priv);
-
-
-/*
- * draft-cam-winget-eap-fast-provisioning-04.txt:
- * Section 3.4 - Key Derivations Used in the EAP-FAST Provisioning Exchange
- */
-struct eap_fast_key_block_provisioning {
- /* Extra key material after TLS key_block */
- u8 session_key_seed[EAP_FAST_SKS_LEN];
- u8 server_challenge[16]; /* MSCHAPv2 ServerChallenge */
- u8 client_challenge[16]; /* MSCHAPv2 ClientChallenge */
-};
struct eap_fast_data {
@@ -75,6 +56,7 @@
int provisioning; /* doing PAC provisioning (not the normal auth) */
int anon_provisioning; /* doing anonymous (unauthenticated)
* provisioning */
+ int session_ticket_used;
u8 key_data[EAP_FAST_KEY_LEN];
u8 emsk[EAP_EMSK_LEN];
@@ -85,14 +67,71 @@
size_t max_pac_list_len;
int use_pac_binary_format;
- int tls_master_secret_set;
-
u8 simck[EAP_FAST_SIMCK_LEN];
int simck_idx;
u8 *pending_phase2_req;
size_t pending_phase2_req_len;
};
+
+
+static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len,
+ const u8 *client_random,
+ const u8 *server_random,
+ u8 *master_secret)
+{
+ struct eap_fast_data *data = ctx;
+#define TLS_RANDOM_LEN 32
+#define TLS_MASTER_SECRET_LEN 48
+ u8 seed[2 * TLS_RANDOM_LEN];
+
+ wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket callback");
+
+ if (client_random == NULL || server_random == NULL ||
+ master_secret == NULL) {
+ wpa_printf(MSG_DEBUG, "EAP-FAST: SessionTicket failed - fall "
+ "back to full TLS handshake");
+ data->session_ticket_used = 0;
+ if (data->provisioning_allowed) {
+ wpa_printf(MSG_DEBUG, "EAP-FAST: Try to provision a "
+ "new PAC-Key");
+ data->provisioning = 1;
+ data->current_pac = NULL;
+ }
+ return 0;
+ }
+
+ wpa_hexdump(MSG_DEBUG, "EAP-FAST: SessionTicket", ticket, len);
+ wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random",
+ client_random, TLS_RANDOM_LEN);
+ wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random",
+ server_random, TLS_RANDOM_LEN);
+
+ if (data->current_pac == NULL) {
+ wpa_printf(MSG_DEBUG, "EAP-FAST: No PAC-Key available for "
+ "using SessionTicket");
+ data->session_ticket_used = 0;
+ return 0;
+ }
+
+ /*
+ * RFC 4851, Section 5.1:
+ * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",
+ * server_random + client_random, 48)
+ */
+ os_memcpy(seed, server_random, TLS_RANDOM_LEN);
+ os_memcpy(seed + TLS_RANDOM_LEN, client_random, TLS_RANDOM_LEN);
+ sha1_t_prf(data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN,
+ "PAC to master secret label hash",
+ seed, sizeof(seed), master_secret, TLS_MASTER_SECRET_LEN);
+
+ wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: master_secret",
+ master_secret, TLS_MASTER_SECRET_LEN);
+
+ data->session_ticket_used = 1;
+
+ return 1;
+}
static int eap_fast_parse_phase1(struct eap_fast_data *data,
@@ -160,6 +199,15 @@
return NULL;
}
+ if (tls_connection_set_session_ticket_cb(sm->ssl_ctx, data->ssl.conn,
+ eap_fast_session_ticket_cb,
+ data) < 0) {
+ wpa_printf(MSG_INFO, "EAP-FAST: Failed to set SessionTicket "
+ "callback");
+ eap_fast_deinit(sm, data);
+ return NULL;
+ }
+
/*
* The local RADIUS server in a Cisco AP does not seem to like empty
* fragments before data, so disable that workaround for CBC.
@@ -234,83 +282,6 @@
data->success = 1;
return 0;
-}
-
-
-static int eap_fast_set_tls_master_secret(struct eap_sm *sm,
- struct eap_fast_data *data,
- const u8 *tls, size_t tls_len)
-{
- struct tls_keys keys;
- u8 master_secret[48], *seed;
- const u8 *server_random;
- size_t seed_len, server_random_len;
-
- if (data->tls_master_secret_set || !data->current_pac ||
- tls_connection_get_keys(sm->ssl_ctx, data->ssl.conn, &keys) ||
- keys.client_random == NULL) {
- return 0;
- }
-
- wpa_hexdump(MSG_DEBUG, "EAP-FAST: client_random",
- keys.client_random, keys.client_random_len);
-
- /*
- * TLS master secret is needed before TLS library has processed this
- * message which includes both ServerHello and an encrypted handshake
- * message, so we need to parse server_random from this message before
- * passing it to TLS library.
- *
- * Example TLS packet header:
- * (16 03 01 00 2a 02 00 00 26 03 01 <32 bytes server_random>)
- * Content Type: Handshake: 0x16
- * Version: TLS 1.0 (0x0301)
- * Lenghth: 42 (0x002a)
- * Handshake Type: Server Hello: 0x02
- * Length: 38 (0x000026)
- * Version TLS 1.0 (0x0301)
- * Random: 32 bytes
- */
- if (tls_len < 43 || tls[0] != 0x16 ||
- tls[1] != 0x03 || tls[2] != 0x01 ||
- tls[5] != 0x02 || tls[9] != 0x03 || tls[10] != 0x01) {
- wpa_hexdump(MSG_DEBUG, "EAP-FAST: unrecognized TLS "
- "ServerHello", tls, tls_len);
- return -1;
- }
- server_random = tls + 11;
- server_random_len = 32;
- wpa_hexdump(MSG_DEBUG, "EAP-FAST: server_random",
- server_random, server_random_len);
-
- seed_len = keys.client_random_len + server_random_len;
- seed = os_malloc(seed_len);
- if (seed == NULL)
- return -1;
- os_memcpy(seed, server_random, server_random_len);
- os_memcpy(seed + server_random_len,
- keys.client_random, keys.client_random_len);
-
- wpa_hexdump(MSG_MSGDUMP, "EAP-FAST: T-PRF seed", seed, seed_len);
- wpa_hexdump_key(MSG_MSGDUMP, "EAP-FAST: PAC-Key",
- data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN);
- /*
- * RFC 4851, Section 5.1:
- * master_secret = T-PRF(PAC-Key, "PAC to master secret label hash",
- * server_random + client_random, 48)
- */
- sha1_t_prf(data->current_pac->pac_key, EAP_FAST_PAC_KEY_LEN,
- "PAC to master secret label hash",
- seed, seed_len, master_secret, sizeof(master_secret));
- os_free(seed);
- wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: TLS pre-master-secret",
- master_secret, sizeof(master_secret));
-
- data->tls_master_secret_set = 1;
-
- return tls_connection_set_master_key(sm->ssl_ctx, data->ssl.conn,
- master_secret,
- sizeof(master_secret));
}
@@ -1719,21 +1690,6 @@
res = 1;
}
} else {
- /*
- * Try to configure the TLS master secret based on PAC-Key
- * and server/client random values. If the needed values are
- * not yet available, the function returns 0, so we only abort
- * on failure case when configuring the TLS library fails, not
- * if the key material is not yet available.
- */
- if (eap_fast_set_tls_master_secret(sm, data, pos, left) < 0) {
- wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to configure "
- "TLS master secret");
- ret->methodState = METHOD_DONE;
- ret->decision = DECISION_FAIL;
- return NULL;
- }
-
/* Continue processing TLS handshake (phase 1). */
res = eap_peer_tls_process_helper(sm, &data->ssl,
EAP_TYPE_FAST,
Modified: wpasupplicant/trunk/src/eap_peer/eap_fast_pac.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_fast_pac.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_fast_pac.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_fast_pac.h Sat Nov 3 11:46:49 2007
@@ -15,54 +15,7 @@
#ifndef EAP_FAST_PAC_H
#define EAP_FAST_PAC_H
-/*
- * draft-cam-winget-eap-fast-provisioning-04.txt:
- * Section 4.2.1 - Formats for PAC TLV Attributes / Type Field
- * Note: bit 0x8000 (Mandatory) and bit 0x4000 (Reserved) are also defined
- * in the general PAC TLV format (Section 4.2).
- */
-#define PAC_TYPE_PAC_KEY 1
-#define PAC_TYPE_PAC_OPAQUE 2
-#define PAC_TYPE_CRED_LIFETIME 3
-#define PAC_TYPE_A_ID 4
-#define PAC_TYPE_I_ID 5
-/*
- * 6 was previous assigned for SERVER_PROTECTED_DATA, but
- * draft-cam-winget-eap-fast-provisioning-02.txt changed this to Reserved.
- */
-#define PAC_TYPE_A_ID_INFO 7
-#define PAC_TYPE_PAC_ACKNOWLEDGEMENT 8
-#define PAC_TYPE_PAC_INFO 9
-#define PAC_TYPE_PAC_TYPE 10
-
-#ifdef _MSC_VER
-#pragma pack(push, 1)
-#endif /* _MSC_VER */
-
-struct pac_tlv_hdr {
- be16 type;
- be16 len;
-} STRUCT_PACKED;
-
-#ifdef _MSC_VER
-#pragma pack(pop)
-#endif /* _MSC_VER */
-
-
-#define EAP_FAST_PAC_KEY_LEN 32
-
-/* draft-cam-winget-eap-fast-provisioning-04.txt: 4.2.6 PAC-Type TLV
- * Note: Machine Authentication PAC and User Authorization PAC were removed in
- * draft-cam-winget-eap-fast-provisioning-03.txt
- */
-#define PAC_TYPE_TUNNEL_PAC 1
-/* Application Specific Short Lived PACs (only in volatile storage) */
-/* User Authorization PAC */
-#define PAC_TYPE_USER_AUTHORIZATION 3
-/* Application Specific Long Lived PACs */
-/* Machine Authentication PAC */
-#define PAC_TYPE_MACHINE_AUTHENTICATION 2
-
+#include "eap_common/eap_fast_common.h"
struct eap_fast_pac {
struct eap_fast_pac *next;
Modified: wpasupplicant/trunk/src/eap_peer/eap_gpsk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_gpsk.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_gpsk.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_gpsk.c Sat Nov 3 11:46:49 2007
@@ -1,5 +1,5 @@
/*
- * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-04.txt)
+ * EAP peer method: EAP-GPSK (draft-ietf-emu-eap-gpsk-06.txt)
* Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
@@ -196,8 +196,8 @@
csuite = (struct eap_gpsk_csuite *) csuite_list;
for (i = 0; i < count; i++) {
int vendor, specifier;
- vendor = WPA_GET_BE24(csuite->vendor);
- specifier = WPA_GET_BE24(csuite->specifier);
+ vendor = WPA_GET_BE32(csuite->vendor);
+ specifier = WPA_GET_BE16(csuite->specifier);
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite[%d]: %d:%d",
i, vendor, specifier);
if (data->vendor == EAP_GPSK_VENDOR_IETF &&
@@ -356,8 +356,8 @@
rpos += csuite_list_len;
csuite = (struct eap_gpsk_csuite *) rpos;
- WPA_PUT_BE24(csuite->vendor, data->vendor);
- WPA_PUT_BE24(csuite->specifier, data->specifier);
+ WPA_PUT_BE32(csuite->vendor, data->vendor);
+ WPA_PUT_BE16(csuite->specifier, data->specifier);
rpos = (u8 *) (csuite + 1);
if (eap_gpsk_derive_keys(data->psk, data->psk_len,
@@ -444,8 +444,8 @@
return NULL;
}
csuite = (const struct eap_gpsk_csuite *) pos;
- vendor = WPA_GET_BE24(csuite->vendor);
- specifier = WPA_GET_BE24(csuite->specifier);
+ vendor = WPA_GET_BE32(csuite->vendor);
+ specifier = WPA_GET_BE16(csuite->specifier);
pos += sizeof(*csuite);
if (vendor != data->vendor || specifier != data->specifier) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel (%d:%d) does not "
Modified: wpasupplicant/trunk/src/eap_peer/eap_gtc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_gtc.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_gtc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_gtc.c Sat Nov 3 11:46:49 2007
@@ -30,7 +30,8 @@
if (data == NULL)
return NULL;
- if (sm->m && sm->m->method == EAP_TYPE_FAST) {
+ if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
+ sm->m->method == EAP_TYPE_FAST) {
wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
"with challenge/response");
data->prefix = 1;
Modified: wpasupplicant/trunk/src/eap_peer/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_i.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_i.h Sat Nov 3 11:46:49 2007
@@ -340,6 +340,7 @@
const u8 * eap_get_config_identity(struct eap_sm *sm, size_t *len);
const u8 * eap_get_config_password(struct eap_sm *sm, size_t *len);
+const u8 * eap_get_config_password2(struct eap_sm *sm, size_t *len, int *hash);
const u8 * eap_get_config_new_password(struct eap_sm *sm, size_t *len);
const u8 * eap_get_config_otp(struct eap_sm *sm, size_t *len);
void eap_clear_config_otp(struct eap_sm *sm);
Modified: wpasupplicant/trunk/src/eap_peer/eap_leap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_leap.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_leap.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_leap.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* EAP peer method: LEAP
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -72,11 +72,12 @@
const u8 *pos, *challenge, *identity, *password;
u8 challenge_len, *rpos;
size_t identity_len, password_len;
+ int pwhash;
wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Request");
identity = eap_get_config_identity(sm, &identity_len);
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (identity == NULL || password == NULL)
return NULL;
@@ -123,7 +124,10 @@
*rpos++ = LEAP_VERSION;
*rpos++ = 0; /* unused */
*rpos++ = LEAP_RESPONSE_LEN;
- nt_challenge_response(challenge, password, password_len, rpos);
+ if (pwhash)
+ challenge_response(challenge, password, rpos);
+ else
+ nt_challenge_response(challenge, password, password_len, rpos);
os_memcpy(data->peer_response, rpos, LEAP_RESPONSE_LEN);
wpa_hexdump(MSG_MSGDUMP, "EAP-LEAP: Response",
rpos, LEAP_RESPONSE_LEN);
@@ -199,10 +203,11 @@
u8 response_len, pw_hash[16], pw_hash_hash[16],
expected[LEAP_RESPONSE_LEN];
size_t password_len;
+ int pwhash;
wpa_printf(MSG_DEBUG, "EAP-LEAP: Processing EAP-Response");
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (password == NULL)
return NULL;
@@ -239,8 +244,12 @@
pos, LEAP_RESPONSE_LEN);
os_memcpy(data->ap_response, pos, LEAP_RESPONSE_LEN);
- nt_password_hash(password, password_len, pw_hash);
- hash_nt_password_hash(pw_hash, pw_hash_hash);
+ if (pwhash) {
+ hash_nt_password_hash(password, pw_hash_hash);
+ } else {
+ nt_password_hash(password, password_len, pw_hash);
+ hash_nt_password_hash(pw_hash, pw_hash_hash);
+ }
challenge_response(data->ap_challenge, pw_hash_hash, expected);
ret->methodState = METHOD_DONE;
@@ -333,11 +342,12 @@
u8 *key, pw_hash_hash[16], pw_hash[16];
const u8 *addr[5], *password;
size_t elen[5], password_len;
+ int pwhash;
if (data->state != LEAP_DONE)
return NULL;
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (password == NULL)
return NULL;
@@ -345,8 +355,12 @@
if (key == NULL)
return NULL;
- nt_password_hash(password, password_len, pw_hash);
- hash_nt_password_hash(pw_hash, pw_hash_hash);
+ if (pwhash)
+ hash_nt_password_hash(password, pw_hash_hash);
+ else {
+ nt_password_hash(password, password_len, pw_hash);
+ hash_nt_password_hash(pw_hash, pw_hash_hash);
+ }
wpa_hexdump_key(MSG_DEBUG, "EAP-LEAP: pw_hash_hash",
pw_hash_hash, 16);
wpa_hexdump(MSG_DEBUG, "EAP-LEAP: peer_challenge",
Modified: wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_mschapv2.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* EAP peer method: EAP-MSCHAPV2 (draft-kamath-pppext-eap-mschapv2-00.txt)
- * Copyright (c) 2004-2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2004-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -180,7 +180,7 @@
static void eap_mschapv2_derive_response(
struct eap_mschapv2_data *data,
const u8 *username, size_t username_len,
- const u8 *password, size_t password_len,
+ const u8 *password, size_t password_len, int pwhash,
const u8 *auth_challenge, const u8 *peer_challenge,
u8 *nt_response)
{
@@ -192,25 +192,45 @@
peer_challenge, MSCHAPV2_CHAL_LEN);
wpa_hexdump_ascii(MSG_DEBUG, "EAP-MSCHAPV2: username",
username, username_len);
- wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: password",
- password, password_len);
- generate_nt_response(auth_challenge, peer_challenge,
- username, username_len,
- password, password_len, nt_response);
+ if (pwhash) {
+ wpa_hexdump_key(MSG_DEBUG, "EAP-MSCHAPV2: password hash",
+ password, password_len);
+ generate_nt_response_pwhash(auth_challenge, peer_challenge,
+ username, username_len,
+ password, nt_response);
+ } else {
+ wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-MSCHAPV2: password",
+ password, password_len);
+ generate_nt_response(auth_challenge, peer_challenge,
+ username, username_len,
+ password, password_len, nt_response);
+ }
wpa_hexdump(MSG_DEBUG, "EAP-MSCHAPV2: response", nt_response,
MSCHAPV2_NT_RESPONSE_LEN);
/* Authenticator response is not really needed yet, but calculate it
* here so that challenges need not be saved. */
- generate_authenticator_response(password, password_len,
- peer_challenge, auth_challenge,
- username, username_len, nt_response,
- data->auth_response);
+ if (pwhash) {
+ generate_authenticator_response_pwhash(
+ password, peer_challenge, auth_challenge,
+ username, username_len, nt_response,
+ data->auth_response);
+ } else {
+ generate_authenticator_response(password, password_len,
+ peer_challenge, auth_challenge,
+ username, username_len,
+ nt_response,
+ data->auth_response);
+ }
data->auth_response_valid = 1;
/* Likewise, generate master_key here since we have the needed data
* available. */
- nt_password_hash(password, password_len, password_hash);
- hash_nt_password_hash(password_hash, password_hash_hash);
+ if (pwhash) {
+ hash_nt_password_hash(password, password_hash_hash);
+ } else {
+ nt_password_hash(password, password_len, password_hash);
+ hash_nt_password_hash(password_hash, password_hash_hash);
+ }
get_master_key(password_hash_hash, nt_response, data->master_key);
data->master_key_valid = 1;
}
@@ -229,11 +249,12 @@
struct ms_response *r;
size_t username_len, identity_len, password_len;
const u8 *username, *identity, *password;
+ int pwhash;
wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Generating Challenge Response");
identity = eap_get_config_identity(sm, &identity_len);
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
if (identity == NULL || password == NULL)
return NULL;
@@ -281,7 +302,7 @@
auth_challenge = data->auth_challenge;
}
eap_mschapv2_derive_response(data, username, username_len,
- password, password_len,
+ password, password_len, pwhash,
auth_challenge, peer_challenge,
r->nt_response);
@@ -375,9 +396,20 @@
"EAP-MSCHAPV2: Password changed successfully");
data->prev_error = 0;
os_free(config->password);
- config->password = config->new_password;
+ if (config->flags & WPA_CONFIG_FLAGS_PASSWORD_NTHASH) {
+ config->password = os_malloc(16);
+ config->password_len = 16;
+ if (config->password) {
+ nt_password_hash(config->new_password,
+ config->new_password_len,
+ config->password);
+ }
+ os_free(config->new_password);
+ } else {
+ config->password = config->new_password;
+ config->password_len = config->new_password_len;
+ }
config->new_password = NULL;
- config->password_len = config->new_password_len;
config->new_password_len = 0;
}
}
@@ -574,9 +606,10 @@
struct eap_mschapv2_hdr *ms;
struct ms_change_password *cp;
u8 password_hash[16], password_hash_hash[16];
+ int pwhash;
username = eap_get_config_identity(sm, &username_len);
- password = eap_get_config_password(sm, &password_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
new_password = eap_get_config_new_password(sm, &new_password_len);
if (username == NULL || password == NULL || new_password == NULL)
return NULL;
@@ -601,14 +634,29 @@
cp = (struct ms_change_password *) (ms + 1);
/* Encrypted-Password */
- new_password_encrypted_with_old_nt_password_hash(
- new_password, new_password_len,
- password, password_len, cp->encr_password);
+ if (pwhash) {
+ encrypt_pw_block_with_password_hash(
+ new_password, new_password_len,
+ password, cp->encr_password);
+ } else {
+ new_password_encrypted_with_old_nt_password_hash(
+ new_password, new_password_len,
+ password, password_len, cp->encr_password);
+ }
/* Encrypted-Hash */
- old_nt_password_hash_encrypted_with_new_nt_password_hash(
- new_password, new_password_len,
- password, password_len, cp->encr_hash);
+ if (pwhash) {
+ u8 new_password_hash[16];
+ nt_password_hash(new_password, new_password_len,
+ new_password_hash);
+ nt_password_hash_encrypted_with_block(password,
+ new_password_hash,
+ cp->encr_hash);
+ } else {
+ old_nt_password_hash_encrypted_with_new_nt_password_hash(
+ new_password, new_password_len,
+ password, password_len, cp->encr_hash);
+ }
/* Peer-Challenge */
if (os_get_random(cp->peer_challenge, MSCHAPV2_CHAL_LEN)) {
Modified: wpasupplicant/trunk/src/eap_peer/eap_tlv.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_tlv.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_tlv.h (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_tlv.h Sat Nov 3 11:46:49 2007
@@ -15,104 +15,7 @@
#ifndef EAP_TLV_H
#define EAP_TLV_H
-/* EAP-TLV TLVs (draft-josefsson-ppext-eap-tls-eap-07.txt) */
-#define EAP_TLV_RESULT_TLV 3 /* Acknowledged Result */
-#define EAP_TLV_NAK_TLV 4
-/* Note: RFC 4851, Section 4.2.4 defines 5 as Error TLV */
-#define EAP_TLV_CRYPTO_BINDING_TLV 5
-#define EAP_TLV_CONNECTION_BINDING_TLV 6
-#define EAP_TLV_VENDOR_SPECIFIC_TLV 7
-#define EAP_TLV_URI_TLV 8
-#define EAP_TLV_EAP_PAYLOAD_TLV 9
-#define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
-#define EAP_TLV_PAC_TLV 11 /* draft-cam-winget-eap-fast-provisioning-04.txt,
- * Section 4.2 */
-#define EAP_TLV_CRYPTO_BINDING_TLV_ 12 /* RFC 4851, Section 4.2.8 */
-/* draft-cam-winget-eap-fast-provisiong-04.txt, Section 4.3.1 */
-#define EAP_TLV_SERVER_TRUSTED_ROOT_TLV 18
-#define EAP_TLV_REQUEST_ACTION_TLV 19 /* RFC 4851, Section 4.2.9 */
-/* draft-cam-winget-eap-fast-provisiong-04.txt, Section 4.3.2 */
-#define EAP_TLV_PKCS7_TLV 20
-
-#define EAP_TLV_RESULT_SUCCESS 1
-#define EAP_TLV_RESULT_FAILURE 2
-
-#define EAP_TLV_TYPE_MANDATORY 0x8000
-
-#ifdef _MSC_VER
-#pragma pack(push, 1)
-#endif /* _MSC_VER */
-
-struct eap_tlv_hdr {
- be16 tlv_type;
- be16 length;
-} STRUCT_PACKED;
-
-struct eap_tlv_nak_tlv {
- be16 tlv_type;
- be16 length;
- be32 vendor_id;
- be16 nak_type;
-} STRUCT_PACKED;
-
-struct eap_tlv_result_tlv {
- be16 tlv_type;
- be16 length;
- be16 status;
-} STRUCT_PACKED;
-
-/* RFC 4851, Section 4.2.7 - Intermediate-Result TLV */
-struct eap_tlv_intermediate_result_tlv {
- be16 tlv_type;
- be16 length;
- be16 status;
- /* Followed by optional TLVs */
-} STRUCT_PACKED;
-
-/* RFC 4851, Section 4.2.8 - Crypto-Binding TLV */
-struct eap_tlv_crypto_binding__tlv {
- be16 tlv_type;
- be16 length;
- u8 reserved;
- u8 version;
- u8 received_version;
- u8 subtype;
- u8 nonce[32];
- u8 compound_mac[20];
-} STRUCT_PACKED;
-
-struct eap_tlv_pac_ack_tlv {
- be16 tlv_type;
- be16 length;
- be16 pac_type;
- be16 pac_len;
- be16 result;
-} STRUCT_PACKED;
-
-/* RFC 4851, Section 4.2.9 - Request-Action TLV */
-struct eap_tlv_request_action_tlv {
- be16 tlv_type;
- be16 length;
- be16 action;
-} STRUCT_PACKED;
-
-/* draft-cam-winget-eap-fast-provisiong-04.txt, Section 4.2.6 - PAC-Type TLV */
-struct eap_tlv_pac_type_tlv {
- be16 tlv_type; /* PAC_TYPE_PAC_TYPE */
- be16 length;
- be16 pac_type;
-} STRUCT_PACKED;
-
-#ifdef _MSC_VER
-#pragma pack(pop)
-#endif /* _MSC_VER */
-
-#define EAP_TLV_CRYPTO_BINDING_SUBTYPE_REQUEST 0
-#define EAP_TLV_CRYPTO_BINDING_SUBTYPE_RESPONSE 1
-
-#define EAP_TLV_ACTION_PROCESS_TLV 1
-#define EAP_TLV_ACTION_NEGOTIATE_EAP 2
-
+#include "eap_common/eap_tlv_common.h"
u8 * eap_tlv_build_nak(int id, u16 nak_type, size_t *resp_len);
u8 * eap_tlv_build_result(int id, u16 status, size_t *resp_len);
Modified: wpasupplicant/trunk/src/eap_peer/eap_ttls.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/eap_ttls.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/eap_ttls.c (original)
+++ wpasupplicant/trunk/src/eap_peer/eap_ttls.c Sat Nov 3 11:46:49 2007
@@ -198,7 +198,7 @@
static u8 * eap_ttls_avp_add(u8 *start, u8 *avphdr, u32 avp_code,
u32 vendor_id, int mandatory,
- u8 *data, size_t len)
+ const u8 *data, size_t len)
{
u8 *pos;
pos = eap_ttls_avp_hdr(avphdr, avp_code, vendor_id, mandatory, len);
@@ -615,13 +615,23 @@
#if EAP_TTLS_VERSION > 0
u8 pw_hash[16], pw_hash_hash[16], master_key[16];
u8 session_key[2 * MSCHAPV2_KEY_LEN];
- struct wpa_ssid *config = eap_get_config(sm);
+ const u8 *password;
+ size_t password_len;
+ int pwhash;
if (data->ttls_version == 0)
return;
- nt_password_hash(config->password, config->password_len, pw_hash);
- hash_nt_password_hash(pw_hash, pw_hash_hash);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
+ if (password == NULL)
+ return;
+
+ if (pwhash)
+ hash_nt_password_hash(password, pw_hash_hash);
+ else {
+ nt_password_hash(password, password_len, pw_hash);
+ hash_nt_password_hash(pw_hash, pw_hash_hash);
+ }
get_master_key(pw_hash_hash, nt_response, master_key);
get_asymetric_start_key(master_key, session_key,
MSCHAPV2_KEY_LEN, 0, 0);
@@ -638,18 +648,22 @@
struct eap_method_ret *ret,
u8 **resp, size_t *resp_len)
{
- struct wpa_ssid *config = eap_get_config(sm);
- u8 *buf, *pos, *challenge, *username, *peer_challenge;
- size_t username_len, i;
+ u8 *buf, *pos, *challenge, *peer_challenge;
+ const u8 *identity, *username, *password;
+ size_t identity_len, password_len, username_len, i;
+ int pwhash;
wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAPV2 Request");
/* MSCHAPv2 does not include optional domain name in the
* challenge-response calculation, so remove domain prefix
* (if present). */
- username = config->identity;
- username_len = config->identity_len;
- pos = username;
+ identity = eap_get_config_identity(sm, &identity_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
+ if (identity == NULL || password == NULL)
+ return -1;
+ username = identity;
+ username_len = identity_len;
for (i = 0; i < username_len; i++) {
if (username[i] == '\\') {
username_len -= i + 1;
@@ -658,7 +672,7 @@
}
}
- pos = buf = os_malloc(config->identity_len + 1000);
+ pos = buf = os_malloc(identity_len + 1000);
if (buf == NULL) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/MSCHAPV2: Failed to allocate memory");
@@ -667,7 +681,7 @@
/* User-Name */
pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
- config->identity, config->identity_len);
+ identity, identity_len);
/* MS-CHAP-Challenge */
challenge = eap_ttls_implicit_challenge(
@@ -701,17 +715,28 @@
peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 username",
username, username_len);
- wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 password",
- config->password, config->password_len);
- generate_nt_response(challenge, peer_challenge,
- username, username_len,
- config->password, config->password_len,
- pos);
- wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 response", pos, 24);
- generate_authenticator_response(config->password, config->password_len,
- peer_challenge, challenge,
- username, username_len,
- pos, data->auth_response);
+ if (pwhash) {
+ wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 password hash",
+ password, 16);
+ generate_nt_response_pwhash(challenge, peer_challenge,
+ username, username_len,
+ password, pos);
+ wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 response", pos, 24);
+ generate_authenticator_response_pwhash(
+ password, peer_challenge, challenge,
+ username, username_len, pos, data->auth_response);
+ } else {
+ wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 password",
+ password, password_len);
+ generate_nt_response(challenge, peer_challenge,
+ username, username_len,
+ password, password_len, pos);
+ wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAPV2 response", pos, 24);
+ generate_authenticator_response(password, password_len,
+ peer_challenge, challenge,
+ username, username_len,
+ pos, data->auth_response);
+ }
data->auth_response_valid = 1;
eap_ttlsv1_permute_inner(sm, data, pos);
@@ -742,12 +767,19 @@
struct eap_method_ret *ret,
u8 **resp, size_t *resp_len)
{
- struct wpa_ssid *config = eap_get_config(sm);
u8 *buf, *pos, *challenge;
+ const u8 *identity, *password;
+ size_t identity_len, password_len;
+ int pwhash;
wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 MSCHAP Request");
- pos = buf = os_malloc(config->identity_len + 1000);
+ identity = eap_get_config_identity(sm, &identity_len);
+ password = eap_get_config_password2(sm, &password_len, &pwhash);
+ if (identity == NULL || password == NULL)
+ return -1;
+
+ pos = buf = os_malloc(identity_len + 1000);
if (buf == NULL) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/MSCHAP: Failed to allocate memory");
@@ -756,7 +788,7 @@
/* User-Name */
pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
- config->identity, config->identity_len);
+ identity, identity_len);
/* MS-CHAP-Challenge */
challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
@@ -780,11 +812,16 @@
*pos++ = 1; /* Flags: Use NT style passwords */
os_memset(pos, 0, 24); /* LM-Response */
pos += 24;
- nt_challenge_response(challenge,
- config->password, config->password_len,
- pos); /* NT-Response */
- wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
- config->password, config->password_len);
+ if (pwhash) {
+ challenge_response(challenge, password, pos); /* NT-Response */
+ wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password hash",
+ password, 16);
+ } else {
+ nt_challenge_response(challenge, password, password_len,
+ pos); /* NT-Response */
+ wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: MSCHAP password",
+ password, password_len);
+ }
wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP implicit challenge",
challenge, EAP_TTLS_MSCHAP_CHALLENGE_LEN);
wpa_hexdump(MSG_DEBUG, "EAP-TTLS: MSCHAP response", pos, 24);
@@ -816,14 +853,19 @@
struct eap_method_ret *ret,
u8 **resp, size_t *resp_len)
{
- struct wpa_ssid *config = eap_get_config(sm);
u8 *buf, *pos;
size_t pad;
+ const u8 *identity, *password;
+ size_t identity_len, password_len;
wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 PAP Request");
- pos = buf = os_malloc(config->identity_len + config->password_len +
- 100);
+ identity = eap_get_config_identity(sm, &identity_len);
+ password = eap_get_config_password(sm, &password_len);
+ if (identity == NULL || password == NULL)
+ return -1;
+
+ pos = buf = os_malloc(identity_len + password_len + 100);
if (buf == NULL) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/PAP: Failed to allocate memory");
@@ -832,16 +874,16 @@
/* User-Name */
pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
- config->identity, config->identity_len);
+ identity, identity_len);
/* User-Password; in RADIUS, this is encrypted, but EAP-TTLS encrypts
* the data, so no separate encryption is used in the AVP itself.
* However, the password is padded to obfuscate its length. */
- pad = (16 - (config->password_len & 15)) & 15;
+ pad = (16 - (password_len & 15)) & 15;
pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_USER_PASSWORD, 0, 1,
- config->password_len + pad);
- os_memcpy(pos, config->password, config->password_len);
- pos += config->password_len;
+ password_len + pad);
+ os_memcpy(pos, password, password_len);
+ pos += password_len;
os_memset(pos, 0, pad);
pos += pad;
AVP_PAD(buf, pos);
@@ -870,14 +912,20 @@
struct eap_method_ret *ret,
u8 **resp, size_t *resp_len)
{
- struct wpa_ssid *config = eap_get_config(sm);
u8 *buf, *pos, *challenge;
const u8 *addr[3];
size_t len[3];
+ const u8 *identity, *password;
+ size_t identity_len, password_len;
wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase 2 CHAP Request");
- pos = buf = os_malloc(config->identity_len + 1000);
+ identity = eap_get_config_identity(sm, &identity_len);
+ password = eap_get_config_password(sm, &password_len);
+ if (identity == NULL || password == NULL)
+ return -1;
+
+ pos = buf = os_malloc(identity_len + 1000);
if (buf == NULL) {
wpa_printf(MSG_ERROR,
"EAP-TTLS/CHAP: Failed to allocate memory");
@@ -886,7 +934,7 @@
/* User-Name */
pos = eap_ttls_avp_add(buf, pos, RADIUS_ATTR_USER_NAME, 0, 1,
- config->identity, config->identity_len);
+ identity, identity_len);
/* CHAP-Challenge */
challenge = eap_ttls_implicit_challenge(sm, data, EAP_TLS_KEY_LEN);
@@ -909,16 +957,16 @@
/* MD5(Ident + Password + Challenge) */
addr[0] = &data->ident;
len[0] = 1;
- addr[1] = config->password;
- len[1] = config->password_len;
+ addr[1] = password;
+ len[1] = password_len;
addr[2] = challenge;
len[2] = EAP_TTLS_CHAP_CHALLENGE_LEN;
md5_vector(3, addr, len, pos);
wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: CHAP username",
- config->identity, config->identity_len);
+ identity, identity_len);
wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: CHAP password",
- config->password, config->password_len);
+ password, password_len);
wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP implicit challenge",
challenge, EAP_TTLS_CHAP_CHALLENGE_LEN);
wpa_hexdump(MSG_DEBUG, "EAP-TTLS: CHAP password",
Modified: wpasupplicant/trunk/src/eap_peer/tncc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_peer/tncc.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_peer/tncc.c (original)
+++ wpasupplicant/trunk/src/eap_peer/tncc.c Sat Nov 3 11:46:49 2007
@@ -684,9 +684,7 @@
}
pos += 6;
- while (*pos == ' ')
- pos++;
- type = atoi(pos);
+ type = strtoul(pos, NULL, 16);
wpa_printf(MSG_DEBUG, "TNC: IMC-IMV-Message Type 0x%x", type);
pos = os_strstr(start, "<Base64>");
Modified: wpasupplicant/trunk/src/eap_server/eap.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap.c Sat Nov 3 11:46:49 2007
@@ -941,6 +941,15 @@
sm->ssl_ctx = conf->ssl_ctx;
sm->eap_sim_db_priv = conf->eap_sim_db_priv;
sm->backend_auth = conf->backend_auth;
+ if (conf->pac_opaque_encr_key) {
+ sm->pac_opaque_encr_key = os_malloc(16);
+ if (sm->pac_opaque_encr_key) {
+ os_memcpy(sm->pac_opaque_encr_key,
+ conf->pac_opaque_encr_key, 16);
+ }
+ }
+ if (conf->eap_fast_a_id)
+ sm->eap_fast_a_id = strdup(conf->eap_fast_a_id);
wpa_printf(MSG_DEBUG, "EAP: Server state machine created");
@@ -967,6 +976,8 @@
free(sm->lastReqData);
free(sm->eapRespData);
free(sm->identity);
+ free(sm->pac_opaque_encr_key);
+ free(sm->eap_fast_a_id);
eap_user_free(sm->user);
free(sm);
}
Modified: wpasupplicant/trunk/src/eap_server/eap.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap.h Sat Nov 3 11:46:49 2007
@@ -57,6 +57,8 @@
void *ssl_ctx;
void *eap_sim_db_priv;
Boolean backend_auth;
+ u8 *pac_opaque_encr_key;
+ char *eap_fast_a_id;
};
Modified: wpasupplicant/trunk/src/eap_server/eap_gpsk.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_gpsk.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_gpsk.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_gpsk.c Sat Nov 3 11:46:49 2007
@@ -1,5 +1,5 @@
/*
- * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-04.txt) server
+ * hostapd / EAP-GPSK (draft-ietf-emu-eap-gpsk-06.txt) server
* Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
@@ -84,17 +84,17 @@
data->csuite_count = 0;
if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
EAP_GPSK_CIPHER_AES)) {
- WPA_PUT_BE24(data->csuite_list[data->csuite_count].vendor,
+ WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
EAP_GPSK_VENDOR_IETF);
- WPA_PUT_BE24(data->csuite_list[data->csuite_count].specifier,
+ WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
EAP_GPSK_CIPHER_AES);
data->csuite_count++;
}
if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
EAP_GPSK_CIPHER_SHA256)) {
- WPA_PUT_BE24(data->csuite_list[data->csuite_count].vendor,
+ WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
EAP_GPSK_VENDOR_IETF);
- WPA_PUT_BE24(data->csuite_list[data->csuite_count].specifier,
+ WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
EAP_GPSK_CIPHER_SHA256);
data->csuite_count++;
}
@@ -192,8 +192,8 @@
memcpy(pos, data->rand_server, EAP_GPSK_RAND_LEN);
pos += EAP_GPSK_RAND_LEN;
csuite = (struct eap_gpsk_csuite *) pos;
- WPA_PUT_BE24(csuite->vendor, data->vendor);
- WPA_PUT_BE24(csuite->specifier, data->specifier);
+ WPA_PUT_BE32(csuite->vendor, data->vendor);
+ WPA_PUT_BE16(csuite->specifier, data->specifier);
pos += sizeof(*csuite);
/* no PD_Payload_2 */
@@ -396,13 +396,13 @@
if (i == data->csuite_count) {
wpa_printf(MSG_DEBUG, "EAP-GPSK: Peer selected unsupported "
"ciphersuite %d:%d",
- WPA_GET_BE24(csuite->vendor),
- WPA_GET_BE24(csuite->specifier));
- eap_gpsk_state(data, FAILURE);
- return;
- }
- data->vendor = WPA_GET_BE24(csuite->vendor);
- data->specifier = WPA_GET_BE24(csuite->specifier);
+ WPA_GET_BE32(csuite->vendor),
+ WPA_GET_BE16(csuite->specifier));
+ eap_gpsk_state(data, FAILURE);
+ return;
+ }
+ data->vendor = WPA_GET_BE32(csuite->vendor);
+ data->specifier = WPA_GET_BE16(csuite->specifier);
wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel %d:%d",
data->vendor, data->specifier);
pos += sizeof(*csuite);
Modified: wpasupplicant/trunk/src/eap_server/eap_gtc.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_gtc.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_gtc.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_gtc.c Sat Nov 3 11:46:49 2007
@@ -20,6 +20,7 @@
struct eap_gtc_data {
enum { CONTINUE, SUCCESS, FAILURE } state;
+ int prefix;
};
@@ -32,6 +33,15 @@
return NULL;
data->state = CONTINUE;
+#ifdef EAP_FAST
+ if (sm->m && sm->m->vendor == EAP_VENDOR_IETF &&
+ sm->m->method == EAP_TYPE_FAST) {
+ wpa_printf(MSG_DEBUG, "EAP-GTC: EAP-FAST tunnel - use prefix "
+ "with challenge/response");
+ data->prefix = 1;
+ }
+#endif /* EAP_FAST */
+
return data;
}
@@ -49,8 +59,10 @@
struct eap_gtc_data *data = priv;
struct eap_hdr *req;
u8 *pos;
- char *msg = "Password";
+ char *msg;
size_t msg_len;
+
+ msg = data->prefix ? "CHALLENGE=Password" : "Password";
msg_len = strlen(msg);
req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GTC, reqDataLen,
@@ -94,6 +106,64 @@
const u8 *pos;
size_t rlen;
+ pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
+ respData, respDataLen, &rlen);
+ if (pos == NULL || rlen < 1)
+ return; /* Should not happen - frame already validated */
+
+ wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
+
+#ifdef EAP_FAST
+ if (data->prefix) {
+ const u8 *pos2, *end;
+ /* "RESPONSE=<user>\0<password>" */
+ if (rlen < 10) {
+ wpa_printf(MSG_DEBUG, "EAP-GTC: Too short response "
+ "for EAP-FAST prefix");
+ data->state = FAILURE;
+ return;
+ }
+
+ end = pos + rlen;
+ pos += 9;
+ pos2 = pos;
+ while (pos2 < end && *pos2)
+ pos2++;
+ if (pos2 == end) {
+ wpa_printf(MSG_DEBUG, "EAP-GTC: No password in "
+ "response to EAP-FAST prefix");
+ data->state = FAILURE;
+ return;
+ }
+
+ wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-GTC: Response user",
+ pos, pos2 - pos);
+ os_free(sm->identity);
+ sm->identity_len = pos2 - pos;
+ sm->identity = os_malloc(sm->identity_len);
+ if (sm->identity == NULL) {
+ data->state = FAILURE;
+ return;
+ }
+ os_memcpy(sm->identity, pos, sm->identity_len);
+
+ if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
+ wpa_hexdump_ascii(MSG_DEBUG, "EAP-GTC: Phase2 "
+ "Identity not found in the user "
+ "database",
+ sm->identity, sm->identity_len);
+ data->state = FAILURE;
+ return;
+ }
+
+ pos = pos2 + 1;
+ rlen = end - pos;
+ wpa_hexdump_ascii_key(MSG_MSGDUMP,
+ "EAP-GTC: Response password",
+ pos, rlen);
+ }
+#endif /* EAP_FAST */
+
if (sm->user == NULL || sm->user->password == NULL ||
sm->user->password_hash) {
wpa_printf(MSG_INFO, "EAP-GTC: Plaintext password not "
@@ -101,13 +171,6 @@
data->state = FAILURE;
return;
}
-
- pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GTC,
- respData, respDataLen, &rlen);
- if (pos == NULL || rlen < 1)
- return; /* Should not happen - frame already validated */
-
- wpa_hexdump_key(MSG_MSGDUMP, "EAP-GTC: Response", pos, rlen);
if (rlen != sm->user->password_len ||
memcmp(pos, sm->user->password, rlen) != 0) {
Modified: wpasupplicant/trunk/src/eap_server/eap_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_i.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_i.h (original)
+++ wpasupplicant/trunk/src/eap_server/eap_i.h Sat Nov 3 11:46:49 2007
@@ -179,6 +179,12 @@
enum {
METHOD_PENDING_NONE, METHOD_PENDING_WAIT, METHOD_PENDING_CONT
} method_pending;
+
+ u8 *auth_challenge;
+ u8 *peer_challenge;
+
+ u8 *pac_opaque_encr_key;
+ char *eap_fast_a_id;
};
int eap_user_get(struct eap_sm *sm, const u8 *identity, size_t identity_len,
Modified: wpasupplicant/trunk/src/eap_server/eap_methods.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_methods.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_methods.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_methods.c Sat Nov 3 11:46:49 2007
@@ -247,6 +247,13 @@
}
#endif /* EAP_VENDOR_TEST */
+#ifdef EAP_FAST
+ if (ret == 0) {
+ int eap_server_fast_register(void);
+ ret = eap_server_fast_register();
+ }
+#endif /* EAP_FAST */
+
return ret;
}
Modified: wpasupplicant/trunk/src/eap_server/eap_mschapv2.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_mschapv2.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_mschapv2.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_mschapv2.c Sat Nov 3 11:46:49 2007
@@ -50,6 +50,8 @@
struct eap_mschapv2_data {
u8 auth_challenge[CHALLENGE_LEN];
+ int auth_challenge_from_tls;
+ u8 *peer_challenge;
u8 auth_response[20];
enum { CHALLENGE, SUCCESS_REQ, FAILURE_REQ, SUCCESS, FAILURE } state;
u8 resp_mschapv2_id;
@@ -67,6 +69,22 @@
return NULL;
data->state = CHALLENGE;
+ if (sm->auth_challenge) {
+ os_memcpy(data->auth_challenge, sm->auth_challenge,
+ CHALLENGE_LEN);
+ data->auth_challenge_from_tls = 1;
+ }
+
+ if (sm->peer_challenge) {
+ data->peer_challenge = os_malloc(CHALLENGE_LEN);
+ if (data->peer_challenge == NULL) {
+ os_free(data);
+ return NULL;
+ }
+ os_memcpy(data->peer_challenge, sm->peer_challenge,
+ CHALLENGE_LEN);
+ }
+
return data;
}
@@ -74,6 +92,10 @@
static void eap_mschapv2_reset(struct eap_sm *sm, void *priv)
{
struct eap_mschapv2_data *data = priv;
+ if (data == NULL)
+ return;
+
+ free(data->peer_challenge);
free(data);
}
@@ -88,7 +110,8 @@
char *name = "hostapd"; /* TODO: make this configurable */
size_t ms_len;
- if (hostapd_get_rand(data->auth_challenge, CHALLENGE_LEN)) {
+ if (!data->auth_challenge_from_tls &&
+ hostapd_get_rand(data->auth_challenge, CHALLENGE_LEN)) {
wpa_printf(MSG_ERROR, "EAP-MSCHAPV2: Failed to get random "
"data");
data->state = FAILURE;
@@ -112,7 +135,8 @@
pos = (u8 *) (ms + 1);
*pos++ = CHALLENGE_LEN;
- memcpy(pos, data->auth_challenge, CHALLENGE_LEN);
+ if (!data->auth_challenge_from_tls)
+ memcpy(pos, data->auth_challenge, CHALLENGE_LEN);
wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Challenge", pos,
CHALLENGE_LEN);
pos += CHALLENGE_LEN;
@@ -306,6 +330,11 @@
name = pos;
name_len = end - name;
+ if (data->peer_challenge) {
+ wpa_printf(MSG_DEBUG, "EAP-MSCHAPV2: Using pre-configured "
+ "Peer-Challenge");
+ peer_challenge = data->peer_challenge;
+ }
wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: Peer-Challenge",
peer_challenge, 16);
wpa_hexdump(MSG_MSGDUMP, "EAP-MSCHAPV2: NT-Response", nt_response, 24);
Modified: wpasupplicant/trunk/src/eap_server/eap_tlv.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/eap_server/eap_tlv.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/eap_server/eap_tlv.c (original)
+++ wpasupplicant/trunk/src/eap_server/eap_tlv.c Sat Nov 3 11:46:49 2007
@@ -16,20 +16,7 @@
#include "common.h"
#include "eap_i.h"
-
-
-/* EAP-TLV TLVs (draft-josefsson-ppext-eap-tls-eap-07.txt) */
-#define EAP_TLV_RESULT_TLV 3 /* Acknowledged Result */
-#define EAP_TLV_NAK_TLV 4
-#define EAP_TLV_CRYPTO_BINDING_TLV 5
-#define EAP_TLV_CONNECTION_BINDING_TLV 6
-#define EAP_TLV_VENDOR_SPECIFIC_TLV 7
-#define EAP_TLV_URI_TLV 8
-#define EAP_TLV_EAP_PAYLOAD_TLV 9
-#define EAP_TLV_INTERMEDIATE_RESULT_TLV 10
-
-#define EAP_TLV_RESULT_SUCCESS 1
-#define EAP_TLV_RESULT_FAILURE 2
+#include "eap_common/eap_tlv_common.h"
struct eap_tlv_data {
Modified: wpasupplicant/trunk/src/l2_packet/l2_packet_freebsd.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/l2_packet/l2_packet_freebsd.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/l2_packet/l2_packet_freebsd.c (original)
+++ wpasupplicant/trunk/src/l2_packet/l2_packet_freebsd.c Sat Nov 3 11:46:49 2007
@@ -14,6 +14,9 @@
*/
#include "includes.h"
+#ifdef __APPLE__
+#include <net/bpf.h>
+#endif /* __APPLE__ */
#include <pcap.h>
#include <sys/ioctl.h>
@@ -231,8 +234,11 @@
void l2_packet_deinit(struct l2_packet_data *l2)
{
if (l2 != NULL) {
- if (l2->pcap)
+ if (l2->pcap) {
+ eloop_unregister_read_sock(
+ pcap_get_selectable_fd(l2->pcap));
pcap_close(l2->pcap);
+ }
os_free(l2);
}
}
Modified: wpasupplicant/trunk/src/radius/radius_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_client.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_client.c (original)
+++ wpasupplicant/trunk/src/radius/radius_client.c Sat Nov 3 11:46:49 2007
@@ -142,7 +142,8 @@
#ifndef CONFIG_NATIVE_WINDOWS
int _errno = errno;
perror("send[RADIUS]");
- if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL) {
+ if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
+ _errno == EBADF) {
hostapd_logger(radius->ctx, NULL, HOSTAPD_MODULE_RADIUS,
HOSTAPD_LEVEL_INFO,
"Send failed - maybe interface status changed -"
Modified: wpasupplicant/trunk/src/radius/radius_server.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.c (original)
+++ wpasupplicant/trunk/src/radius/radius_server.c Sat Nov 3 11:46:49 2007
@@ -87,6 +87,8 @@
int num_sess;
void *eap_sim_db_priv;
void *ssl_ctx;
+ u8 *pac_opaque_encr_key;
+ char *eap_fast_a_id;
int ipv6;
struct os_time start_time;
struct radius_server_counters counters;
@@ -309,6 +311,8 @@
eap_conf.ssl_ctx = data->ssl_ctx;
eap_conf.eap_sim_db_priv = data->eap_sim_db_priv;
eap_conf.backend_auth = TRUE;
+ eap_conf.pac_opaque_encr_key = data->pac_opaque_encr_key;
+ eap_conf.eap_fast_a_id = data->eap_fast_a_id;
sess->eap = eap_server_sm_init(sess, &radius_server_eapol_cb,
&eap_conf);
if (sess->eap == NULL) {
@@ -999,6 +1003,13 @@
data->eap_sim_db_priv = conf->eap_sim_db_priv;
data->ssl_ctx = conf->ssl_ctx;
data->ipv6 = conf->ipv6;
+ if (conf->pac_opaque_encr_key) {
+ data->pac_opaque_encr_key = os_malloc(16);
+ os_memcpy(data->pac_opaque_encr_key, conf->pac_opaque_encr_key,
+ 16);
+ }
+ if (conf->eap_fast_a_id)
+ data->eap_fast_a_id = os_strdup(conf->eap_fast_a_id);
data->get_eap_user = conf->get_eap_user;
data->clients = radius_server_read_clients(conf->client_file,
Modified: wpasupplicant/trunk/src/radius/radius_server.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/radius/radius_server.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/radius/radius_server.h (original)
+++ wpasupplicant/trunk/src/radius/radius_server.h Sat Nov 3 11:46:49 2007
@@ -24,6 +24,8 @@
void *conf_ctx;
void *eap_sim_db_priv;
void *ssl_ctx;
+ u8 *pac_opaque_encr_key;
+ char *eap_fast_a_id;
int ipv6;
int (*get_eap_user)(void *ctx, const u8 *identity, size_t identity_len,
int phase2, struct eap_user *user);
Modified: wpasupplicant/trunk/src/rsn_supp/wpa_ft.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/rsn_supp/wpa_ft.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/rsn_supp/wpa_ft.c (original)
+++ wpasupplicant/trunk/src/rsn_supp/wpa_ft.c Sat Nov 3 11:46:49 2007
@@ -229,7 +229,7 @@
pos += sizeof(*mdie);
os_memcpy(mdie->mobility_domain, sm->mobility_domain,
MOBILITY_DOMAIN_ID_LEN);
- mdie->ft_capab = RSN_FT_CAPAB_FT_OVER_AIR;
+ mdie->ft_capab = 0; /* FIX: copy from the target AP's MDIE */
/* FTIE[SNonce, R0KH-ID] */
*pos++ = WLAN_EID_FAST_BSS_TRANSITION;
@@ -747,7 +747,8 @@
if (parse.gtk[1] != keylen) {
wpa_printf(MSG_DEBUG, "FT: GTK length mismatch: received %d "
- "negotiated %d", parse.gtk[1], keylen);
+ "negotiated %lu",
+ parse.gtk[1], (unsigned long) keylen);
return -1;
}
Modified: wpasupplicant/trunk/src/tls/asn1.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/asn1.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/asn1.c (original)
+++ wpasupplicant/trunk/src/tls/asn1.c Sat Nov 3 11:46:49 2007
@@ -58,6 +58,10 @@
}
tmp &= 0x7f; /* number of subsequent octets */
hdr->length = 0;
+ if (tmp > 4) {
+ wpa_printf(MSG_DEBUG, "ASN.1: Too long length field");
+ return -1;
+ }
while (tmp--) {
if (pos >= end) {
wpa_printf(MSG_DEBUG, "ASN.1: Length "
@@ -71,7 +75,7 @@
hdr->length = tmp;
}
- if (pos + hdr->length > end) {
+ if (end < pos || hdr->length > (unsigned int) (end - pos)) {
wpa_printf(MSG_DEBUG, "ASN.1: Contents underflow");
return -1;
}
Modified: wpasupplicant/trunk/src/tls/tlsv1_client.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/tlsv1_client.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/tlsv1_client.c (original)
+++ wpasupplicant/trunk/src/tls/tlsv1_client.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
- * wpa_supplicant: TLSv1 client (RFC 2246)
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * TLSv1 client (RFC 2246)
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,614 +15,26 @@
#include "includes.h"
#include "common.h"
-#include "base64.h"
-#include "md5.h"
#include "sha1.h"
-#include "crypto.h"
#include "tls.h"
#include "tlsv1_common.h"
+#include "tlsv1_record.h"
#include "tlsv1_client.h"
-#include "x509v3.h"
+#include "tlsv1_client_i.h"
/* TODO:
* Support for a message fragmented across several records (RFC 2246, 6.2.1)
*/
-struct tlsv1_client {
- enum {
- CLIENT_HELLO, SERVER_HELLO, SERVER_CERTIFICATE,
- SERVER_KEY_EXCHANGE, SERVER_CERTIFICATE_REQUEST,
- SERVER_HELLO_DONE, CLIENT_KEY_EXCHANGE, CHANGE_CIPHER_SPEC,
- SERVER_CHANGE_CIPHER_SPEC, SERVER_FINISHED, ACK_FINISHED,
- ESTABLISHED, FAILED
- } state;
-
- struct tlsv1_record_layer rl;
-
- u8 session_id[TLS_SESSION_ID_MAX_LEN];
- size_t session_id_len;
- u8 client_random[TLS_RANDOM_LEN];
- u8 server_random[TLS_RANDOM_LEN];
- u8 master_secret[TLS_MASTER_SECRET_LEN];
-
- u8 alert_level;
- u8 alert_description;
-
- unsigned int certificate_requested:1;
- unsigned int session_resumed:1;
- unsigned int ticket:1;
- unsigned int ticket_key:1;
-
- struct crypto_public_key *server_rsa_key;
-
- struct crypto_hash *verify_md5_client;
- struct crypto_hash *verify_sha1_client;
- struct crypto_hash *verify_md5_server;
- struct crypto_hash *verify_sha1_server;
- struct crypto_hash *verify_md5_cert;
- struct crypto_hash *verify_sha1_cert;
-
-#define MAX_CIPHER_COUNT 30
- u16 cipher_suites[MAX_CIPHER_COUNT];
- size_t num_cipher_suites;
-
- u16 prev_cipher_suite;
-
- u8 *client_hello_ext;
- size_t client_hello_ext_len;
-
- /* The prime modulus used for Diffie-Hellman */
- u8 *dh_p;
- size_t dh_p_len;
- /* The generator used for Diffie-Hellman */
- u8 *dh_g;
- size_t dh_g_len;
- /* The server's Diffie-Hellman public value */
- u8 *dh_ys;
- size_t dh_ys_len;
-
- struct x509_certificate *trusted_certs;
- struct x509_certificate *client_cert;
- struct crypto_private_key *client_key;
-};
-
-
-static int tls_derive_keys(struct tlsv1_client *conn,
- const u8 *pre_master_secret,
- size_t pre_master_secret_len);
-static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len);
-static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len);
-static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len);
-
-
-static void tls_alert(struct tlsv1_client *conn, u8 level, u8 description)
+
+void tls_alert(struct tlsv1_client *conn, u8 level, u8 description)
{
conn->alert_level = level;
conn->alert_description = description;
}
-static void tls_verify_hash_add(struct tlsv1_client *conn, const u8 *buf,
- size_t len)
-{
- if (conn->verify_md5_client && conn->verify_sha1_client) {
- crypto_hash_update(conn->verify_md5_client, buf, len);
- crypto_hash_update(conn->verify_sha1_client, buf, len);
- }
- if (conn->verify_md5_server && conn->verify_sha1_server) {
- crypto_hash_update(conn->verify_md5_server, buf, len);
- crypto_hash_update(conn->verify_sha1_server, buf, len);
- }
- if (conn->verify_md5_cert && conn->verify_sha1_cert) {
- crypto_hash_update(conn->verify_md5_cert, buf, len);
- crypto_hash_update(conn->verify_sha1_cert, buf, len);
- }
-}
-
-
-static u8 * tls_send_alert(struct tlsv1_client *conn,
- u8 level, u8 description,
- size_t *out_len)
-{
- u8 *alert, *pos, *length;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send Alert(%d:%d)", level, description);
- *out_len = 0;
-
- alert = os_malloc(10);
- if (alert == NULL)
- return NULL;
-
- pos = alert;
-
- /* TLSPlaintext */
- /* ContentType type */
- *pos++ = TLS_CONTENT_TYPE_ALERT;
- /* ProtocolVersion version */
- WPA_PUT_BE16(pos, TLS_VERSION);
- pos += 2;
- /* uint16 length (to be filled) */
- length = pos;
- pos += 2;
- /* opaque fragment[TLSPlaintext.length] */
-
- /* Alert */
- /* AlertLevel level */
- *pos++ = level;
- /* AlertDescription description */
- *pos++ = description;
-
- WPA_PUT_BE16(length, pos - length - 2);
- *out_len = pos - alert;
-
- return alert;
-}
-
-
-static u8 * tls_send_client_hello(struct tlsv1_client *conn,
- size_t *out_len)
-{
- u8 *hello, *end, *pos, *hs_length, *hs_start, *rhdr;
- struct os_time now;
- size_t len, i;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send ClientHello");
- *out_len = 0;
-
- os_get_time(&now);
- WPA_PUT_BE32(conn->client_random, now.sec);
- if (os_get_random(conn->client_random + 4, TLS_RANDOM_LEN - 4)) {
- wpa_printf(MSG_ERROR, "TLSv1: Could not generate "
- "client_random");
- return NULL;
- }
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
- conn->client_random, TLS_RANDOM_LEN);
-
- len = 100 + conn->num_cipher_suites * 2 + conn->client_hello_ext_len;
- hello = os_malloc(len);
- if (hello == NULL)
- return NULL;
- end = hello + len;
-
- rhdr = hello;
- pos = rhdr + TLS_RECORD_HEADER_LEN;
-
- /* opaque fragment[TLSPlaintext.length] */
-
- /* Handshake */
- hs_start = pos;
- /* HandshakeType msg_type */
- *pos++ = TLS_HANDSHAKE_TYPE_CLIENT_HELLO;
- /* uint24 length (to be filled) */
- hs_length = pos;
- pos += 3;
- /* body - ClientHello */
- /* ProtocolVersion client_version */
- WPA_PUT_BE16(pos, TLS_VERSION);
- pos += 2;
- /* Random random: uint32 gmt_unix_time, opaque random_bytes */
- os_memcpy(pos, conn->client_random, TLS_RANDOM_LEN);
- pos += TLS_RANDOM_LEN;
- /* SessionID session_id */
- *pos++ = conn->session_id_len;
- os_memcpy(pos, conn->session_id, conn->session_id_len);
- pos += conn->session_id_len;
- /* CipherSuite cipher_suites<2..2^16-1> */
- WPA_PUT_BE16(pos, 2 * conn->num_cipher_suites);
- pos += 2;
- for (i = 0; i < conn->num_cipher_suites; i++) {
- WPA_PUT_BE16(pos, conn->cipher_suites[i]);
- pos += 2;
- }
- /* CompressionMethod compression_methods<1..2^8-1> */
- *pos++ = 1;
- *pos++ = TLS_COMPRESSION_NULL;
-
- if (conn->client_hello_ext) {
- os_memcpy(pos, conn->client_hello_ext,
- conn->client_hello_ext_len);
- pos += conn->client_hello_ext_len;
- }
-
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
- tls_verify_hash_add(conn, hs_start, pos - hs_start);
-
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
- rhdr, end - rhdr, pos - hs_start, out_len) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(hello);
- return NULL;
- }
-
- conn->state = SERVER_HELLO;
-
- return hello;
-}
-
-
-static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len, i;
- u16 cipher_suite;
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4)
- goto decode_error;
-
- /* HandshakeType msg_type */
- if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) {
- wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
- "message %d (expected ServerHello)", *pos);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
- pos++;
- /* uint24 length */
- len = WPA_GET_BE24(pos);
- pos += 3;
- left -= 4;
-
- if (len > left)
- goto decode_error;
-
- /* body - ServerHello */
-
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
- end = pos + len;
-
- /* ProtocolVersion server_version */
- if (end - pos < 2)
- goto decode_error;
- if (WPA_GET_BE16(pos) != TLS_VERSION) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
- "ServerHello");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_PROTOCOL_VERSION);
- return -1;
- }
- pos += 2;
-
- /* Random random */
- if (end - pos < TLS_RANDOM_LEN)
- goto decode_error;
-
- os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN);
- pos += TLS_RANDOM_LEN;
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
- conn->server_random, TLS_RANDOM_LEN);
-
- /* SessionID session_id */
- if (end - pos < 1)
- goto decode_error;
- if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
- goto decode_error;
- if (conn->session_id_len && conn->session_id_len == *pos &&
- os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {
- pos += 1 + conn->session_id_len;
- wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");
- conn->session_resumed = 1;
- } else {
- conn->session_id_len = *pos;
- pos++;
- os_memcpy(conn->session_id, pos, conn->session_id_len);
- pos += conn->session_id_len;
- }
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
- conn->session_id, conn->session_id_len);
-
- /* CipherSuite cipher_suite */
- if (end - pos < 2)
- goto decode_error;
- cipher_suite = WPA_GET_BE16(pos);
- pos += 2;
- for (i = 0; i < conn->num_cipher_suites; i++) {
- if (cipher_suite == conn->cipher_suites[i])
- break;
- }
- if (i == conn->num_cipher_suites) {
- wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
- "cipher suite 0x%04x", cipher_suite);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_ILLEGAL_PARAMETER);
- return -1;
- }
-
- if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {
- wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "
- "cipher suite for a resumed connection (0x%04x != "
- "0x%04x)", cipher_suite, conn->prev_cipher_suite);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_ILLEGAL_PARAMETER);
- return -1;
- }
-
- if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
- "record layer");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- conn->prev_cipher_suite = cipher_suite;
-
- if (conn->session_resumed || conn->ticket_key)
- tls_derive_keys(conn, NULL, 0);
-
- /* CompressionMethod compression_method */
- if (end - pos < 1)
- goto decode_error;
- if (*pos != TLS_COMPRESSION_NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
- "compression 0x%02x", *pos);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_ILLEGAL_PARAMETER);
- return -1;
- }
- pos++;
-
- if (end != pos) {
- wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
- "end of ServerHello", pos, end - pos);
- goto decode_error;
- }
-
- *in_len = end - in_data;
-
- conn->state = (conn->session_resumed || conn->ticket) ?
- SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
-
- return 0;
-
-decode_error:
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
-}
-
-
-static int tls_server_key_exchange_allowed(struct tlsv1_client *conn)
-{
- const struct tls_cipher_suite *suite;
-
- /* RFC 2246, Section 7.4.3 */
- suite = tls_get_cipher_suite(conn->rl.cipher_suite);
- if (suite == NULL)
- return 0;
-
- switch (suite->key_exchange) {
- case TLS_KEY_X_DHE_DSS:
- case TLS_KEY_X_DHE_DSS_EXPORT:
- case TLS_KEY_X_DHE_RSA:
- case TLS_KEY_X_DHE_RSA_EXPORT:
- case TLS_KEY_X_DH_anon_EXPORT:
- case TLS_KEY_X_DH_anon:
- return 1;
- case TLS_KEY_X_RSA_EXPORT:
- return 1 /* FIX: public key len > 512 bits */;
- default:
- return 0;
- }
-}
-
-
-static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len, list_len, cert_len, idx;
- u8 type;
- struct x509_certificate *chain = NULL, *last = NULL, *cert;
- int reason;
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
- "(len=%lu)", (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- type = *pos++;
- len = WPA_GET_BE24(pos);
- pos += 3;
- left -= 4;
-
- if (len > left) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
- "length (len=%lu != left=%lu)",
- (unsigned long) len, (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
- return tls_process_server_key_exchange(conn, ct, in_data,
- in_len);
- if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
- return tls_process_certificate_request(conn, ct, in_data,
- in_len);
- if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
- return tls_process_server_hello_done(conn, ct, in_data,
- in_len);
- if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
- "message %d (expected Certificate/"
- "ServerKeyExchange/CertificateRequest/"
- "ServerHelloDone)", type);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG,
- "TLSv1: Received Certificate (certificate_list len %lu)",
- (unsigned long) len);
-
- /*
- * opaque ASN.1Cert<2^24-1>;
- *
- * struct {
- * ASN.1Cert certificate_list<1..2^24-1>;
- * } Certificate;
- */
-
- end = pos + len;
-
- if (end - pos < 3) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
- "(left=%lu)", (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- list_len = WPA_GET_BE24(pos);
- pos += 3;
-
- if ((size_t) (end - pos) != list_len) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
- "length (len=%lu left=%lu)",
- (unsigned long) list_len,
- (unsigned long) (end - pos));
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- idx = 0;
- while (pos < end) {
- if (end - pos < 3) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
- "certificate_list");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- x509_certificate_chain_free(chain);
- return -1;
- }
-
- cert_len = WPA_GET_BE24(pos);
- pos += 3;
-
- if ((size_t) (end - pos) < cert_len) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
- "length (len=%lu left=%lu)",
- (unsigned long) cert_len,
- (unsigned long) (end - pos));
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- x509_certificate_chain_free(chain);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
- (unsigned long) idx, (unsigned long) cert_len);
-
- if (idx == 0) {
- crypto_public_key_free(conn->server_rsa_key);
- if (tls_parse_cert(pos, cert_len,
- &conn->server_rsa_key)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
- "the certificate");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_BAD_CERTIFICATE);
- x509_certificate_chain_free(chain);
- return -1;
- }
- }
-
- cert = x509_certificate_parse(pos, cert_len);
- if (cert == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
- "the certificate");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_BAD_CERTIFICATE);
- x509_certificate_chain_free(chain);
- return -1;
- }
-
- if (last == NULL)
- chain = cert;
- else
- last->next = cert;
- last = cert;
-
- idx++;
- pos += cert_len;
- }
-
- if (x509_certificate_chain_validate(conn->trusted_certs, chain,
- &reason) < 0) {
- int tls_reason;
- wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
- "validation failed (reason=%d)", reason);
- switch (reason) {
- case X509_VALIDATE_BAD_CERTIFICATE:
- tls_reason = TLS_ALERT_BAD_CERTIFICATE;
- break;
- case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
- tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
- break;
- case X509_VALIDATE_CERTIFICATE_REVOKED:
- tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
- break;
- case X509_VALIDATE_CERTIFICATE_EXPIRED:
- tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
- break;
- case X509_VALIDATE_CERTIFICATE_UNKNOWN:
- tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
- break;
- case X509_VALIDATE_UNKNOWN_CA:
- tls_reason = TLS_ALERT_UNKNOWN_CA;
- break;
- default:
- tls_reason = TLS_ALERT_BAD_CERTIFICATE;
- break;
- }
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
- x509_certificate_chain_free(chain);
- return -1;
- }
-
- x509_certificate_chain_free(chain);
-
- *in_len = end - in_data;
-
- conn->state = SERVER_KEY_EXCHANGE;
-
- return 0;
-}
-
-
-static void tlsv1_client_free_dh(struct tlsv1_client *conn)
+void tlsv1_client_free_dh(struct tlsv1_client *conn)
{
os_free(conn->dh_p);
os_free(conn->dh_g);
@@ -631,438 +43,7 @@
}
-static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
- const u8 *buf, size_t len)
-{
- const u8 *pos, *end;
-
- tlsv1_client_free_dh(conn);
-
- pos = buf;
- end = buf + len;
-
- if (end - pos < 3)
- goto fail;
- conn->dh_p_len = WPA_GET_BE16(pos);
- pos += 2;
- if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len)
- goto fail;
- conn->dh_p = os_malloc(conn->dh_p_len);
- if (conn->dh_p == NULL)
- goto fail;
- os_memcpy(conn->dh_p, pos, conn->dh_p_len);
- pos += conn->dh_p_len;
- wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
- conn->dh_p, conn->dh_p_len);
-
- if (end - pos < 3)
- goto fail;
- conn->dh_g_len = WPA_GET_BE16(pos);
- pos += 2;
- if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
- goto fail;
- conn->dh_g = os_malloc(conn->dh_g_len);
- if (conn->dh_g == NULL)
- goto fail;
- os_memcpy(conn->dh_g, pos, conn->dh_g_len);
- pos += conn->dh_g_len;
- wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
- conn->dh_g, conn->dh_g_len);
- if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
- goto fail;
-
- if (end - pos < 3)
- goto fail;
- conn->dh_ys_len = WPA_GET_BE16(pos);
- pos += 2;
- if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
- goto fail;
- conn->dh_ys = os_malloc(conn->dh_ys_len);
- if (conn->dh_ys == NULL)
- goto fail;
- os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
- pos += conn->dh_ys_len;
- wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
- conn->dh_ys, conn->dh_ys_len);
-
- return 0;
-
-fail:
- tlsv1_client_free_dh(conn);
- return -1;
-}
-
-
-static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len;
- u8 type;
- const struct tls_cipher_suite *suite;
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
- "(Left=%lu)", (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- type = *pos++;
- len = WPA_GET_BE24(pos);
- pos += 3;
- left -= 4;
-
- if (len > left) {
- wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
- "length (len=%lu != left=%lu)",
- (unsigned long) len, (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- end = pos + len;
-
- if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
- return tls_process_certificate_request(conn, ct, in_data,
- in_len);
- if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
- return tls_process_server_hello_done(conn, ct, in_data,
- in_len);
- if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
- "message %d (expected ServerKeyExchange/"
- "CertificateRequest/ServerHelloDone)", type);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
-
- if (!tls_server_key_exchange_allowed(conn)) {
- wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
- "with the selected cipher suite");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
- suite = tls_get_cipher_suite(conn->rl.cipher_suite);
- if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
- if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- return -1;
- }
- } else {
- wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- *in_len = end - in_data;
-
- conn->state = SERVER_CERTIFICATE_REQUEST;
-
- return 0;
-}
-
-
-static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len;
- u8 type;
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
- "(left=%lu)", (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- type = *pos++;
- len = WPA_GET_BE24(pos);
- pos += 3;
- left -= 4;
-
- if (len > left) {
- wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
- "length (len=%lu != left=%lu)",
- (unsigned long) len, (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- end = pos + len;
-
- if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
- return tls_process_server_hello_done(conn, ct, in_data,
- in_len);
- if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
- wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
- "message %d (expected CertificateRequest/"
- "ServerHelloDone)", type);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
-
- conn->certificate_requested = 1;
-
- *in_len = end - in_data;
-
- conn->state = SERVER_HELLO_DONE;
-
- return 0;
-}
-
-
-static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len;
- u8 type;
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
- "(left=%lu)", (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- type = *pos++;
- len = WPA_GET_BE24(pos);
- pos += 3;
- left -= 4;
-
- if (len > left) {
- wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
- "length (len=%lu != left=%lu)",
- (unsigned long) len, (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
- end = pos + len;
-
- if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
- "message %d (expected ServerHelloDone)", type);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
-
- *in_len = end - in_data;
-
- conn->state = CLIENT_KEY_EXCHANGE;
-
- return 0;
-}
-
-
-static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
- u8 ct, const u8 *in_data,
- size_t *in_len)
-{
- const u8 *pos;
- size_t left;
-
- if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 1) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- if (*pos != TLS_CHANGE_CIPHER_SPEC) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
- "received data 0x%x", *pos);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
- if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
- "for record layer");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- *in_len = pos + 1 - in_data;
-
- conn->state = SERVER_FINISHED;
-
- return 0;
-}
-
-
-static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len)
-{
- const u8 *pos, *end;
- size_t left, len, hlen;
- u8 verify_data[TLS_VERIFY_DATA_LEN];
- u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
-
- if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- if (left < 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
- "Finished",
- (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- return -1;
- }
-
- if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
- "type 0x%x", pos[0]);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- len = WPA_GET_BE24(pos + 1);
-
- pos += 4;
- left -= 4;
-
- if (len > left) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
- "(len=%lu > left=%lu)",
- (unsigned long) len, (unsigned long) left);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- return -1;
- }
- end = pos + len;
- if (len != TLS_VERIFY_DATA_LEN) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
- "in Finished: %lu (expected %d)",
- (unsigned long) len, TLS_VERIFY_DATA_LEN);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- return -1;
- }
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
- pos, TLS_VERIFY_DATA_LEN);
-
- hlen = MD5_MAC_LEN;
- if (conn->verify_md5_server == NULL ||
- crypto_hash_finish(conn->verify_md5_server, hash, &hlen) < 0) {
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- conn->verify_md5_server = NULL;
- crypto_hash_finish(conn->verify_sha1_server, NULL, NULL);
- conn->verify_sha1_server = NULL;
- return -1;
- }
- conn->verify_md5_server = NULL;
- hlen = SHA1_MAC_LEN;
- if (conn->verify_sha1_server == NULL ||
- crypto_hash_finish(conn->verify_sha1_server, hash + MD5_MAC_LEN,
- &hlen) < 0) {
- conn->verify_sha1_server = NULL;
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- conn->verify_sha1_server = NULL;
-
- if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
- "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
- verify_data, TLS_VERIFY_DATA_LEN)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECRYPT_ERROR);
- return -1;
- }
- wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
- verify_data, TLS_VERIFY_DATA_LEN);
-
- if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
- wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
-
- *in_len = end - in_data;
-
- conn->state = (conn->session_resumed || conn->ticket) ?
- CHANGE_CIPHER_SPEC : ACK_FINISHED;
-
- return 0;
-}
-
-
-static int tls_derive_pre_master_secret(u8 *pre_master_secret)
+int tls_derive_pre_master_secret(u8 *pre_master_secret)
{
WPA_PUT_BE16(pre_master_secret, TLS_VERSION);
if (os_get_random(pre_master_secret + 2,
@@ -1072,9 +53,8 @@
}
-static int tls_derive_keys(struct tlsv1_client *conn,
- const u8 *pre_master_secret,
- size_t pre_master_secret_len)
+int tls_derive_keys(struct tlsv1_client *conn,
+ const u8 *pre_master_secret, size_t pre_master_secret_len)
{
u8 seed[2 * TLS_RANDOM_LEN];
u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
@@ -1138,718 +118,6 @@
}
-static int tls_write_client_certificate(struct tlsv1_client *conn,
- u8 **msgpos, u8 *end)
-{
- u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start;
- size_t rlen;
- struct x509_certificate *cert;
-
- pos = *msgpos;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send Certificate");
- rhdr = pos;
- pos += TLS_RECORD_HEADER_LEN;
-
- /* opaque fragment[TLSPlaintext.length] */
-
- /* Handshake */
- hs_start = pos;
- /* HandshakeType msg_type */
- *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE;
- /* uint24 length (to be filled) */
- hs_length = pos;
- pos += 3;
- /* body - Certificate */
- /* uint24 length (to be filled) */
- cert_start = pos;
- pos += 3;
- cert = conn->client_cert;
- while (cert) {
- if (pos + 3 + cert->cert_len > end) {
- wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space "
- "for Certificate (cert_len=%lu left=%lu)",
- (unsigned long) cert->cert_len,
- (unsigned long) (end - pos));
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- WPA_PUT_BE24(pos, cert->cert_len);
- pos += 3;
- os_memcpy(pos, cert->cert_start, cert->cert_len);
- pos += cert->cert_len;
-
- if (x509_certificate_self_signed(cert))
- break;
- cert = x509_certificate_get_subject(conn->trusted_certs,
- &cert->issuer);
- }
- if (cert == conn->client_cert || cert == NULL) {
- /*
- * Client was not configured with all the needed certificates
- * to form a full certificate chain. The server may fail to
- * validate the chain unless it is configured with all the
- * missing CA certificates.
- */
- wpa_printf(MSG_DEBUG, "TLSv1: Full client certificate chain "
- "not configured - validation may fail");
- }
- WPA_PUT_BE24(cert_start, pos - cert_start - 3);
-
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
-
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
- rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- pos = rhdr + rlen;
-
- tls_verify_hash_add(conn, hs_start, pos - hs_start);
-
- *msgpos = pos;
-
- return 0;
-}
-
-
-static int tlsv1_key_x_anon_dh(struct tlsv1_client *conn, u8 **pos, u8 *end)
-{
-#ifdef EAP_FAST
- /* ClientDiffieHellmanPublic */
- u8 *csecret, *csecret_start, *dh_yc, *shared;
- size_t csecret_len, dh_yc_len, shared_len;
-
- csecret_len = conn->dh_p_len;
- csecret = os_malloc(csecret_len);
- if (csecret == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
- "memory for Yc (Diffie-Hellman)");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- if (os_get_random(csecret, csecret_len)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
- "data for Diffie-Hellman");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(csecret);
- return -1;
- }
-
- if (os_memcmp(csecret, conn->dh_p, csecret_len) > 0)
- csecret[0] = 0; /* make sure Yc < p */
-
- csecret_start = csecret;
- while (csecret_len > 1 && *csecret_start == 0) {
- csecret_start++;
- csecret_len--;
- }
- wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH client's secret value",
- csecret_start, csecret_len);
-
- /* Yc = g^csecret mod p */
- dh_yc_len = conn->dh_p_len;
- dh_yc = os_malloc(dh_yc_len);
- if (dh_yc == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
- "memory for Diffie-Hellman");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(csecret);
- return -1;
- }
- crypto_mod_exp(conn->dh_g, conn->dh_g_len,
- csecret_start, csecret_len,
- conn->dh_p, conn->dh_p_len,
- dh_yc, &dh_yc_len);
-
- wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",
- dh_yc, dh_yc_len);
-
- WPA_PUT_BE16(*pos, dh_yc_len);
- *pos += 2;
- if (*pos + dh_yc_len > end) {
- wpa_printf(MSG_DEBUG, "TLSv1: Not enough room in the "
- "message buffer for Yc");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(csecret);
- os_free(dh_yc);
- return -1;
- }
- os_memcpy(*pos, dh_yc, dh_yc_len);
- *pos += dh_yc_len;
- os_free(dh_yc);
-
- shared_len = conn->dh_p_len;
- shared = os_malloc(shared_len);
- if (shared == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "
- "DH");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(csecret);
- return -1;
- }
-
- /* shared = Ys^csecret mod p */
- crypto_mod_exp(conn->dh_ys, conn->dh_ys_len,
- csecret_start, csecret_len,
- conn->dh_p, conn->dh_p_len,
- shared, &shared_len);
- wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",
- shared, shared_len);
-
- os_memset(csecret_start, 0, csecret_len);
- os_free(csecret);
- if (tls_derive_keys(conn, shared, shared_len)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- os_free(shared);
- return -1;
- }
- os_memset(shared, 0, shared_len);
- os_free(shared);
- tlsv1_client_free_dh(conn);
- return 0;
-#else /* EAP_FAST */
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR);
- return -1;
-#endif /* EAP_FAST */
-}
-
-
-static int tlsv1_key_x_rsa(struct tlsv1_client *conn, u8 **pos, u8 *end)
-{
- u8 pre_master_secret[TLS_PRE_MASTER_SECRET_LEN];
- size_t clen;
- int res;
-
- if (tls_derive_pre_master_secret(pre_master_secret) < 0 ||
- tls_derive_keys(conn, pre_master_secret,
- TLS_PRE_MASTER_SECRET_LEN)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- /* EncryptedPreMasterSecret */
- if (conn->server_rsa_key == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: No server RSA key to "
- "use for encrypting pre-master secret");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- /* RSA encrypted value is encoded with PKCS #1 v1.5 block type 2. */
- *pos += 2;
- clen = end - *pos;
- res = crypto_public_key_encrypt_pkcs1_v15(
- conn->server_rsa_key,
- pre_master_secret, TLS_PRE_MASTER_SECRET_LEN,
- *pos, &clen);
- os_memset(pre_master_secret, 0, TLS_PRE_MASTER_SECRET_LEN);
- if (res < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: RSA encryption failed");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- WPA_PUT_BE16(*pos - 2, clen);
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: Encrypted pre_master_secret",
- *pos, clen);
- *pos += clen;
-
- return 0;
-}
-
-
-static int tls_write_client_key_exchange(struct tlsv1_client *conn,
- u8 **msgpos, u8 *end)
-{
- u8 *pos, *rhdr, *hs_start, *hs_length;
- size_t rlen;
- tls_key_exchange keyx;
- const struct tls_cipher_suite *suite;
-
- suite = tls_get_cipher_suite(conn->rl.cipher_suite);
- if (suite == NULL)
- keyx = TLS_KEY_X_NULL;
- else
- keyx = suite->key_exchange;
-
- pos = *msgpos;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send ClientKeyExchange");
-
- rhdr = pos;
- pos += TLS_RECORD_HEADER_LEN;
-
- /* opaque fragment[TLSPlaintext.length] */
-
- /* Handshake */
- hs_start = pos;
- /* HandshakeType msg_type */
- *pos++ = TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE;
- /* uint24 length (to be filled) */
- hs_length = pos;
- pos += 3;
- /* body - ClientKeyExchange */
- if (keyx == TLS_KEY_X_DH_anon) {
- if (tlsv1_key_x_anon_dh(conn, &pos, end) < 0)
- return -1;
- } else {
- if (tlsv1_key_x_rsa(conn, &pos, end) < 0)
- return -1;
- }
-
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
-
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
- rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- pos = rhdr + rlen;
- tls_verify_hash_add(conn, hs_start, pos - hs_start);
-
- *msgpos = pos;
-
- return 0;
-}
-
-
-static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
- u8 **msgpos, u8 *end)
-{
- u8 *pos, *rhdr, *hs_start, *hs_length, *signed_start;
- size_t rlen, hlen, clen;
- u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos;
- enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;
-
- pos = *msgpos;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send CertificateVerify");
- rhdr = pos;
- pos += TLS_RECORD_HEADER_LEN;
-
- /* Handshake */
- hs_start = pos;
- /* HandshakeType msg_type */
- *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY;
- /* uint24 length (to be filled) */
- hs_length = pos;
- pos += 3;
-
- /*
- * RFC 2246: 7.4.3 and 7.4.8:
- * Signature signature
- *
- * RSA:
- * digitally-signed struct {
- * opaque md5_hash[16];
- * opaque sha_hash[20];
- * };
- *
- * DSA:
- * digitally-signed struct {
- * opaque sha_hash[20];
- * };
- *
- * The hash values are calculated over all handshake messages sent or
- * received starting at ClientHello up to, but not including, this
- * CertificateVerify message, including the type and length fields of
- * the handshake messages.
- */
-
- hpos = hash;
-
- if (alg == SIGN_ALG_RSA) {
- hlen = MD5_MAC_LEN;
- if (conn->verify_md5_cert == NULL ||
- crypto_hash_finish(conn->verify_md5_cert, hpos, &hlen) < 0)
- {
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- conn->verify_md5_cert = NULL;
- crypto_hash_finish(conn->verify_sha1_cert, NULL, NULL);
- conn->verify_sha1_cert = NULL;
- return -1;
- }
- hpos += MD5_MAC_LEN;
- } else
- crypto_hash_finish(conn->verify_md5_cert, NULL, NULL);
-
- conn->verify_md5_cert = NULL;
- hlen = SHA1_MAC_LEN;
- if (conn->verify_sha1_cert == NULL ||
- crypto_hash_finish(conn->verify_sha1_cert, hpos, &hlen) < 0) {
- conn->verify_sha1_cert = NULL;
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- conn->verify_sha1_cert = NULL;
-
- if (alg == SIGN_ALG_RSA)
- hlen += MD5_MAC_LEN;
-
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
-
- /*
- * RFC 2246, 4.7:
- * In digital signing, one-way hash functions are used as input for a
- * signing algorithm. A digitally-signed element is encoded as an
- * opaque vector <0..2^16-1>, where the length is specified by the
- * signing algorithm and key.
- *
- * In RSA signing, a 36-byte structure of two hashes (one SHA and one
- * MD5) is signed (encrypted with the private key). It is encoded with
- * PKCS #1 block type 0 or type 1 as described in [PKCS1].
- */
- signed_start = pos; /* length to be filled */
- pos += 2;
- clen = end - pos;
- if (crypto_private_key_sign_pkcs1(conn->client_key, hash, hlen,
- pos, &clen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to sign hash (PKCS #1)");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- WPA_PUT_BE16(signed_start, clen);
-
- pos += clen;
-
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
-
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
- rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- pos = rhdr + rlen;
-
- tls_verify_hash_add(conn, hs_start, pos - hs_start);
-
- *msgpos = pos;
-
- return 0;
-}
-
-
-static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
- u8 **msgpos, u8 *end)
-{
- u8 *pos, *rhdr;
- size_t rlen;
-
- pos = *msgpos;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
- rhdr = pos;
- pos += TLS_RECORD_HEADER_LEN;
- *pos = TLS_CHANGE_CIPHER_SPEC;
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
- rhdr, end - rhdr, 1, &rlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- if (tlsv1_record_change_write_cipher(&conn->rl) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for "
- "record layer");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- *msgpos = rhdr + rlen;
-
- return 0;
-}
-
-
-static int tls_write_client_finished(struct tlsv1_client *conn,
- u8 **msgpos, u8 *end)
-{
- u8 *pos, *rhdr, *hs_start, *hs_length;
- size_t rlen, hlen;
- u8 verify_data[TLS_VERIFY_DATA_LEN];
- u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
-
- pos = *msgpos;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
-
- /* Encrypted Handshake Message: Finished */
-
- hlen = MD5_MAC_LEN;
- if (conn->verify_md5_client == NULL ||
- crypto_hash_finish(conn->verify_md5_client, hash, &hlen) < 0) {
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- conn->verify_md5_client = NULL;
- crypto_hash_finish(conn->verify_sha1_client, NULL, NULL);
- conn->verify_sha1_client = NULL;
- return -1;
- }
- conn->verify_md5_client = NULL;
- hlen = SHA1_MAC_LEN;
- if (conn->verify_sha1_client == NULL ||
- crypto_hash_finish(conn->verify_sha1_client, hash + MD5_MAC_LEN,
- &hlen) < 0) {
- conn->verify_sha1_client = NULL;
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- conn->verify_sha1_client = NULL;
-
- if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
- "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
- verify_data, TLS_VERIFY_DATA_LEN)) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
- wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
- verify_data, TLS_VERIFY_DATA_LEN);
-
- rhdr = pos;
- pos += TLS_RECORD_HEADER_LEN;
- /* Handshake */
- hs_start = pos;
- /* HandshakeType msg_type */
- *pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
- /* uint24 length (to be filled) */
- hs_length = pos;
- pos += 3;
- os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
- pos += TLS_VERIFY_DATA_LEN;
- WPA_PUT_BE24(hs_length, pos - hs_length - 3);
- tls_verify_hash_add(conn, hs_start, pos - hs_start);
-
- if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
- rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_INTERNAL_ERROR);
- return -1;
- }
-
- pos = rhdr + rlen;
-
- *msgpos = pos;
-
- return 0;
-}
-
-
-static size_t tls_client_cert_chain_der_len(struct tlsv1_client *conn)
-{
- size_t len = 0;
- struct x509_certificate *cert;
-
- cert = conn->client_cert;
- while (cert) {
- len += 3 + cert->cert_len;
- if (x509_certificate_self_signed(cert))
- break;
- cert = x509_certificate_get_subject(conn->trusted_certs,
- &cert->issuer);
- }
-
- return len;
-}
-
-
-static u8 * tls_send_client_key_exchange(struct tlsv1_client *conn,
- size_t *out_len)
-{
- u8 *msg, *end, *pos;
- size_t msglen;
-
- *out_len = 0;
-
- msglen = 1000;
- if (conn->certificate_requested)
- msglen += tls_client_cert_chain_der_len(conn);
-
- msg = os_malloc(msglen);
- if (msg == NULL)
- return NULL;
-
- pos = msg;
- end = msg + msglen;
-
- if (conn->certificate_requested) {
- if (tls_write_client_certificate(conn, &pos, end) < 0) {
- os_free(msg);
- return NULL;
- }
- }
-
- if (tls_write_client_key_exchange(conn, &pos, end) < 0 ||
- (conn->certificate_requested && conn->client_key &&
- tls_write_client_certificate_verify(conn, &pos, end) < 0) ||
- tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||
- tls_write_client_finished(conn, &pos, end) < 0) {
- os_free(msg);
- return NULL;
- }
-
- *out_len = pos - msg;
-
- conn->state = SERVER_CHANGE_CIPHER_SPEC;
-
- return msg;
-}
-
-
-static u8 * tls_send_change_cipher_spec(struct tlsv1_client *conn,
- size_t *out_len)
-{
- u8 *msg, *end, *pos;
-
- *out_len = 0;
-
- msg = os_malloc(1000);
- if (msg == NULL)
- return NULL;
-
- pos = msg;
- end = msg + 1000;
-
- if (tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||
- tls_write_client_finished(conn, &pos, end) < 0) {
- os_free(msg);
- return NULL;
- }
-
- *out_len = pos - msg;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Session resumption completed "
- "successfully");
- conn->state = ESTABLISHED;
-
- return msg;
-}
-
-
-static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
- const u8 *in_data, size_t *in_len,
- u8 **out_data, size_t *out_len)
-{
- const u8 *pos;
- size_t left;
-
- if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
- wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
- "received content type 0x%x", ct);
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- pos = in_data;
- left = *in_len;
-
- wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
- pos, left);
-
- *out_data = os_malloc(left);
- if (*out_data) {
- os_memcpy(*out_data, pos, left);
- *out_len = left;
- }
-
- return 0;
-}
-
-
-static int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
- const u8 *buf, size_t *len,
- u8 **out_data, size_t *out_len)
-{
- if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
- buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
- size_t hr_len = WPA_GET_BE24(buf + 1);
- if (hr_len > *len - 4) {
- wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
- tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
- TLS_ALERT_DECODE_ERROR);
- return -1;
- }
- wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
- *len = 4 + hr_len;
- return 0;
- }
-
- switch (conn->state) {
- case SERVER_HELLO:
- if (tls_process_server_hello(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_CERTIFICATE:
- if (tls_process_certificate(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_KEY_EXCHANGE:
- if (tls_process_server_key_exchange(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_CERTIFICATE_REQUEST:
- if (tls_process_certificate_request(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_HELLO_DONE:
- if (tls_process_server_hello_done(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_CHANGE_CIPHER_SPEC:
- if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
- return -1;
- break;
- case SERVER_FINISHED:
- if (tls_process_server_finished(conn, ct, buf, len))
- return -1;
- break;
- case ACK_FINISHED:
- if (out_data &&
- tls_process_application_data(conn, ct, buf, len, out_data,
- out_len))
- return -1;
- break;
- default:
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
- "while processing received message",
- conn->state);
- return -1;
- }
-
- if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
- tls_verify_hash_add(conn, buf, *len);
-
- return 0;
-}
-
-
/**
* tlsv1_client_handshake - Process TLS handshake
* @conn: TLSv1 client connection data from tlsv1_client_init()
@@ -1866,6 +134,7 @@
const u8 *pos, *end;
u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
size_t in_msg_len;
+ int no_appl_data;
if (conn->state == CLIENT_HELLO) {
if (in_len)
@@ -1915,36 +184,20 @@
os_free(in_msg);
in_msg = NULL;
- switch (conn->state) {
- case CLIENT_KEY_EXCHANGE:
- msg = tls_send_client_key_exchange(conn, out_len);
- break;
- case CHANGE_CIPHER_SPEC:
- msg = tls_send_change_cipher_spec(conn, out_len);
- break;
- case ACK_FINISHED:
- wpa_printf(MSG_DEBUG, "TLSv1: Handshake completed "
- "successfully");
- conn->state = ESTABLISHED;
- if (appl_data == NULL || *appl_data == NULL) {
- /* Need to return something to get final TLS ACK. */
- msg = os_malloc(1);
- }
- *out_len = 0;
- break;
- default:
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d while "
- "generating reply", conn->state);
- break;
- }
+ no_appl_data = appl_data == NULL || *appl_data == NULL;
+ msg = tlsv1_client_handshake_write(conn, out_len, no_appl_data);
failed:
os_free(in_msg);
if (conn->alert_level) {
conn->state = FAILED;
os_free(msg);
- msg = tls_send_alert(conn, conn->alert_level,
- conn->alert_description, out_len);
+ msg = tlsv1_client_send_alert(conn, conn->alert_level,
+ conn->alert_description,
+ out_len);
+ } else if (msg == NULL) {
+ msg = os_zalloc(1);
+ *out_len = 0;
}
return msg;
@@ -2071,49 +324,6 @@
}
-static void tlsv1_client_free_verify_hashes(struct tlsv1_client *conn)
-{
- crypto_hash_finish(conn->verify_md5_client, NULL, NULL);
- crypto_hash_finish(conn->verify_md5_server, NULL, NULL);
- crypto_hash_finish(conn->verify_md5_cert, NULL, NULL);
- crypto_hash_finish(conn->verify_sha1_client, NULL, NULL);
- crypto_hash_finish(conn->verify_sha1_server, NULL, NULL);
- crypto_hash_finish(conn->verify_sha1_cert, NULL, NULL);
- conn->verify_md5_client = NULL;
- conn->verify_md5_server = NULL;
- conn->verify_md5_cert = NULL;
- conn->verify_sha1_client = NULL;
- conn->verify_sha1_server = NULL;
- conn->verify_sha1_cert = NULL;
-}
-
-
-static int tlsv1_client_init_verify_hashes(struct tlsv1_client *conn)
-{
- conn->verify_md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL,
- 0);
- conn->verify_md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL,
- 0);
- conn->verify_md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
- conn->verify_sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL,
- 0);
- conn->verify_sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL,
- 0);
- conn->verify_sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL,
- 0);
- if (conn->verify_md5_client == NULL ||
- conn->verify_md5_server == NULL ||
- conn->verify_md5_cert == NULL ||
- conn->verify_sha1_client == NULL ||
- conn->verify_sha1_server == NULL ||
- conn->verify_sha1_cert == NULL) {
- tlsv1_client_free_verify_hashes(conn);
- return -1;
- }
- return 0;
-}
-
-
/**
* tlsv1_client_init - Initialize TLSv1 client connection
* Returns: Pointer to TLSv1 client connection data or %NULL on failure
@@ -2130,7 +340,7 @@
conn->state = CLIENT_HELLO;
- if (tlsv1_client_init_verify_hashes(conn) < 0) {
+ if (tls_verify_hash_init(&conn->verify) < 0) {
wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
"hash");
os_free(conn);
@@ -2162,12 +372,10 @@
tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
tlsv1_record_change_write_cipher(&conn->rl);
tlsv1_record_change_read_cipher(&conn->rl);
- tlsv1_client_free_verify_hashes(conn);
+ tls_verify_hash_free(&conn->verify);
os_free(conn->client_hello_ext);
tlsv1_client_free_dh(conn);
- x509_certificate_chain_free(conn->trusted_certs);
- x509_certificate_chain_free(conn->client_cert);
- crypto_private_key_free(conn->client_key);
+ tlsv1_cred_free(conn->cred);
os_free(conn);
}
@@ -2271,8 +479,7 @@
{
conn->state = CLIENT_HELLO;
- tlsv1_client_free_verify_hashes(conn);
- if (tlsv1_client_init_verify_hashes(conn) < 0) {
+ if (tls_verify_hash_init(&conn->verify) < 0) {
wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
"hash");
return -1;
@@ -2315,7 +522,7 @@
{
u8 *pos;
- conn->ticket = 0;
+ conn->session_ticket_included = 0;
os_free(conn->client_hello_ext);
conn->client_hello_ext = NULL;
conn->client_hello_ext_len = 0;
@@ -2337,7 +544,7 @@
conn->client_hello_ext_len = 6 + data_len;
if (ext_type == TLS_EXT_PAC_OPAQUE) {
- conn->ticket = 1;
+ conn->session_ticket_included = 1;
wpa_printf(MSG_DEBUG, "TLSv1: Using session ticket");
}
@@ -2372,27 +579,6 @@
/**
- * tlsv1_client_set_master_key - Configure master secret for TLS connection
- * @conn: TLSv1 client connection data from tlsv1_client_init()
- * @key: TLS pre-master-secret
- * @key_len: length of key in bytes
- * Returns: 0 on success, -1 on failure
- */
-int tlsv1_client_set_master_key(struct tlsv1_client *conn,
- const u8 *key, size_t key_len)
-{
- if (key_len > TLS_MASTER_SECRET_LEN)
- return -1;
- wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret from session "
- "ticket", key, key_len);
- os_memcpy(conn->master_secret, key, key_len);
- conn->ticket_key = 1;
-
- return 0;
-}
-
-
-/**
* tlsv1_client_get_keyblock_size - Get TLS key_block size
* @conn: TLSv1 client connection data from tlsv1_client_init()
* Returns: Size of the key_block for the negotiated cipher suite or -1 on
@@ -2425,7 +611,9 @@
if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
count = 0;
suites = conn->cipher_suites;
+#ifndef CONFIG_CRYPTO_INTERNAL
suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
+#endif /* CONFIG_CRYPTO_INTERNAL */
suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
@@ -2440,223 +628,31 @@
}
-static int tlsv1_client_add_cert_der(struct x509_certificate **chain,
- const u8 *buf, size_t len)
-{
- struct x509_certificate *cert;
- char name[128];
-
- cert = x509_certificate_parse(buf, len);
- if (cert == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: %s - failed to parse certificate",
- __func__);
- return -1;
- }
-
- cert->next = *chain;
- *chain = cert;
-
- x509_name_string(&cert->subject, name, sizeof(name));
- wpa_printf(MSG_DEBUG, "TLSv1: Added certificate: %s", name);
-
- return 0;
-}
-
-
-static const char *pem_cert_begin = "-----BEGIN CERTIFICATE-----";
-static const char *pem_cert_end = "-----END CERTIFICATE-----";
-
-
-static const u8 * search_tag(const char *tag, const u8 *buf, size_t len)
-{
- size_t i, plen;
-
- plen = os_strlen(tag);
- if (len < plen)
- return NULL;
-
- for (i = 0; i < len - plen; i++) {
- if (os_memcmp(buf + i, tag, plen) == 0)
- return buf + i;
- }
-
- return NULL;
-}
-
-
-static int tlsv1_client_add_cert(struct x509_certificate **chain,
- const u8 *buf, size_t len)
-{
- const u8 *pos, *end;
- unsigned char *der;
- size_t der_len;
-
- pos = search_tag(pem_cert_begin, buf, len);
- if (!pos) {
- wpa_printf(MSG_DEBUG, "TLSv1: No PEM certificate tag found - "
- "assume DER format");
- return tlsv1_client_add_cert_der(chain, buf, len);
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Converting PEM format certificate into "
- "DER format");
-
- while (pos) {
- pos += os_strlen(pem_cert_begin);
- end = search_tag(pem_cert_end, pos, buf + len - pos);
- if (end == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Could not find PEM "
- "certificate end tag (%s)", pem_cert_end);
- return -1;
- }
-
- der = base64_decode(pos, end - pos, &der_len);
- if (der == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Could not decode PEM "
- "certificate");
- return -1;
- }
-
- if (tlsv1_client_add_cert_der(chain, der, der_len) < 0) {
- wpa_printf(MSG_INFO, "TLSv1: Failed to parse PEM "
- "certificate after DER conversion");
- os_free(der);
- return -1;
- }
-
- os_free(der);
-
- end += os_strlen(pem_cert_end);
- pos = search_tag(pem_cert_begin, end, buf + len - end);
- }
-
- return 0;
-}
-
-
-static int tlsv1_client_set_cert_chain(struct x509_certificate **chain,
- const char *cert, const u8 *cert_blob,
- size_t cert_blob_len)
-{
- if (cert_blob)
- return tlsv1_client_add_cert(chain, cert_blob, cert_blob_len);
-
- if (cert) {
- u8 *buf;
- size_t len;
- int ret;
-
- buf = (u8 *) os_readfile(cert, &len);
- if (buf == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
- cert);
- return -1;
- }
-
- ret = tlsv1_client_add_cert(chain, buf, len);
- os_free(buf);
- return ret;
- }
-
- return 0;
-}
-
-
-/**
- * tlsv1_client_set_ca_cert - Set trusted CA certificate(s)
- * @conn: TLSv1 client connection data from tlsv1_client_init()
- * @cert: File or reference name for X.509 certificate in PEM or DER format
- * @cert_blob: cert as inlined data or %NULL if not used
- * @cert_blob_len: ca_cert_blob length
- * @path: Path to CA certificates (not yet supported)
- * Returns: 0 on success, -1 on failure
- */
-int tlsv1_client_set_ca_cert(struct tlsv1_client *conn, const char *cert,
- const u8 *cert_blob, size_t cert_blob_len,
- const char *path)
-{
- if (tlsv1_client_set_cert_chain(&conn->trusted_certs, cert,
- cert_blob, cert_blob_len) < 0)
- return -1;
-
- if (path) {
- /* TODO: add support for reading number of certificate files */
- wpa_printf(MSG_INFO, "TLSv1: Use of CA certificate directory "
- "not yet supported");
- return -1;
- }
-
- return 0;
-}
-
-
-/**
- * tlsv1_client_set_client_cert - Set client certificate
- * @conn: TLSv1 client connection data from tlsv1_client_init()
- * @cert: File or reference name for X.509 certificate in PEM or DER format
- * @cert_blob: cert as inlined data or %NULL if not used
- * @cert_blob_len: ca_cert_blob length
- * Returns: 0 on success, -1 on failure
- */
-int tlsv1_client_set_client_cert(struct tlsv1_client *conn, const char *cert,
- const u8 *cert_blob, size_t cert_blob_len)
-{
- return tlsv1_client_set_cert_chain(&conn->client_cert, cert,
- cert_blob, cert_blob_len);
-}
-
-
-static int tlsv1_client_set_key(struct tlsv1_client *conn,
- const u8 *key, size_t len)
-{
- conn->client_key = crypto_private_key_import(key, len);
- if (conn->client_key == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Failed to parse private key");
- return -1;
- }
- return 0;
-}
-
-
-/**
- * tlsv1_client_set_private_key - Set client private key
- * @conn: TLSv1 client connection data from tlsv1_client_init()
- * @private_key: File or reference name for the key in PEM or DER format
- * @private_key_passwd: Passphrase for decrypted private key, %NULL if no
- * passphrase is used.
- * @private_key_blob: private_key as inlined data or %NULL if not used
- * @private_key_blob_len: private_key_blob length
- * Returns: 0 on success, -1 on failure
- */
-int tlsv1_client_set_private_key(struct tlsv1_client *conn,
- const char *private_key,
- const char *private_key_passwd,
- const u8 *private_key_blob,
- size_t private_key_blob_len)
-{
- crypto_private_key_free(conn->client_key);
- conn->client_key = NULL;
-
- if (private_key_blob)
- return tlsv1_client_set_key(conn, private_key_blob,
- private_key_blob_len);
-
- if (private_key) {
- u8 *buf;
- size_t len;
- int ret;
-
- buf = (u8 *) os_readfile(private_key, &len);
- if (buf == NULL) {
- wpa_printf(MSG_INFO, "TLSv1: Failed to read '%s'",
- private_key);
- return -1;
- }
-
- ret = tlsv1_client_set_key(conn, buf, len);
- os_free(buf);
- return ret;
- }
-
- return 0;
-}
+/**
+ * tlsv1_client_set_cred - Set client credentials
+ * @conn: TLSv1 client connection data from tlsv1_client_init()
+ * @cred: Credentials from tlsv1_cred_alloc()
+ * Returns: 0 on success, -1 on failure
+ *
+ * On success, the client takes ownership of the credentials block and caller
+ * must not free it. On failure, caller is responsible for freeing the
+ * credential block.
+ */
+int tlsv1_client_set_cred(struct tlsv1_client *conn,
+ struct tlsv1_credentials *cred)
+{
+ tlsv1_cred_free(conn->cred);
+ conn->cred = cred;
+ return 0;
+}
+
+
+void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn,
+ tlsv1_client_session_ticket_cb cb,
+ void *ctx)
+{
+ wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
+ cb, ctx);
+ conn->session_ticket_cb = cb;
+ conn->session_ticket_cb_ctx = ctx;
+}
Modified: wpasupplicant/trunk/src/tls/tlsv1_client.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/tlsv1_client.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/tlsv1_client.h (original)
+++ wpasupplicant/trunk/src/tls/tlsv1_client.h Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
- * wpa_supplicant: TLSv1 client (RFC 2246)
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * TLSv1 client (RFC 2246)
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,8 @@
#ifndef TLSV1_CLIENT_H
#define TLSV1_CLIENT_H
+
+#include "tlsv1_cred.h"
struct tlsv1_client;
@@ -41,19 +43,17 @@
int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type,
const u8 *data, size_t data_len);
int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys);
-int tlsv1_client_set_master_key(struct tlsv1_client *conn,
- const u8 *key, size_t key_len);
int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn);
int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers);
-int tlsv1_client_set_ca_cert(struct tlsv1_client *conn, const char *cert,
- const u8 *cert_blob, size_t cert_blob_len,
- const char *path);
-int tlsv1_client_set_client_cert(struct tlsv1_client *conn, const char *cert,
- const u8 *cert_blob, size_t cert_blob_len);
-int tlsv1_client_set_private_key(struct tlsv1_client *conn,
- const char *private_key,
- const char *private_key_passwd,
- const u8 *private_key_blob,
- size_t private_key_blob_len);
+int tlsv1_client_set_cred(struct tlsv1_client *conn,
+ struct tlsv1_credentials *cred);
+
+typedef int (*tlsv1_client_session_ticket_cb)
+(void *ctx, const u8 *ticket, size_t len, const u8 *client_random,
+ const u8 *server_random, u8 *master_secret);
+
+void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn,
+ tlsv1_client_session_ticket_cb cb,
+ void *ctx);
#endif /* TLSV1_CLIENT_H */
Modified: wpasupplicant/trunk/src/tls/tlsv1_common.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/tlsv1_common.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/tlsv1_common.c (original)
+++ wpasupplicant/trunk/src/tls/tlsv1_common.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
- * wpa_supplicant/hostapd: TLSv1 common routines
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * TLSv1 common routines
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,9 +15,6 @@
#include "includes.h"
#include "common.h"
-#include "md5.h"
-#include "sha1.h"
-#include "crypto.h"
#include "x509v3.h"
#include "tlsv1_common.h"
@@ -101,13 +98,38 @@
}
-static const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
+const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher)
{
size_t i;
for (i = 0; i < NUM_TLS_CIPHER_DATA; i++)
if (tls_ciphers[i].cipher == cipher)
return &tls_ciphers[i];
return NULL;
+}
+
+
+int tls_server_key_exchange_allowed(tls_cipher cipher)
+{
+ const struct tls_cipher_suite *suite;
+
+ /* RFC 2246, Section 7.4.3 */
+ suite = tls_get_cipher_suite(cipher);
+ if (suite == NULL)
+ return 0;
+
+ switch (suite->key_exchange) {
+ case TLS_KEY_X_DHE_DSS:
+ case TLS_KEY_X_DHE_DSS_EXPORT:
+ case TLS_KEY_X_DHE_RSA:
+ case TLS_KEY_X_DHE_RSA_EXPORT:
+ case TLS_KEY_X_DH_anon_EXPORT:
+ case TLS_KEY_X_DH_anon:
+ return 1;
+ case TLS_KEY_X_RSA_EXPORT:
+ return 1 /* FIX: public key len > 512 bits */;
+ default:
+ return 0;
+ }
}
@@ -165,388 +187,55 @@
}
-/**
- * tlsv1_record_set_cipher_suite - TLS record layer: Set cipher suite
- * @rl: Pointer to TLS record layer data
- * @cipher_suite: New cipher suite
- * Returns: 0 on success, -1 on failure
- *
- * This function is used to prepare TLS record layer for cipher suite change.
- * tlsv1_record_change_write_cipher() and
- * tlsv1_record_change_read_cipher() functions can then be used to change the
- * currently used ciphers.
- */
-int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
- u16 cipher_suite)
-{
- const struct tls_cipher_suite *suite;
- const struct tls_cipher_data *data;
-
- wpa_printf(MSG_DEBUG, "TLSv1: Selected cipher suite: 0x%04x",
- cipher_suite);
- rl->cipher_suite = cipher_suite;
-
- suite = tls_get_cipher_suite(cipher_suite);
- if (suite == NULL)
+int tls_verify_hash_init(struct tls_verify_hash *verify)
+{
+ tls_verify_hash_free(verify);
+ verify->md5_client = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
+ verify->md5_server = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
+ verify->md5_cert = crypto_hash_init(CRYPTO_HASH_ALG_MD5, NULL, 0);
+ verify->sha1_client = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
+ verify->sha1_server = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
+ verify->sha1_cert = crypto_hash_init(CRYPTO_HASH_ALG_SHA1, NULL, 0);
+ if (verify->md5_client == NULL || verify->md5_server == NULL ||
+ verify->md5_cert == NULL || verify->sha1_client == NULL ||
+ verify->sha1_server == NULL || verify->sha1_cert == NULL) {
+ tls_verify_hash_free(verify);
return -1;
-
- if (suite->hash == TLS_HASH_MD5) {
- rl->hash_alg = CRYPTO_HASH_ALG_HMAC_MD5;
- rl->hash_size = MD5_MAC_LEN;
- } else if (suite->hash == TLS_HASH_SHA) {
- rl->hash_alg = CRYPTO_HASH_ALG_HMAC_SHA1;
- rl->hash_size = SHA1_MAC_LEN;
- }
-
- data = tls_get_cipher_data(suite->cipher);
- if (data == NULL)
- return -1;
-
- rl->key_material_len = data->key_material;
- rl->iv_size = data->block_size;
- rl->cipher_alg = data->alg;
-
+ }
return 0;
}
-/**
- * tlsv1_record_change_write_cipher - TLS record layer: Change write cipher
- * @rl: Pointer to TLS record layer data
- * Returns: 0 on success (cipher changed), -1 on failure
- *
- * This function changes TLS record layer to use the new cipher suite
- * configured with tlsv1_record_set_cipher_suite() for writing.
- */
-int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl)
-{
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New write cipher suite "
- "0x%04x", rl->cipher_suite);
- rl->write_cipher_suite = rl->cipher_suite;
- os_memset(rl->write_seq_num, 0, TLS_SEQ_NUM_LEN);
-
- if (rl->write_cbc) {
- crypto_cipher_deinit(rl->write_cbc);
- rl->write_cbc = NULL;
- }
- if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
- rl->write_cbc = crypto_cipher_init(rl->cipher_alg,
- rl->write_iv, rl->write_key,
- rl->key_material_len);
- if (rl->write_cbc == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
- "cipher");
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/**
- * tlsv1_record_change_read_cipher - TLS record layer: Change read cipher
- * @rl: Pointer to TLS record layer data
- * Returns: 0 on success (cipher changed), -1 on failure
- *
- * This function changes TLS record layer to use the new cipher suite
- * configured with tlsv1_record_set_cipher_suite() for reading.
- */
-int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl)
-{
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - New read cipher suite "
- "0x%04x", rl->cipher_suite);
- rl->read_cipher_suite = rl->cipher_suite;
- os_memset(rl->read_seq_num, 0, TLS_SEQ_NUM_LEN);
-
- if (rl->read_cbc) {
- crypto_cipher_deinit(rl->read_cbc);
- rl->read_cbc = NULL;
- }
- if (rl->cipher_alg != CRYPTO_CIPHER_NULL) {
- rl->read_cbc = crypto_cipher_init(rl->cipher_alg,
- rl->read_iv, rl->read_key,
- rl->key_material_len);
- if (rl->read_cbc == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize "
- "cipher");
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/**
- * tlsv1_record_send - TLS record layer: Send a message
- * @rl: Pointer to TLS record layer data
- * @content_type: Content type (TLS_CONTENT_TYPE_*)
- * @buf: Buffer to send (with TLS_RECORD_HEADER_LEN octets reserved in the
- * beginning for record layer to fill in; payload filled in after this and
- * extra space in the end for HMAC).
- * @buf_size: Maximum buf size
- * @payload_len: Length of the payload
- * @out_len: Buffer for returning the used buf length
- * Returns: 0 on success, -1 on failure
- *
- * This function fills in the TLS record layer header, adds HMAC, and encrypts
- * the data using the current write cipher.
- */
-int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
- size_t buf_size, size_t payload_len, size_t *out_len)
-{
- u8 *pos, *ct_start, *length, *payload;
- struct crypto_hash *hmac;
- size_t clen;
-
- pos = buf;
- /* ContentType type */
- ct_start = pos;
- *pos++ = content_type;
- /* ProtocolVersion version */
- WPA_PUT_BE16(pos, TLS_VERSION);
- pos += 2;
- /* uint16 length */
- length = pos;
- WPA_PUT_BE16(length, payload_len);
- pos += 2;
-
- /* opaque fragment[TLSPlaintext.length] */
- payload = pos;
- pos += payload_len;
-
- if (rl->write_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
- hmac = crypto_hash_init(rl->hash_alg, rl->write_mac_secret,
- rl->hash_size);
- if (hmac == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
- "to initialize HMAC");
- return -1;
- }
- crypto_hash_update(hmac, rl->write_seq_num, TLS_SEQ_NUM_LEN);
- /* type + version + length + fragment */
- crypto_hash_update(hmac, ct_start, pos - ct_start);
- clen = buf + buf_size - pos;
- if (clen < rl->hash_size) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Not "
- "enough room for MAC");
- crypto_hash_finish(hmac, NULL, NULL);
- return -1;
- }
-
- if (crypto_hash_finish(hmac, pos, &clen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
- "to calculate HMAC");
- return -1;
- }
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Write HMAC",
- pos, clen);
- pos += clen;
- if (rl->iv_size) {
- size_t len = pos - payload;
- size_t pad;
- pad = (len + 1) % rl->iv_size;
- if (pad)
- pad = rl->iv_size - pad;
- if (pos + pad + 1 > buf + buf_size) {
- wpa_printf(MSG_DEBUG, "TLSv1: No room for "
- "block cipher padding");
- return -1;
- }
- os_memset(pos, pad, pad + 1);
- pos += pad + 1;
- }
-
- if (crypto_cipher_encrypt(rl->write_cbc, payload,
- payload, pos - payload) < 0)
- return -1;
- }
-
- WPA_PUT_BE16(length, pos - length - 2);
- inc_byte_array(rl->write_seq_num, TLS_SEQ_NUM_LEN);
-
- *out_len = pos - buf;
-
- return 0;
-}
-
-
-/**
- * tlsv1_record_receive - TLS record layer: Process a received message
- * @rl: Pointer to TLS record layer data
- * @in_data: Received data
- * @in_len: Length of the received data
- * @out_data: Buffer for output data (must be at least as long as in_data)
- * @out_len: Set to maximum out_data length by caller; used to return the
- * length of the used data
- * @alert: Buffer for returning an alert value on failure
- * Returns: 0 on success, -1 on failure
- *
- * This function decrypts the received message, verifies HMAC and TLS record
- * layer header.
- */
-int tlsv1_record_receive(struct tlsv1_record_layer *rl,
- const u8 *in_data, size_t in_len,
- u8 *out_data, size_t *out_len, u8 *alert)
-{
- size_t i, rlen, hlen;
- u8 padlen;
- struct crypto_hash *hmac;
- u8 len[2], hash[100];
-
- wpa_hexdump(MSG_MSGDUMP, "TLSv1: Record Layer - Received",
- in_data, in_len);
-
- if (in_len < TLS_RECORD_HEADER_LEN) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short record (in_len=%lu)",
- (unsigned long) in_len);
- *alert = TLS_ALERT_DECODE_ERROR;
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "TLSv1: Received content type %d version %d.%d "
- "length %d", in_data[0], in_data[1], in_data[2],
- WPA_GET_BE16(in_data + 3));
-
- if (in_data[0] != TLS_CONTENT_TYPE_HANDSHAKE &&
- in_data[0] != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC &&
- in_data[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type 0x%x",
- in_data[0]);
- *alert = TLS_ALERT_UNEXPECTED_MESSAGE;
- return -1;
- }
-
- if (WPA_GET_BE16(in_data + 1) != TLS_VERSION) {
- wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version "
- "%d.%d", in_data[1], in_data[2]);
- *alert = TLS_ALERT_PROTOCOL_VERSION;
- return -1;
- }
-
- rlen = WPA_GET_BE16(in_data + 3);
-
- /* TLSCiphertext must not be more than 2^14+2048 bytes */
- if (TLS_RECORD_HEADER_LEN + rlen > 18432) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
- (unsigned long) (TLS_RECORD_HEADER_LEN + rlen));
- *alert = TLS_ALERT_RECORD_OVERFLOW;
- return -1;
- }
-
- in_data += TLS_RECORD_HEADER_LEN;
- in_len -= TLS_RECORD_HEADER_LEN;
-
- if (rlen > in_len) {
- wpa_printf(MSG_DEBUG, "TLSv1: Not all record data included "
- "(rlen=%lu > in_len=%lu)",
- (unsigned long) rlen, (unsigned long) in_len);
- *alert = TLS_ALERT_DECODE_ERROR;
- return -1;
- }
-
- in_len = rlen;
-
- if (*out_len < in_len) {
- wpa_printf(MSG_DEBUG, "TLSv1: Not enough output buffer for "
- "processing received record");
- *alert = TLS_ALERT_INTERNAL_ERROR;
- return -1;
- }
-
- os_memcpy(out_data, in_data, in_len);
- *out_len = in_len;
-
- if (rl->read_cipher_suite != TLS_NULL_WITH_NULL_NULL) {
- if (crypto_cipher_decrypt(rl->read_cbc, out_data,
- out_data, in_len) < 0) {
- *alert = TLS_ALERT_DECRYPTION_FAILED;
- return -1;
- }
- if (rl->iv_size) {
- if (in_len == 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short record"
- " (no pad)");
- *alert = TLS_ALERT_DECODE_ERROR;
- return -1;
- }
- padlen = out_data[in_len - 1];
- if (padlen >= in_len) {
- wpa_printf(MSG_DEBUG, "TLSv1: Incorrect pad "
- "length (%u, in_len=%lu) in "
- "received record",
- padlen, (unsigned long) in_len);
- *alert = TLS_ALERT_DECRYPTION_FAILED;
- return -1;
- }
- for (i = in_len - padlen; i < in_len; i++) {
- if (out_data[i] != padlen) {
- wpa_hexdump(MSG_DEBUG,
- "TLSv1: Invalid pad in "
- "received record",
- out_data + in_len - padlen,
- padlen);
- *alert = TLS_ALERT_DECRYPTION_FAILED;
- return -1;
- }
- }
-
- *out_len -= padlen + 1;
- }
-
- wpa_hexdump(MSG_MSGDUMP,
- "TLSv1: Record Layer - Decrypted data",
- out_data, in_len);
-
- if (*out_len < rl->hash_size) {
- wpa_printf(MSG_DEBUG, "TLSv1: Too short record; no "
- "hash value");
- *alert = TLS_ALERT_INTERNAL_ERROR;
- return -1;
- }
-
- *out_len -= rl->hash_size;
-
- hmac = crypto_hash_init(rl->hash_alg, rl->read_mac_secret,
- rl->hash_size);
- if (hmac == NULL) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
- "to initialize HMAC");
- *alert = TLS_ALERT_INTERNAL_ERROR;
- return -1;
- }
-
- crypto_hash_update(hmac, rl->read_seq_num, TLS_SEQ_NUM_LEN);
- /* type + version + length + fragment */
- crypto_hash_update(hmac, in_data - TLS_RECORD_HEADER_LEN, 3);
- WPA_PUT_BE16(len, *out_len);
- crypto_hash_update(hmac, len, 2);
- crypto_hash_update(hmac, out_data, *out_len);
- hlen = sizeof(hash);
- if (crypto_hash_finish(hmac, hash, &hlen) < 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record Layer - Failed "
- "to calculate HMAC");
- return -1;
- }
- if (hlen != rl->hash_size ||
- os_memcmp(hash, out_data + *out_len, hlen) != 0) {
- wpa_printf(MSG_DEBUG, "TLSv1: Invalid HMAC value in "
- "received message");
- *alert = TLS_ALERT_BAD_RECORD_MAC;
- return -1;
- }
- }
-
- /* TLSCompressed must not be more than 2^14+1024 bytes */
- if (TLS_RECORD_HEADER_LEN + *out_len > 17408) {
- wpa_printf(MSG_DEBUG, "TLSv1: Record overflow (len=%lu)",
- (unsigned long) (TLS_RECORD_HEADER_LEN + *out_len));
- *alert = TLS_ALERT_RECORD_OVERFLOW;
- return -1;
- }
-
- inc_byte_array(rl->read_seq_num, TLS_SEQ_NUM_LEN);
-
- return 0;
-}
+void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
+ size_t len)
+{
+ if (verify->md5_client && verify->sha1_client) {
+ crypto_hash_update(verify->md5_client, buf, len);
+ crypto_hash_update(verify->sha1_client, buf, len);
+ }
+ if (verify->md5_server && verify->sha1_server) {
+ crypto_hash_update(verify->md5_server, buf, len);
+ crypto_hash_update(verify->sha1_server, buf, len);
+ }
+ if (verify->md5_cert && verify->sha1_cert) {
+ crypto_hash_update(verify->md5_cert, buf, len);
+ crypto_hash_update(verify->sha1_cert, buf, len);
+ }
+}
+
+
+void tls_verify_hash_free(struct tls_verify_hash *verify)
+{
+ crypto_hash_finish(verify->md5_client, NULL, NULL);
+ crypto_hash_finish(verify->md5_server, NULL, NULL);
+ crypto_hash_finish(verify->md5_cert, NULL, NULL);
+ crypto_hash_finish(verify->sha1_client, NULL, NULL);
+ crypto_hash_finish(verify->sha1_server, NULL, NULL);
+ crypto_hash_finish(verify->sha1_cert, NULL, NULL);
+ verify->md5_client = NULL;
+ verify->md5_server = NULL;
+ verify->md5_cert = NULL;
+ verify->sha1_client = NULL;
+ verify->sha1_server = NULL;
+ verify->sha1_cert = NULL;
+}
Modified: wpasupplicant/trunk/src/tls/tlsv1_common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/tlsv1_common.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/tlsv1_common.h (original)
+++ wpasupplicant/trunk/src/tls/tlsv1_common.h Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
- * wpa_supplicant/hostapd: TLSv1 common definitions
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * TLSv1 common definitions
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -12,8 +12,10 @@
* See README and COPYING for more details.
*/
-#ifndef TLSV1_COMMON
-#define TLSV1_COMMON
+#ifndef TLSV1_COMMON_H
+#define TLSV1_COMMON_H
+
+#include "crypto.h"
#define TLS_VERSION 0x0301 /* TLSv1 */
#define TLS_RANDOM_LEN 32
@@ -21,34 +23,22 @@
#define TLS_MASTER_SECRET_LEN 48
#define TLS_SESSION_ID_MAX_LEN 32
#define TLS_VERIFY_DATA_LEN 12
-#define TLS_MAX_WRITE_MAC_SECRET_LEN 20
-#define TLS_MAX_WRITE_KEY_LEN 32
-#define TLS_MAX_IV_LEN 16
-#define TLS_MAX_KEY_BLOCK_LEN (2 * (TLS_MAX_WRITE_MAC_SECRET_LEN + \
- TLS_MAX_WRITE_KEY_LEN + TLS_MAX_IV_LEN))
-#define TLS_SEQ_NUM_LEN 8
-#define TLS_RECORD_HEADER_LEN 5
-
-/* ContentType */
-enum {
- TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
- TLS_CONTENT_TYPE_ALERT = 21,
- TLS_CONTENT_TYPE_HANDSHAKE = 22,
- TLS_CONTENT_TYPE_APPLICATION_DATA = 23
-};
/* HandshakeType */
enum {
TLS_HANDSHAKE_TYPE_HELLO_REQUEST = 0,
TLS_HANDSHAKE_TYPE_CLIENT_HELLO = 1,
TLS_HANDSHAKE_TYPE_SERVER_HELLO = 2,
+ TLS_HANDSHAKE_TYPE_NEW_SESSION_TICKET = 4 /* RFC 4507 */,
TLS_HANDSHAKE_TYPE_CERTIFICATE = 11,
TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE = 12,
TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST = 13,
TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE = 14,
TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY = 15,
TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE = 16,
- TLS_HANDSHAKE_TYPE_FINISHED = 20
+ TLS_HANDSHAKE_TYPE_FINISHED = 20,
+ TLS_HANDSHAKE_TYPE_CERTIFICATE_URL = 21 /* RFC 4366 */,
+ TLS_HANDSHAKE_TYPE_CERTIFICATE_STATUS = 22 /* RFC 4366 */
};
/* CipherSuite */
@@ -124,6 +114,11 @@
#define TLS_ALERT_INTERNAL_ERROR 80
#define TLS_ALERT_USER_CANCELED 90
#define TLS_ALERT_NO_RENEGOTIATION 100
+#define TLS_ALERT_UNSUPPORTED_EXTENSION 110 /* RFC 4366 */
+#define TLS_ALERT_CERTIFICATE_UNOBTAINABLE 111 /* RFC 4366 */
+#define TLS_ALERT_UNRECOGNIZED_NAME 112 /* RFC 4366 */
+#define TLS_ALERT_BAD_CERTIFICATE_STATUS_RESPONSE 113 /* RFC 4366 */
+#define TLS_ALERT_BAD_CERTIFICATE_HASH_VALUE 114 /* RFC 4366 */
/* ChangeCipherSpec */
enum {
@@ -131,7 +126,15 @@
};
/* TLS Extensions */
-#define TLS_EXT_PAC_OPAQUE 35
+#define TLS_EXT_SERVER_NAME 0 /* RFC 4366 */
+#define TLS_EXT_MAX_FRAGMENT_LENGTH 1 /* RFC 4366 */
+#define TLS_EXT_CLIENT_CERTIFICATE_URL 2 /* RFC 4366 */
+#define TLS_EXT_TRUSTED_CA_KEYS 3 /* RFC 4366 */
+#define TLS_EXT_TRUNCATED_HMAC 4 /* RFC 4366 */
+#define TLS_EXT_STATUS_REQUEST 5 /* RFC 4366 */
+#define TLS_EXT_SESSION_TICKET 35 /* RFC 4507 */
+
+#define TLS_EXT_PAC_OPAQUE TLS_EXT_SESSION_TICKET /* EAP-FAST terminology */
typedef enum {
@@ -191,43 +194,23 @@
};
-struct tlsv1_record_layer {
- u8 write_mac_secret[TLS_MAX_WRITE_MAC_SECRET_LEN];
- u8 read_mac_secret[TLS_MAX_WRITE_MAC_SECRET_LEN];
- u8 write_key[TLS_MAX_WRITE_KEY_LEN];
- u8 read_key[TLS_MAX_WRITE_KEY_LEN];
- u8 write_iv[TLS_MAX_IV_LEN];
- u8 read_iv[TLS_MAX_IV_LEN];
-
- size_t hash_size;
- size_t key_material_len;
- size_t iv_size; /* also block_size */
-
- enum crypto_hash_alg hash_alg;
- enum crypto_cipher_alg cipher_alg;
-
- u8 write_seq_num[TLS_SEQ_NUM_LEN];
- u8 read_seq_num[TLS_SEQ_NUM_LEN];
-
- u16 cipher_suite;
- u16 write_cipher_suite;
- u16 read_cipher_suite;
-
- struct crypto_cipher *write_cbc;
- struct crypto_cipher *read_cbc;
+struct tls_verify_hash {
+ struct crypto_hash *md5_client;
+ struct crypto_hash *sha1_client;
+ struct crypto_hash *md5_server;
+ struct crypto_hash *sha1_server;
+ struct crypto_hash *md5_cert;
+ struct crypto_hash *sha1_cert;
};
const struct tls_cipher_suite * tls_get_cipher_suite(u16 suite);
+const struct tls_cipher_data * tls_get_cipher_data(tls_cipher cipher);
+int tls_server_key_exchange_allowed(tls_cipher cipher);
int tls_parse_cert(const u8 *buf, size_t len, struct crypto_public_key **pk);
-int tlsv1_record_set_cipher_suite(struct tlsv1_record_layer *rl,
- u16 cipher_suite);
-int tlsv1_record_change_write_cipher(struct tlsv1_record_layer *rl);
-int tlsv1_record_change_read_cipher(struct tlsv1_record_layer *rl);
-int tlsv1_record_send(struct tlsv1_record_layer *rl, u8 content_type, u8 *buf,
- size_t buf_size, size_t payload_len, size_t *out_len);
-int tlsv1_record_receive(struct tlsv1_record_layer *rl,
- const u8 *in_data, size_t in_len,
- u8 *out_data, size_t *out_len, u8 *alert);
+int tls_verify_hash_init(struct tls_verify_hash *verify);
+void tls_verify_hash_add(struct tls_verify_hash *verify, const u8 *buf,
+ size_t len);
+void tls_verify_hash_free(struct tls_verify_hash *verify);
#endif /* TLSV1_COMMON_H */
Modified: wpasupplicant/trunk/src/tls/x509v3.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/tls/x509v3.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/tls/x509v3.c (original)
+++ wpasupplicant/trunk/src/tls/x509v3.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* X.509v3 certificate parsing and processing (RFC 3280 profile)
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -75,8 +75,39 @@
}
+static int x509_whitespace(char c)
+{
+ return c == ' ' || c == '\t';
+}
+
+
+static void x509_str_strip_whitespace(char *a)
+{
+ char *ipos, *opos;
+ int remove_whitespace = 1;
+
+ ipos = opos = a;
+
+ while (*ipos) {
+ if (remove_whitespace && x509_whitespace(*ipos))
+ ipos++;
+ else {
+ remove_whitespace = x509_whitespace(*ipos);
+ *opos++ = *ipos++;
+ }
+ }
+
+ *opos-- = '\0';
+ if (opos > a && x509_whitespace(*opos))
+ *opos = '\0';
+}
+
+
static int x509_str_compare(const char *a, const char *b)
{
+ char *aa, *bb;
+ int ret;
+
if (!a && b)
return -1;
if (a && !b)
@@ -84,14 +115,31 @@
if (!a && !b)
return 0;
- return os_strcmp(a, b);
+ aa = os_strdup(a);
+ bb = os_strdup(b);
+
+ if (aa == NULL || bb == NULL) {
+ os_free(aa);
+ os_free(bb);
+ return os_strcasecmp(a, b);
+ }
+
+ x509_str_strip_whitespace(aa);
+ x509_str_strip_whitespace(bb);
+
+ ret = os_strcasecmp(aa, bb);
+
+ os_free(aa);
+ os_free(bb);
+
+ return ret;
}
/**
* x509_name_compare - Compare X.509 certificate names
* @a: Certificate name
- * @b: Certifiatte name
+ * @b: Certificate name
* Returns: <0, 0, or >0 based on whether a is less than, equal to, or
* greater than b
*/
@@ -553,6 +601,17 @@
if (os_mktime(year, month, day, hour, min, sec, val) < 0) {
wpa_hexdump_ascii(MSG_DEBUG, "X509: Failed to convert Time",
buf, len);
+ if (year < 1970) {
+ /*
+ * At least some test certificates have been configured
+ * to use dates prior to 1970. Set the date to
+ * beginning of 1970 to handle these case.
+ */
+ wpa_printf(MSG_DEBUG, "X509: Year=%d before epoch - "
+ "assume epoch as the time", year);
+ *val = 0;
+ return 0;
+ }
return -1;
}
@@ -720,7 +779,8 @@
return 0;
}
- if (asn1_get_next(pos, len, &hdr) < 0 ||
+ if (asn1_get_next(hdr.payload + hdr.length, len - hdr.length,
+ &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL) {
wpa_printf(MSG_DEBUG, "X509: Failed to parse "
"BasicConstraints");
@@ -1443,6 +1503,13 @@
return -1;
}
+ if (cert->version == X509_CERT_V3 &&
+ !(cert->extensions_present & X509_EXT_BASIC_CONSTRAINTS)) {
+ wpa_printf(MSG_DEBUG, "X509: v3 CA certificate did not "
+ "include BasicConstraints extension");
+ return -1;
+ }
+
if ((cert->extensions_present & X509_EXT_KEY_USAGE) &&
!(cert->key_usage & X509_KEY_USAGE_KEY_CERT_SIGN)) {
wpa_printf(MSG_DEBUG, "X509: Issuer certificate did not have "
@@ -1466,7 +1533,8 @@
struct x509_certificate *chain,
int *reason)
{
- int idx, chain_trusted = 0;
+ long unsigned idx;
+ int chain_trusted = 0;
struct x509_certificate *cert, *trust;
char buf[128];
struct os_time now;
@@ -1478,12 +1546,15 @@
for (cert = chain, idx = 0; cert; cert = cert->next, idx++) {
x509_name_string(&cert->subject, buf, sizeof(buf));
- wpa_printf(MSG_DEBUG, "X509: %d: %s", idx, buf);
+ wpa_printf(MSG_DEBUG, "X509: %lu: %s", idx, buf);
if (chain_trusted)
continue;
- if (now.sec < cert->not_before || now.sec > cert->not_after) {
+ if ((unsigned long) now.sec <
+ (unsigned long) cert->not_before ||
+ (unsigned long) now.sec >
+ (unsigned long) cert->not_after) {
wpa_printf(MSG_INFO, "X509: Certificate not valid "
"(now=%lu not_before=%lu not_after=%lu)",
now.sec, cert->not_before, cert->not_after);
@@ -1505,7 +1576,16 @@
return -1;
}
- /* TODO: validate pathLenConstraint */
+ if ((cert->next->extensions_present &
+ X509_EXT_PATH_LEN_CONSTRAINT) &&
+ idx > cert->next->path_len_constraint) {
+ wpa_printf(MSG_DEBUG, "X509: pathLenConstraint"
+ " not met (idx=%lu issuer "
+ "pathLenConstraint=%lu)", idx,
+ cert->next->path_len_constraint);
+ *reason = X509_VALIDATE_BAD_CERTIFICATE;
+ return -1;
+ }
if (x509_certificate_check_signature(cert->next, cert)
< 0) {
Modified: wpasupplicant/trunk/src/utils/common.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/common.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/common.h (original)
+++ wpasupplicant/trunk/src/utils/common.h Sat Nov 3 11:46:49 2007
@@ -33,6 +33,24 @@
#define bswap_64 bswap64
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
* defined(__DragonFly__) */
+
+#ifdef __APPLE__
+#include <sys/types.h>
+#include <machine/endian.h>
+#define __BYTE_ORDER _BYTE_ORDER
+#define __LITTLE_ENDIAN _LITTLE_ENDIAN
+#define __BIG_ENDIAN _BIG_ENDIAN
+static inline unsigned short bswap_16(unsigned short v)
+{
+ return ((v & 0xff) << 8) | (v >> 8);
+}
+
+static inline unsigned int bswap_32(unsigned int v)
+{
+ return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
+ ((v & 0xff0000) >> 8) | (v >> 24);
+}
+#endif /* __APPLE__ */
#ifdef CONFIG_TI_COMPILER
#define __BIG_ENDIAN 4321
Modified: wpasupplicant/trunk/src/utils/os_unix.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/src/utils/os_unix.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/src/utils/os_unix.c (original)
+++ wpasupplicant/trunk/src/utils/os_unix.c Sat Nov 3 11:46:49 2007
@@ -175,7 +175,7 @@
int os_unsetenv(const char *name)
{
-#if defined(__FreeBSD__) || defined(__NetBSD__)
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__)
unsetenv(name);
return 0;
#else
Modified: wpasupplicant/trunk/wpa_supplicant/ChangeLog
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ChangeLog?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ChangeLog (original)
+++ wpasupplicant/trunk/wpa_supplicant/ChangeLog Sat Nov 3 11:46:49 2007
@@ -1,4 +1,26 @@
ChangeLog for wpa_supplicant
+
+????-??-?? - v0.6.1
+ * added support for configuring password as NtPasswordHash
+ (16-byte MD4 hash of password) in hash:<32 hex digits> format
+ * added support for fallback from abbreviated TLS handshake to
+ full handshake when using EAP-FAST (e.g., due to an expired
+ PAC-Opaque)
+ * updated EAP Generalized Pre-Shared Key (EAP-GPSK) to use the latest
+ draft (draft-ietf-emu-eap-gpsk-06.txt)
+ * added support for drivers that take care of RSN 4-way handshake
+ internally (WPA_DRIVER_FLAGS_4WAY_HANDSHAKE in get_capa flags and
+ WPA_ALG_PMK in set_key)
+ * added an experimental port for Mac OS X (CONFIG_DRIVER_OSX=y in
+ .config); this version supports only ap_scan=2 mode and allow the
+ driver to take care of the 4-way handshake
+ * fixed a buffer overflow in parsing TSF from scan results when using
+ driver_wext.c with a driver that includes the TSF (e.g., iwl4965)
+ [Bug 232]
+ * updated FT support to use the latest draft, IEEE 802.11r/D8.0
+ * fixed an integer overflow issue in the ASN.1 parser used by the
+ (experimental) internal TLS implementation to avoid a potential
+ buffer read overflow
2007-05-28 - v0.6.0
* added network configuration parameter 'frequency' for setting
Modified: wpasupplicant/trunk/wpa_supplicant/Makefile
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/Makefile?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/Makefile (original)
+++ wpasupplicant/trunk/wpa_supplicant/Makefile Sat Nov 3 11:46:49 2007
@@ -189,6 +189,20 @@
OBJS_d += ../src/drivers/driver_test.o
endif
+ifdef CONFIG_DRIVER_OSX
+CFLAGS += -DCONFIG_DRIVER_OSX
+OBJS_d += ../src/drivers/driver_osx.o
+LDFLAGS += -framework CoreFoundation
+LDFLAGS += -F/System/Library/PrivateFrameworks -framework Apple80211
+endif
+
+ifdef CONFIG_DRIVER_IPHONE
+CFLAGS += -DCONFIG_DRIVER_IPHONE
+OBJS_d += ../src/drivers/driver_iphone.o
+OBJS_d += ../src/drivers/MobileApple80211.o
+LIBS += -framework CoreFoundation
+endif
+
ifndef CONFIG_L2_PACKET
CONFIG_L2_PACKET=linux
endif
@@ -393,6 +407,7 @@
else
CFLAGS += -DEAP_FAST
OBJS += ../src/eap_peer/eap_fast.o ../src/eap_peer/eap_fast_pac.o
+OBJS_h += ../src/eap_server/eap_fast.o
endif
TLS_FUNCS=y
endif
@@ -555,12 +570,15 @@
endif
ifeq ($(CONFIG_TLS), internal)
OBJS += ../src/crypto/tls_internal.o
-OBJS += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_client.o
+OBJS += ../src/tls/tlsv1_common.o ../src/tls/tlsv1_record.o
+OBJS += ../src/tls/tlsv1_cred.o ../src/tls/tlsv1_client.o
+OBJS += ../src/tls/tlsv1_client_write.o ../src/tls/tlsv1_client_read.o
OBJS += ../src/tls/asn1.o ../src/tls/x509v3.o
OBJS_p += ../src/tls/asn1.o
OBJS_p += ../src/crypto/rc4.o ../src/crypto/aes_wrap.o ../src/crypto/aes.o
NEED_BASE64=y
CFLAGS += -DCONFIG_TLS_INTERNAL
+CFLAGS += -DCONFIG_TLS_INTERNAL_CLIENT
ifeq ($(CONFIG_CRYPTO), internal)
ifdef CONFIG_INTERNAL_LIBTOMMATH
CFLAGS += -DCONFIG_INTERNAL_LIBTOMMATH
Modified: wpasupplicant/trunk/wpa_supplicant/config.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/config.c Sat Nov 3 11:46:49 2007
@@ -949,6 +949,86 @@
return buf;
}
+
+
+static int wpa_config_parse_password(const struct parse_data *data,
+ struct wpa_ssid *ssid, int line,
+ const char *value)
+{
+ u8 *hash;
+
+ if (os_strncmp(value, "hash:", 5) != 0) {
+ char *tmp;
+ size_t res_len;
+
+ tmp = wpa_config_parse_string(value, &res_len);
+ if (tmp == NULL) {
+ wpa_printf(MSG_ERROR, "Line %d: failed to parse "
+ "password.", line);
+ return -1;
+ }
+ wpa_hexdump_ascii(MSG_MSGDUMP, data->name,
+ (u8 *) tmp, res_len);
+
+ os_free(ssid->password);
+ ssid->password = (u8 *) tmp;
+ ssid->password_len = res_len;
+ ssid->flags &= ~WPA_CONFIG_FLAGS_PASSWORD_NTHASH;
+
+ return 0;
+ }
+
+
+ /* NtPasswordHash: hash:<32 hex digits> */
+ if (os_strlen(value + 5) != 2 * 16) {
+ wpa_printf(MSG_ERROR, "Line %d: Invalid password hash length "
+ "(expected 32 hex digits)", line);
+ return -1;
+ }
+
+ hash = os_malloc(16);
+ if (hash == NULL)
+ return -1;
+
+ if (hexstr2bin(value + 5, hash, 16)) {
+ os_free(hash);
+ wpa_printf(MSG_ERROR, "Line %d: Invalid password hash", line);
+ return -1;
+ }
+
+ wpa_hexdump_key(MSG_MSGDUMP, data->name, hash, 16);
+
+ os_free(ssid->password);
+ ssid->password = hash;
+ ssid->password_len = 16;
+ ssid->flags |= WPA_CONFIG_FLAGS_PASSWORD_NTHASH;
+
+ return 0;
+}
+
+
+static char * wpa_config_write_password(const struct parse_data *data,
+ struct wpa_ssid *ssid)
+{
+ char *buf;
+
+ if (ssid->password == NULL)
+ return NULL;
+
+ if (!(ssid->flags & WPA_CONFIG_FLAGS_PASSWORD_NTHASH)) {
+ return wpa_config_write_string(
+ ssid->password, ssid->password_len);
+ }
+
+ buf = os_malloc(5 + 32 + 1);
+ if (buf == NULL)
+ return NULL;
+
+ os_memcpy(buf, "hash:", 5);
+ wpa_snprintf_hex(buf + 5, 32 + 1, ssid->password, 16);
+
+ return buf;
+}
#endif /* IEEE8021X_EAPOL */
@@ -1137,7 +1217,7 @@
{ STR_LEN(anonymous_identity) },
{ STR_RANGE_KEY(eappsk, EAP_PSK_LEN_MIN, EAP_PSK_LEN_MAX) },
{ STR_LEN(nai) },
- { STR_LEN_KEY(password) },
+ { FUNC(password) },
{ STR(ca_cert) },
{ STR(ca_path) },
{ STR(client_cert) },
Modified: wpasupplicant/trunk/wpa_supplicant/config_ssid.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/config_ssid.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/config_ssid.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/config_ssid.h Sat Nov 3 11:46:49 2007
@@ -226,6 +226,14 @@
/**
* password - Password string for EAP
+ *
+ * This field can include either the plaintext password (default
+ * option) or a NtPasswordHash (16-byte MD4 hash of the unicode
+ * presentation of the password) if flags field has
+ * WPA_CONFIG_FLAGS_PASSWORD_NTHASH bit set to 1. NtPasswordHash can
+ * only be used with authentication mechanism that use this hash as the
+ * starting point for operation: MSCHAP and MSCHAPv2 (EAP-MSCHAPv2,
+ * EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP).
*/
u8 *password;
@@ -849,6 +857,17 @@
* will be used instead of this configured value.
*/
int frequency;
+
+#define WPA_CONFIG_FLAGS_PASSWORD_NTHASH BIT(0)
+ /**
+ * flags - Network configuration flags (bitfield)
+ *
+ * This variable is used for internal flags to describe further details
+ * for the network parameters.
+ * bit 0 = password is represented as a 16-byte NtPasswordHash value
+ * instead of plaintext password
+ */
+ u32 flags;
};
int wpa_config_allowed_eap_method(struct wpa_ssid *ssid, int vendor,
Modified: wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/ctrl_iface.c Sat Nov 3 11:46:49 2007
@@ -1225,6 +1225,12 @@
wpa_s->disconnected = 0;
wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 0, 0);
+ } else if (os_strcmp(buf, "RECONNECT") == 0) {
+ if (wpa_s->disconnected) {
+ wpa_s->disconnected = 0;
+ wpa_s->reassociate = 1;
+ wpa_supplicant_req_scan(wpa_s, 0, 0);
+ }
} else if (os_strncmp(buf, "PREAUTH ", 8) == 0) {
if (wpa_supplicant_ctrl_iface_preauth(wpa_s, buf + 8))
reply_len = -1;
@@ -1257,6 +1263,7 @@
reply_len = wpa_supplicant_ctrl_iface_list_networks(
wpa_s, reply, reply_size);
} else if (os_strcmp(buf, "DISCONNECT") == 0) {
+ wpa_s->reassociate = 0;
wpa_s->disconnected = 1;
wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
} else if (os_strcmp(buf, "SCAN") == 0) {
Modified: wpasupplicant/trunk/wpa_supplicant/doc/ctrl_iface.doxygen
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/ctrl_iface.doxygen?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/ctrl_iface.doxygen (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/ctrl_iface.doxygen Sat Nov 3 11:46:49 2007
@@ -203,6 +203,12 @@
Force reassociation.
+\subsection ctrl_iface_RECONNECT RECONNECT
+
+Connect if disconnected (i.e., like \c REASSOCIATE, but only connect
+if in disconnected state).
+
+
\subsection ctrl_iface_PREAUTH PREAUTH <BSSID>
Start pre-authentication with the given BSSID.
@@ -255,7 +261,8 @@
\subsection ctrl_iface_DISCONNECT DISCONNECT
-Disconnect and wait for \c REASSOCIATE command before connecting.
+Disconnect and wait for \c REASSOCIATE or \c RECONNECT command before
+connecting.
\subsection ctrl_iface_SCAN SCAN
Modified: wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.sgml
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.sgml?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.sgml (original)
+++ wpasupplicant/trunk/wpa_supplicant/doc/docbook/wpa_cli.sgml Sat Nov 3 11:46:49 2007
@@ -140,7 +140,7 @@
<listitem><para>Run in daemon mode executing the action file
based on events from wpa_supplicant. The specified file will
be executed with the first argument set to interface name and
- second to "CONNECT" or "DISCONNECT" depending on the event.
+ second to "CONNECTED" or "DISCONNECTED" depending on the event.
This can be used to execute networking tools required to configure
the interface.</para>
Modified: wpasupplicant/trunk/wpa_supplicant/eap_testing.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/eap_testing.txt?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/eap_testing.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/eap_testing.txt Sat Nov 3 11:46:49 2007
@@ -79,12 +79,12 @@
EAP-PAX - - - - - + - - - - + -
EAP-SAKE - - - - - - - - - - + -
EAP-GPSK - - - - - - - - - - + -
-EAP-FAST/MSCHAPv2(prov) - - - + - - - - - + - +
-EAP-FAST/GTC(auth) - - - + - - - - - + - +
-EAP-FAST/MSCHAPv2(aprov)- - - - - - - - - - - +
-EAP-FAST/GTC(aprov) - - - - - - - - - - - +
+EAP-FAST/MSCHAPv2(prov) - - - + - - - - - + + +
+EAP-FAST/GTC(auth) - - - + - - - - - + + +
+EAP-FAST/MSCHAPv2(aprov)- - - - - - - - - - + +
+EAP-FAST/GTC(aprov) - - - - - - - - - - + +
EAP-FAST/TLS(aprov) - - - - - - - - - - - +
-EAP-FAST/MSCHAPv2(auth) - - - - - - - - - - - +
+EAP-FAST/MSCHAPv2(auth) - - - - - - - - - - + +
EAP-FAST/TLS(auth) - - - - - - - - - - - +
LEAP + - + + + + F +6 - + - +
EAP-TNC - - - - - + - - - - - -
Modified: wpasupplicant/trunk/wpa_supplicant/eapol_test.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/eapol_test.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/eapol_test.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/eapol_test.c Sat Nov 3 11:46:49 2007
@@ -199,7 +199,8 @@
size_t len)
{
/* struct wpa_supplicant *wpa_s = ctx; */
- printf("WPA: eapol_test_eapol_send(type=%d len=%d)\n", type, len);
+ printf("WPA: eapol_test_eapol_send(type=%d len=%lu)\n",
+ type, (unsigned long) len);
if (type == IEEE802_1X_TYPE_EAP_PACKET) {
wpa_hexdump(MSG_DEBUG, "TX EAP -> RADIUS", buf, len);
ieee802_1x_encapsulate_radius(&eapol_test, buf, len);
Modified: wpasupplicant/trunk/wpa_supplicant/events.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/events.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/events.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/events.c Sat Nov 3 11:46:49 2007
@@ -444,9 +444,10 @@
wpa_printf(MSG_DEBUG, " skip - disabled");
continue;
}
- if (bss->ssid_len != ssid->ssid_len ||
- os_memcmp(bss->ssid, ssid->ssid,
- bss->ssid_len) != 0) {
+ if (ssid->ssid_len != 0 &&
+ (bss->ssid_len != ssid->ssid_len ||
+ os_memcmp(bss->ssid, ssid->ssid,
+ bss->ssid_len) != 0)) {
wpa_printf(MSG_DEBUG, " skip - "
"SSID mismatch");
continue;
@@ -520,7 +521,7 @@
wpa_supplicant_dbus_notify_scan_results(wpa_s);
- if (wpa_s->conf->ap_scan == 2)
+ if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
return;
results = wpa_s->scan_results;
num = wpa_s->num_scan_results;
@@ -733,6 +734,19 @@
wpa_supplicant_req_auth_timeout(wpa_s, 10, 0);
}
wpa_supplicant_cancel_scan(wpa_s);
+
+ if (wpa_s->driver_4way_handshake &&
+ (wpa_s->key_mgmt == WPA_KEY_MGMT_PSK ||
+ wpa_s->key_mgmt == WPA_KEY_MGMT_FT_PSK)) {
+ /*
+ * We are done; the driver will take care of RSN 4-way
+ * handshake.
+ */
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+ eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
+ eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
+ }
}
Modified: wpasupplicant/trunk/wpa_supplicant/mlme.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/mlme.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/mlme.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/mlme.c Sat Nov 3 11:46:49 2007
@@ -460,8 +460,7 @@
mdie = (struct rsn_mdie *) (bss->mdie + 2);
if (mdie &&
os_memcmp(mdie->mobility_domain, wpa_s->mlme.current_md,
- MOBILITY_DOMAIN_ID_LEN) == 0 &&
- (mdie->ft_capab & RSN_FT_CAPAB_FT_OVER_AIR)) {
+ MOBILITY_DOMAIN_ID_LEN) == 0) {
wpa_printf(MSG_DEBUG, "MLME: Trying to use FT "
"over-the-air");
wpa_s->mlme.auth_alg = WLAN_AUTH_FT;
@@ -586,15 +585,14 @@
wpa_s->mlme.auth_alg != WLAN_AUTH_FT &&
bss && bss->mdie &&
bss->mdie_len >= 2 + sizeof(struct rsn_mdie) &&
- bss->mdie[1] >= sizeof(struct rsn_mdie) &&
- bss->mdie[2 + MOBILITY_DOMAIN_ID_LEN] & RSN_FT_CAPAB_FT_OVER_AIR) {
+ bss->mdie[1] >= sizeof(struct rsn_mdie)) {
pos = buf + blen;
blen += 2 + sizeof(struct rsn_mdie);
*pos++ = WLAN_EID_MOBILITY_DOMAIN;
*pos++ = sizeof(struct rsn_mdie);
os_memcpy(pos, bss->mdie + 2, MOBILITY_DOMAIN_ID_LEN);
pos += MOBILITY_DOMAIN_ID_LEN;
- *pos++ = RSN_FT_CAPAB_FT_OVER_AIR;
+ *pos++ = 0; /* FIX: copy from the target AP's MDIE */
}
if ((wpa_s->mlme.key_mgmt == KEY_MGMT_FT_802_1X ||
Modified: wpasupplicant/trunk/wpa_supplicant/tests/test_aes.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/tests/test_aes.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/tests/test_aes.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/tests/test_aes.c Sat Nov 3 11:46:49 2007
@@ -277,6 +277,23 @@
printf("OMAC1-AES-128 test vector %d failed\n", i);
ret++;
}
+
+ if (tv->msg_len > 1) {
+ const u8 *addr[2];
+ size_t len[2];
+
+ addr[0] = tv->msg;
+ len[0] = 1;
+ addr[1] = tv->msg + 1;
+ len[1] = tv->msg_len - 1;
+
+ omac1_aes_128_vector(tv->k, 2, addr, len, result);
+ if (memcmp(result, tv->tag, 16) != 0) {
+ printf("OMAC1-AES-128(vector) test vector %d "
+ "failed\n", i);
+ ret++;
+ }
+ }
}
ret += test_eax();
Modified: wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/tests/test_x509v3.c Sat Nov 3 11:46:49 2007
@@ -1,6 +1,6 @@
/*
* Testing tool for X.509v3 routines
- * Copyright (c) 2006, Jouni Malinen <j at w1.fi>
+ * Copyright (c) 2006-2007, Jouni Malinen <j at w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,8 +15,8 @@
#include "includes.h"
#include "common.h"
-#include "asn1.h"
-#include "x509v3.h"
+#include "tls/asn1.h"
+#include "tls/x509v3.h"
extern int wpa_debug_level;
@@ -43,7 +43,7 @@
return -1;
}
- cert = x509_certificate_parse(buf, len);
+ cert = x509_certificate_parse((u8 *) buf, len);
if (cert == NULL) {
printf("Failed to parse X.509 certificate\n");
return -1;
Modified: wpasupplicant/trunk/wpa_supplicant/todo.txt
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/todo.txt?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/todo.txt (original)
+++ wpasupplicant/trunk/wpa_supplicant/todo.txt Sat Nov 3 11:46:49 2007
@@ -50,8 +50,6 @@
- possibility to link in WPA Authenticator state machine to wpa_supplicant
(new STAKey handshake, WPA2 IBSS)
- consider merging hostapd and wpa_supplicant PMKSA cache implementations
-- add support for configuring password for MSCHAPv2 as NtPasswordHash in
- the same way as was added to hostapd (hash:<hex value>)
- consider adding generic buffer functionality that could be used in number
of places
* allocate buffer (with default max size), allow reserving head room to
@@ -110,15 +108,16 @@
- change TLS/crypto library interface to use a structure of function
pointers and helper inline functions (like driver_ops) instead of
requiring every TLS wrapper to implement all functions
-- move from CVS to git (0.3.x, 0.4.x, 0.5.x releases will continue
- to be updated only on CVS)
-- move files into subdirectories and combine wpa_supplicant and hostapd
- into a repository that matches in directory structure with the release
- tarballs
- (subdirs: eap_common, eap_peer, eap_server, driver, driver_ap, ...)
- make it clearer that EAP server/peer can be used as a separate library
for other programs
- add support for encrypted configuration fields (e.g., password, psk,
passphrase, pin)
- wpa_gui: add support for setting and showing priority, id_str, auth_alg
(open/shared for static WEP)
+
+- cleanup TLS/PEAP/TTLS/FAST fragmentation: both the handshake and Appl. Data
+ phases should be able to use the same functions for this;
+ the last step in processing sent should be this code and rest of the code
+ should not need to care about fragmentation at all
+- test EAP-FAST peer with OpenSSL and verify that fallback to full handshake
+ (ServerHello followed by something else than ChangeCipherSpec)
Modified: wpasupplicant/trunk/wpa_supplicant/wpa_cli.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_cli.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_cli.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_cli.c Sat Nov 3 11:46:49 2007
@@ -120,8 +120,10 @@
" list of variables when run without arguments)\n"
" get_network <network id> <variable> = get network variables\n"
" save_config = save the current configuration\n"
-" disconnect = disconnect and wait for reassociate command before "
-"connecting\n"
+" disconnect = disconnect and wait for reassociate/reconnect command before\n "
+" connecting\n"
+" reconnect = like reassociate, but only takes effect if already "
+"disconnected\n"
" scan = request new BSS scan\n"
" scan_results = get latest scan results\n"
" get_capability <eap/pairwise/group/key_mgmt/proto/auth_alg> = "
@@ -323,13 +325,13 @@
if (argc != 2) {
printf("Invalid SET command: needs two arguments (variable "
"name and value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "SET %s %s", argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -363,13 +365,13 @@
if (argc != 1) {
printf("Invalid PREAUTH command: needs one argument "
"(BSSID)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "PREAUTH %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long PREAUTH command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -383,12 +385,12 @@
if (argc != 1) {
printf("Invalid AP_SCAN command: needs one argument (ap_scan "
"value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long AP_SCAN command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -403,13 +405,13 @@
if (argc != 1) {
printf("Invalid STKSTART command: needs one argument "
"(Peer STA MAC address)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "STKSTART %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long STKSTART command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -423,13 +425,13 @@
if (argc != 1) {
printf("Invalid FT_DS command: needs one argument "
"(Target AP MAC address)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "FT_DS %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long FT_DS command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -443,12 +445,12 @@
if (argc != 1) {
printf("Invalid LEVEL command: needs one argument (debug "
"level)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long LEVEL command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -462,7 +464,7 @@
if (argc < 2) {
printf("Invalid IDENTITY command: needs two arguments "
"(network id and identity)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -471,14 +473,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long IDENTITY command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long IDENTITY command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -495,7 +497,7 @@
if (argc < 2) {
printf("Invalid PASSWORD command: needs two arguments "
"(network id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -504,14 +506,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -529,7 +531,7 @@
if (argc < 2) {
printf("Invalid NEW_PASSWORD command: needs two arguments "
"(network id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -538,14 +540,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long NEW_PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long NEW_PASSWORD command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -562,7 +564,7 @@
if (argc < 2) {
printf("Invalid PIN command: needs two arguments "
"(network id and pin)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -571,14 +573,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PIN command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PIN command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -594,7 +596,7 @@
if (argc < 2) {
printf("Invalid OTP command: needs two arguments (network "
"id and password)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -603,14 +605,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long OTP command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long OTP command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -628,7 +630,7 @@
if (argc < 2) {
printf("Invalid PASSPHRASE command: needs two arguments "
"(network id and passphrase)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -637,14 +639,14 @@
argv[0], argv[1]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSPHRASE command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 2; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long PASSPHRASE command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -661,7 +663,7 @@
if (argc < 2) {
printf("Invalid BSSID command: needs two arguments (network "
"id and BSSID)\n");
- return 0;
+ return -1;
}
end = cmd + sizeof(cmd);
@@ -669,14 +671,14 @@
ret = os_snprintf(pos, end - pos, "BSSID");
if (ret < 0 || ret >= end - pos) {
printf("Too long BSSID command.\n");
- return 0;
+ return -1;
}
pos += ret;
for (i = 0; i < argc; i++) {
ret = os_snprintf(pos, end - pos, " %s", argv[i]);
if (ret < 0 || ret >= end - pos) {
printf("Too long BSSID command.\n");
- return 0;
+ return -1;
}
pos += ret;
}
@@ -701,7 +703,7 @@
if (argc < 1) {
printf("Invalid SELECT_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
@@ -722,7 +724,7 @@
if (argc < 1) {
printf("Invalid ENABLE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
@@ -743,7 +745,7 @@
if (argc < 1) {
printf("Invalid DISABLE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
@@ -771,7 +773,7 @@
if (argc < 1) {
printf("Invalid REMOVE_NETWORK command: needs one argument "
"(network id)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
@@ -818,14 +820,14 @@
if (argc != 3) {
printf("Invalid SET_NETWORK command: needs three arguments\n"
"(network id, variable name, and value)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
argv[0], argv[1], argv[2]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long SET_NETWORK command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -845,14 +847,14 @@
if (argc != 2) {
printf("Invalid GET_NETWORK command: needs two arguments\n"
"(network id and variable name)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "GET_NETWORK %s %s",
argv[0], argv[1]);
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
printf("Too long GET_NETWORK command.\n");
- return 0;
+ return -1;
}
return wpa_ctrl_command(ctrl, cmd);
}
@@ -862,6 +864,13 @@
char *argv[])
{
return wpa_ctrl_command(ctrl, "DISCONNECT");
+}
+
+
+static int wpa_cli_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
+ char *argv[])
+{
+ return wpa_ctrl_command(ctrl, "RECONNECT");
}
@@ -894,13 +903,13 @@
if (argc < 1 || argc > 2) {
printf("Invalid GET_CAPABILITY command: need either one or "
"two arguments\n");
- return 0;
+ return -1;
}
if ((argc == 2) && os_strcmp(argv[1], "strict") != 0) {
printf("Invalid GET_CAPABILITY command: second argument, "
"if any, must be 'strict'\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "GET_CAPABILITY %s%s", argv[0],
@@ -972,7 +981,7 @@
"argument (interface name)\n"
"All arguments: ifname confname driver ctrl_interface "
"driver_param bridge_name\n");
- return 0;
+ return -1;
}
/*
@@ -1001,7 +1010,7 @@
if (argc != 1) {
printf("Invalid INTERFACE_REMOVE command: needs one argument "
"(interface name)\n");
- return 0;
+ return -1;
}
res = os_snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
@@ -1049,6 +1058,7 @@
{ "get_network", wpa_cli_cmd_get_network },
{ "save_config", wpa_cli_cmd_save_config },
{ "disconnect", wpa_cli_cmd_disconnect },
+ { "reconnect", wpa_cli_cmd_reconnect },
{ "scan", wpa_cli_cmd_scan },
{ "scan_results", wpa_cli_cmd_scan_results },
{ "get_capability", wpa_cli_cmd_get_capability },
@@ -1063,10 +1073,11 @@
};
-static void wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
+static int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
{
struct wpa_cli_cmd *cmd, *match = NULL;
int count;
+ int ret = 0;
count = 0;
cmd = wpa_cli_commands;
@@ -1095,11 +1106,15 @@
cmd++;
}
printf("\n");
+ ret = 1;
} else if (count == 0) {
printf("Unknown command '%s'\n", argv[0]);
+ ret = 1;
} else {
- match->handler(ctrl, argc - 1, &argv[1]);
- }
+ ret = match->handler(ctrl, argc - 1, &argv[1]);
+ }
+
+ return ret;
}
@@ -1554,6 +1569,7 @@
int warning_displayed = 0;
int c;
int daemonize = 0;
+ int ret = 0;
const char *global = NULL;
if (os_program_init())
@@ -1665,12 +1681,12 @@
else if (action_file)
wpa_cli_action(ctrl_conn);
else
- wpa_request(ctrl_conn, argc - optind, &argv[optind]);
+ ret = wpa_request(ctrl_conn, argc - optind, &argv[optind]);
os_free(ctrl_ifname);
wpa_cli_cleanup();
- return 0;
+ return ret;
}
#else /* CONFIG_CTRL_IFACE */
Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.c Sat Nov 3 11:46:49 2007
@@ -1512,6 +1512,11 @@
}
params.wep_tx_keyidx = ssid->wep_tx_keyidx;
+ if (wpa_s->driver_4way_handshake &&
+ (params.key_mgmt_suite == KEY_MGMT_PSK ||
+ params.key_mgmt_suite == KEY_MGMT_FT_PSK))
+ params.passphrase = ssid->passphrase;
+
#ifdef CONFIG_IEEE80211W
switch (ssid->ieee80211w) {
case NO_IEEE80211W:
@@ -1987,7 +1992,11 @@
return;
}
- if (wpa_s->eapol_received == 0) {
+ if (wpa_s->eapol_received == 0 &&
+ (!wpa_s->driver_4way_handshake ||
+ (wpa_s->key_mgmt != WPA_KEY_MGMT_PSK &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_FT_PSK) ||
+ wpa_s->wpa_state != WPA_COMPLETED)) {
/* Timeout for completing IEEE 802.1X and WPA authentication */
wpa_supplicant_req_auth_timeout(
wpa_s,
@@ -2016,7 +2025,18 @@
eapol_sm_rx_eapol(wpa_s->eapol, src_addr, buf, len) > 0)
return;
wpa_drv_poll(wpa_s);
- wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
+ if (!wpa_s->driver_4way_handshake)
+ wpa_sm_rx_eapol(wpa_s->wpa, src_addr, buf, len);
+ else if (wpa_s->key_mgmt == WPA_KEY_MGMT_IEEE8021X ||
+ wpa_s->key_mgmt == WPA_KEY_MGMT_FT_IEEE8021X) {
+ /*
+ * Set portValid = TRUE here since we are going to skip 4-way
+ * handshake processing which would normally set portValid. We
+ * need this to allow the EAPOL state machines to be completed
+ * without going through EAPOL-Key handshake.
+ */
+ eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
+ }
}
@@ -2220,6 +2240,57 @@
}
+#ifdef IEEE8021X_EAPOL
+static void wpa_supplicant_eapol_cb(struct eapol_sm *eapol, int success,
+ void *ctx)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ int res, pmk_len;
+ u8 pmk[PMK_LEN];
+
+ wpa_printf(MSG_DEBUG, "EAPOL authentication completed %ssuccessfully",
+ success ? "" : "un");
+
+ if (!success || !wpa_s->driver_4way_handshake)
+ return;
+
+ if (wpa_s->key_mgmt != WPA_KEY_MGMT_IEEE8021X &&
+ wpa_s->key_mgmt != WPA_KEY_MGMT_FT_IEEE8021X)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Configure PMK for driver-based RSN 4-way "
+ "handshake");
+
+ pmk_len = PMK_LEN;
+ res = eapol_sm_get_key(eapol, pmk, PMK_LEN);
+ if (res) {
+ /*
+ * EAP-LEAP is an exception from other EAP methods: it
+ * uses only 16-byte PMK.
+ */
+ res = eapol_sm_get_key(eapol, pmk, 16);
+ pmk_len = 16;
+ }
+
+ if (res) {
+ wpa_printf(MSG_DEBUG, "Failed to get PMK from EAPOL state "
+ "machines");
+ return;
+ }
+
+ if (wpa_drv_set_key(wpa_s, WPA_ALG_PMK, NULL, 0, 0, NULL, 0, pmk,
+ pmk_len)) {
+ wpa_printf(MSG_DEBUG, "Failed to set PMK to the driver");
+ }
+
+ eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
+ wpa_supplicant_cancel_auth_timeout(wpa_s);
+ wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+
+}
+#endif /* IEEE8021X_EAPOL */
+
+
static int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s)
{
#ifdef IEEE8021X_EAPOL
@@ -2243,6 +2314,8 @@
ctx->opensc_engine_path = wpa_s->conf->opensc_engine_path;
ctx->pkcs11_engine_path = wpa_s->conf->pkcs11_engine_path;
ctx->pkcs11_module_path = wpa_s->conf->pkcs11_module_path;
+ ctx->cb = wpa_supplicant_eapol_cb;
+ ctx->cb_ctx = wpa_s;
wpa_s->eapol = eapol_sm_init(ctx);
if (wpa_s->eapol == NULL) {
os_free(ctx);
@@ -2392,11 +2465,14 @@
return -1;
}
- if (wpa_drv_get_capa(wpa_s, &capa) == 0 &&
- capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
- wpa_s->use_client_mlme = 1;
- if (ieee80211_sta_init(wpa_s))
- return -1;
+ if (wpa_drv_get_capa(wpa_s, &capa) == 0) {
+ if (capa.flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
+ wpa_s->use_client_mlme = 1;
+ if (ieee80211_sta_init(wpa_s))
+ return -1;
+ }
+ if (capa.flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE)
+ wpa_s->driver_4way_handshake = 1;
}
return 0;
Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant.conf Sat Nov 3 11:46:49 2007
@@ -295,7 +295,11 @@
# anonymous_identity: Anonymous identity string for EAP (to be used as the
# unencrypted identity with EAP types that support different tunnelled
# identity, e.g., EAP-TTLS)
-# password: Password string for EAP
+# password: Password string for EAP. This field can include either the
+# plaintext password (using ASCII or hex string) or a NtPasswordHash
+# (16-byte MD4 hash of password) in hash:<32 hex digits> format.
+# NtPasswordHash can only be used when the password is for MSCHAPv2 or
+# MSCHAP (EAP-MSCHAPv2, EAP-TTLS/MSCHAPv2, EAP-TTLS/MSCHAP, LEAP)
# ca_cert: File path to CA certificate file (PEM/DER). This file can have one
# or more trusted CA certificates. If ca_cert and ca_path are not
# included, server certificate will not be verified. This is insecure and
Modified: wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h
URL: http://svn.debian.org/wsvn/pkg-wpa/wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h?rev=880&op=diff
==============================================================================
--- wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h (original)
+++ wpasupplicant/trunk/wpa_supplicant/wpa_supplicant_i.h Sat Nov 3 11:46:49 2007
@@ -349,6 +349,7 @@
struct wpa_client_mlme mlme;
int use_client_mlme;
+ int driver_4way_handshake;
};
More information about the Pkg-wpa-devel
mailing list