Windows 8.1 Wi-Fi client handshake failure
Hello, I'm having trouble getting a Windows 8.1 laptop to connect to my Wi-Fi which is using only EAP-TLS managed by FreeRADIUS. Before you ask, yes I have included serverAuth/clientAuth in the certificates and the configuration is tested to work with Linux and Android clients, so I don't think there is a problem on the server side. That is as far as Google has been able to help me, so I'm hoping someone here has had the same problem and might know a solution. The specific issue as far as I can troubleshoot is that the client and server can't agree on a shared TLS cipher. I'm seeing these lines in my logs every time I attempt a connection: Info: [tls] TLS_accept: before/accept initialization Info: [tls] <<< TLS 1.0 Handshake [length 0067], ClientHello Info: [tls] >>> TLS 1.0 Alert [length 0002], fatal handshake_failure Error: TLS Alert write:fatal:handshake failure Error: TLS_accept: error in SSLv3 read client hello C Error: rlm_eap: SSL error error:1408A0C1:lib(20):func(138):reason(193) Error: SSL: SSL_read failed in a system call (-1), TLS session fails.
From [1] it looks like the SSL errors mean:
lib(20) = ERR_LIB_SSL func(138) = SSL_F_SSL3_GET_CLIENT_HELLO reason(193) = SSL_R_NO_SHARED_CIPHER [1] http://comments.gmane.org/gmane.comp.encryption.openssl.user/9654 But that is as far as I can get. I've tried disabling every option I can in the configs and many variations on the Windows side, but they all stop at the same point. There is no limit I have set on which TLS ciphers can be used (cipher_list in eap{tls{}} is not used, and gave the same error when set to DEFAULT). My only other guess is there is something wrong with the certificates, but I'm not sure what might be wrong. I have copied both my root and my radius intermediate CA certificates onto the Windows client along with the client certificate and key. They are installed and the chain is valid according to the Windows Credential Manager. The server ca.pem has both the root and intermediate certificates concatenated together and that works fine with my other clients. So all I can think of is that Windows is being extra picky about something. Below is the sanitized text certificate for the server and client in the hope that the error is obvious to someone else: openssl x509 -text -in server.crt Certificate: Data: Version: 3 (0x2) Serial Number: * Signature Algorithm: ecdsa-with-SHA512 Issuer: O=CA, OU=radius Validity Not Before: Oct 6 17:01:03 2014 GMT Not After : Oct 6 17:01:03 2015 GMT Subject: O=CA, OU=radius, CN=my.server.fqdn Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (521 bit) pub: * ASN1 OID: secp521r1 X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: * X509v3 Authority Key Identifier: keyid:* DirName:/O=CA/OU=root serial:* X509v3 CRL Distribution Points: Full Name: URI:http://my.crl.fqdn/radius.crl Authority Information Access: CA Issuers - URI:http://my.crl.fqdn/radius.pem OCSP - URI:http://my.ocsp.fqdn X509v3 Key Usage: Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Issuer Alternative Name: <EMPTY> X509v3 Subject Alternative Name: DNS:my.server.fqdn Signature Algorithm: ecdsa-with-SHA512 * -----BEGIN CERTIFICATE----- * -----END CERTIFICATE----- openssl x509 -text -in client.crt Certificate: Data: Version: 3 (0x2) Serial Number: * Signature Algorithm: ecdsa-with-SHA512 Issuer: O=CA, OU=radius Validity Not Before: Oct 1 21:49:00 2014 GMT Not After : Oct 1 21:49:00 2015 GMT Subject: O=CA, OU=radius, CN=username Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (521 bit) pub: * ASN1 OID: secp521r1 X509v3 extensions: X509v3 Basic Constraints: CA:FALSE X509v3 Subject Key Identifier: * X509v3 Authority Key Identifier: keyid:* DirName:/O=CA/OU=root serial:* X509v3 CRL Distribution Points: Full Name: URI:http://my.crl.fqdn/radius.crl Authority Information Access: CA Issuers - URI:http://my.crl.fqdn/radius.pem OCSP - URI:http://my.ocsp.fqdn X509v3 Key Usage: Digital Signature X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Issuer Alternative Name: <EMPTY> Signature Algorithm: ecdsa-with-SHA512 * -----BEGIN CERTIFICATE----- * -----END CERTIFICATE----- And my logs for good measure radiusd -XX Info: radiusd: FreeRADIUS Version 2.2.5, for host mips-openwrt-linux-gnu, built on Sep 28 2014 at 19:17:25 Debug: Server was built with: Debug: accounting Debug: authentication Debug: WITH_DHCP Debug: WITH_VMPS Debug: Server core libs: Debug: ssl: OpenSSL 1.0.1i 6 Aug 2014 Info: Copyright (C) 1999-2013 The FreeRADIUS server project and contributors. Info: There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A Info: PARTICULAR PURPOSE. Info: You may redistribute copies of FreeRADIUS under the terms of the Info: GNU General Public License. Info: For more information about these matters, see the file named COPYRIGHT. Info: Starting - reading configuration files ... Debug: including configuration file /etc/freeradius2/radiusd.conf Debug: including configuration file /etc/freeradius2/clients.conf Debug: including configuration file /etc/freeradius2/eap.conf Debug: including files in directory /etc/freeradius2/sites/ Debug: including configuration file /etc/freeradius2/sites/default Debug: main { Debug: allow_core_dumps = no Debug: } Debug: including dictionary file /etc/freeradius2/dictionary Debug: main { Debug: name = "radiusd" Debug: prefix = "/usr" Debug: localstatedir = "/var" Debug: sbindir = "/usr/sbin" Debug: logdir = "/var/log" Debug: run_dir = "/var/run" Debug: libdir = "/usr/lib/freeradius2" Debug: radacctdir = "/var/db/radacct" Debug: hostname_lookups = no Debug: max_request_time = 30 Debug: cleanup_delay = 5 Debug: max_requests = 2048 Debug: pidfile = "/var/run/radiusd.pid" Debug: checkrad = "/usr/sbin/checkrad" Debug: debug_level = 0 Debug: proxy_requests = yes Debug: log { Debug: stripped_names = no Debug: auth = no Debug: auth_badpass = no Debug: auth_goodpass = no Debug: } Debug: } Debug: radiusd: #### Loading Realms and Home Servers #### Debug: radiusd: #### Loading Clients #### Debug: client localhost { Debug: ipaddr = 127.0.0.1 Debug: require_message_authenticator = yes Debug: secret = "*removed1*" Debug: nastype = "other" Debug: } Debug: radiusd: #### Instantiating modules #### Debug: radiusd: #### Loading Virtual Servers #### Debug: server { # from file ?4?wXj Debug: modules { Debug: Module: Checking authenticate {...} for more modules to load Debug: (Loaded rlm_eap, checking if it's valid) Debug: Module: Linked to module rlm_eap Debug: Module: Instantiating module "eap" from file /etc/freeradius2/eap.conf Debug: eap { Debug: default_eap_type = "tls" Debug: timer_expire = 60 Debug: ignore_unknown_eap_types = no Debug: cisco_accounting_username_bug = no Debug: max_sessions = 2048 Debug: } Debug: Module: Linked to sub-module rlm_eap_tls Debug: Module: Instantiating eap-tls Debug: tls { Debug: rsa_key_exchange = no Debug: dh_key_exchange = yes Debug: rsa_key_length = 512 Debug: dh_key_length = 512 Debug: verify_depth = 0 Debug: pem_file_type = yes Debug: private_key_file = "/etc/freeradius2/certs/server.key" Debug: certificate_file = "/etc/freeradius2/certs/server.crt" Debug: CA_file = "/etc/freeradius2/certs/ca.pem" Debug: dh_file = "/etc/freeradius2/certs/dh" Debug: fragment_size = 1024 Debug: include_length = yes Debug: check_crl = no Debug: ecdh_curve = "prime256v1" Debug: } Debug: Module: Checking authorize {...} for more modules to load Debug: } # modules Debug: } # server Debug: radiusd: #### Opening IP addresses and Ports #### Debug: listen { Debug: type = "auth" Debug: ipaddr = 127.0.0.1 Debug: port = 0 Debug: } Debug: Listening on authentication address 127.0.0.1 port 1812 Debug: Listening on proxy address * port 1104 Info: Ready to process requests. rad_recv: Access-Request packet from host 127.0.0.1 port 51343, id=22, length=205 User-Name = "*removed2*" Called-Station-Id = "*removed3*" NAS-Port-Type = Wireless-802.11 NAS-Port = 2 Calling-Station-Id = "*removed4*" Connect-Info = "CONNECT 54Mbps 802.11a" Acct-Session-Id = "542D9EF5-0000004F" Framed-MTU = 1400 EAP-Message = 0x024700110162726f6e7468696e6b706164 Message-Authenticator = 0x7e8c00ff349e844a25b649a660222938 Info: # Executing section authorize from file /etc/freeradius2/sites/default Info: +group authorize { Info: [eap] EAP packet type response id 71 length 17 Info: [eap] No EAP Start, assuming it's an on-going EAP conversation Info: ++[eap] = updated Info: +} # group authorize = updated Info: Found Auth-Type = EAP Info: # Executing group from file /etc/freeradius2/sites/default Info: +group authenticate { Info: [eap] EAP Identity Info: [eap] processing type tls Info: [tls] Requiring client certificate Info: [tls] Initiate Info: [tls] Start returned 1 Info: ++[eap] = handled Info: +} # group authenticate = handled Sending Access-Challenge of id 22 to 127.0.0.1 port 51343 EAP-Message = 0x014800060d20 Message-Authenticator = 0x00000000000000000000000000000000 State = 0xafea1117afa21cb71a84ea873cb44d4b Info: Finished request 0. Debug: Going to the next request Debug: Waking up in 4.9 seconds. rad_recv: Access-Request packet from host 127.0.0.1 port 51343, id=23, length=324 User-Name = "*removed2*" Called-Station-Id = "*removed3*" NAS-Port-Type = Wireless-802.11 NAS-Port = 2 Calling-Station-Id = "*removed4*" Connect-Info = "CONNECT 54Mbps 802.11a" Acct-Session-Id = "542D9EF5-0000004F" Framed-MTU = 1400 EAP-Message = 0x024800760d800000006c16030100670100006303015432d337768f888dfe17dc33835f35dd997aa21e12f03cacec5381488ea003f3000018c014c0130035002fc00ac00900380032000a00130005000401000022ff01000100000500050100000000000a0006000400170018000b0002010000230000 State = 0xafea1117afa21cb71a84ea873cb44d4b Message-Authenticator = 0xa8307e6d117840db9b85cd0c44938b91 Info: # Executing section authorize from file /etc/freeradius2/sites/default Info: +group authorize { Info: [eap] EAP packet type response id 72 length 118 Info: [eap] No EAP Start, assuming it's an on-going EAP conversation Info: ++[eap] = updated Info: +} # group authorize = updated Info: Found Auth-Type = EAP Info: # Executing group from file /etc/freeradius2/sites/default Info: +group authenticate { Info: [eap] Request found, released from the list Info: [eap] EAP/tls Info: [eap] processing type tls Info: [tls] Authenticate Info: [tls] processing EAP-TLS Debug: TLS Length 108 Info: [tls] Length Included Info: [tls] eaptls_verify returned 11 Info: [tls] (other): before/accept initialization Info: [tls] TLS_accept: before/accept initialization Info: [tls] <<< TLS 1.0 Handshake [length 0067], ClientHello Info: [tls] >>> TLS 1.0 Alert [length 0002], fatal handshake_failure Error: TLS Alert write:fatal:handshake failure Error: TLS_accept: error in SSLv3 read client hello C Error: rlm_eap: SSL error error:1408A0C1:lib(20):func(138):reason(193) Error: SSL: SSL_read failed in a system call (-1), TLS session fails. Debug: TLS receive handshake failed during operation Info: [tls] eaptls_process returned 4 Info: [eap] Handler failed in EAP/tls Info: [eap] Failed in EAP select Info: ++[eap] = invalid Info: +} # group authenticate = invalid Info: Failed to authenticate the user. Sending Access-Reject of id 23 to 127.0.0.1 port 51343 EAP-Message = 0x04480004 Message-Authenticator = 0x00000000000000000000000000000000 Info: Finished request 1. Debug: Going to the next request Debug: Waking up in 4.9 seconds. Info: Cleaning up request 0 ID 22 with timestamp +40 Info: Cleaning up request 1 ID 23 with timestamp +40 Info: Ready to process requests.
Martin Rowe wrote:
The specific issue as far as I can troubleshoot is that the client and server can't agree on a shared TLS cipher. I'm seeing these lines in my logs every time I attempt a connection:
You'll probably need to update the "cipher_list" in the "eap" module configuration. Windows is picky...
But that is as far as I can get. I've tried disabling every option I can in the configs and many variations on the Windows side, but they all stop at the same point. There is no limit I have set on which TLS ciphers can be used (cipher_list in eap{tls{}} is not used, and gave the same error when set to DEFAULT).
The DEFAULT list of ciphers is old. Your OpenSSL libraries may not include the new ciphers that Windows expects. Try setting it to "ALL". If that doesn't work, it's more difficult to say what's wrong. Windows is "helpful" and doesn't produce reasonable error messages about what it expects.
My only other guess is there is something wrong with the certificates, but I'm not sure what might be wrong. I have copied both my root and my radius intermediate CA certificates onto the Windows client along with the client certificate and key. They are installed and the chain is valid according to the Windows Credential Manager.
Then that should work. Does PEAP work? Alan DeKok.
Alan DeKok wrote:
The DEFAULT list of ciphers is old. Your OpenSSL libraries may not include the new ciphers that Windows expects. Try setting it to "ALL". If that doesn't work, it's more difficult to say what's wrong. Windows is "helpful" and doesn't produce reasonable error messages about what it expects.
Hadn't tried "ALL", but testing it now doesn't change the error. The config line in the debug output did reflect "ALL" being set.
Does PEAP work?
I just added a couple of config lines to allow PEAP/MSCHAPv2. My Android device was still able to negotiate a TLS connection, but the Windows client stops with the same error (just [tls] swapped with [peap], otherwise the lines are identical). At least that eliminates the client certificate. I'll play around some of the extensions on the server certificate. Thanks Marty
Martin Rowe wrote:
At least that eliminates the client certificate. I'll play around some of the extensions on the server certificate.
So I played around a lot with the server certificate. The error only occurs when the server key is generated using curve secp521r1. [1] and [2] both claim Windows 8.1 supports that curve, and it works with the other "supported" curves (secp256r1 and secp384r1) and even works when Windows uses secp521r1 for the client key/certificate, just not when the server uses it. Like I said earlier, Linux and Android are both able to connect when the server uses secp521r1, so I'm assuming this is a Windows bug. [1] http://technet.microsoft.com/en-us/library/cc766285(v=ws.10).aspx [2] http://en.wikipedia.org/wiki/Comparison_of_TLS_implementations A little further investigation found [3] which seems to indicate that secp521r1 can be enabled. I checked on Windows 8.1 and the settings appear the same, but it's late so this will have to wait until tomorrow. There is still hope. [3] http://www.carbonwind.net/blog/post/IE8-on-Windows-7-and-the-sha512ecdsa-com... Thanks Marty
Martin Rowe wrote:
So I played around a lot with the server certificate. The error only occurs when the server key is generated using curve secp521r1.
Ah... elliptical curves are notorious for inter-operability issues. When I create certificates, I use "conservative" values. RSA, 2048 bit keys, SHA, etc. That works everywhere. The more "odd" things you use, the less likely it is to work. Alan DeKok.
For TLS-based EAP purposes, I feel we should all be using certificates with SHA-2 family signature algorithms now, the best choice probably being SHA-256, as Microsoft, Google and Mozilla are actively deprecating SHA-1. Even though this is mostly in the context of the secure Web, is it not likely that we will see operating systems being hostile to certificates with a SHA-1 signature algorithm going forward, as it is today with certificates that use MD5? http://blogs.technet.com/b/pki/archive/2013/11/12/sha1-deprecation-policy.as... http://googleonlinesecurity.blogspot.com/2014/09/gradually-sunsetting-sha-1.... https://wiki.mozilla.org/CA:Problematic_Practices#SHA-1_Certificates On Tue, Oct 7, 2014 at 1:19 PM, Alan DeKok <aland@deployingradius.com> wrote:
When I create certificates, I use "conservative" values. RSA, 2048 bit keys, SHA, etc. That works everywhere.
Nick Lowe wrote:
For TLS-based EAP purposes, I feel we should all be using certificates with SHA-2 family signature algorithms now, the best choice probably being SHA-256, as Microsoft, Google and Mozilla are actively deprecating SHA-1.
Version 3.0.4 (and following) defaults to SHA256. Version 2.2.6 (and following) will default to SHA256. Alan DeKok.
Hi,
A little further investigation found [3] which seems to indicate that secp521r1 can be enabled. I checked on Windows 8.1 and the settings appear the same, but it's late so this will have to wait until tomorrow. There is still hope.
yes client issue. I expect, actually its a driver issue...and if you do something horrible like enable FIPS mode on the client (so all the encryption is done in software via CPU rather than by NIC in hardware via driver) it'll work :( alan
yes client issue. I expect, actually its a driver issue...and if you do something horrible like enable FIPS mode on the client (so all the encryption is done in software via CPU rather than by NIC in hardware via driver) it'll work :(
Unfortunately FIPS did not help, neither did the registry hack in [3] above. There is a bug somewhere in the Windows/Intel driver mix, but I'm not going to waste any more of my time trying to solve their standards (in)compliance.
When I create certificates, I use "conservative" values. RSA, 2048 bit keys, SHA, etc. That works everywhere. The more "odd" things you use, the less likely it is to work.
I tend to try the strongest values I can get to work, and in this case a server key using secp384r1 will still work while I need to support Windows clients. But then again maybe that's why I keep having odd things go wrong that Google can't help solve ;) Thanks everyone for your help Marty
participants (4)
-
A.L.M.Buxey@lboro.ac.uk -
Alan DeKok -
Martin Rowe -
Nick Lowe