Cipher list presented by wpa_supplicant does not reflect type of ca_cert used, causes authentication failures

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>  Another issue is with cipher negotiation.  This affects TLS 1.2, too.
>  If the cipher list contains ECC, then OpenSSL is happy to negotiate ECC.  Even if it's only been configured with RSA certs.  So wpa_supplicant sends "I can do ECC and RSA", and when FreeRADIUS responds with an ECC cert, wpa_supplicant goes "no compatible cipher list".  Authentication then fails.  This makes end users unhappy.

OK, so there are two issues here, one more specific to FreeRADIUS, and a general one for EAP clients using OpenSSL.

For the FreeRADIUS a contributor introduced a flag "cipher_server_preference", which they set to default to "yes" (true), which sets SSL_OP_CIPHER_SERVER_PREFERENCE in the SSL_CTX.  This flag breaks cipher negotiation, in that the server completely ignores the clients cipher list, and uses its, local, configured, cipher list instead.

What we really want is the union of the server's acceptable ciphers and the clients acceptable ciphers, I don't think OpenSSL is calculating this irrespective of SSL_OP_CIPHER_SERVER_PREFERENCE, but i'd need to investigate more.  This issue is orthogonal to the next issue and something we'll deal with internally.

--

The second issue is that wpa_supplicant isn't being smart about the ordering or content of its cipher list.

Ideally: 
- If the ca_cert configured is an ECC cert, then the ECC kx ciphers should be first in the acceptable cipher list
- If the ca_cert configured is an RSA cert, then the RSA kx ciphers should be first in the acceptable cipher list.
- If it's using DH kx, DH ciphers.
- PSK, PSK kx ciphers etc...

I don't know about the last two (not tested), but I know that it's not currently being smart about the first two.

The problem comes when two certificate chains are configured on the RADIUS server, one for ECC and one for RSA (as is supported in OpenSSL >= 1.0.2 and probably other libraries). OpenSSL will present the certificate chain matching the server key type that matches the kx type of the chosen cipher.

Even if wpa_supplicant only has access to the RSA ca_cert cert, in newer versions of OpensSSL it'll indicate a preference for ciphers with a ECC kx, so the EAP server will send over the ECC cert chain and authentication will fail.

I'm not sure about the real world severity of the issue.  I would imagine if wpa_supplicant is compiled against an OpenSSL version new enough to prefer ciphers with ECC kx, then common ECC root CA certs would be present on the system in addition to the RSA ones.  If this is the case everything should work fine.

There are two solutions to this problem that I can see, and they're complimentary not exclusive.

- First, if only a single ca_cert is configured and there's no cipher list explicitly configured.  wpa_supplicant should only present ciphers with a kx algorithm compatible with that CA.  I believe you can have mixed type trust chains, but I don't believe this is at all common.

- Second, allow multiple ca_cert to be configured if this isn't allowed already.  OpenSSL does most of the heavy lifting for you here.  You just need to call SSL_CTX_use_certificate_chain_file with each of the different ca_cert options.  It'll sort them into the different chains for you. 

>  This is arguably a bug in OpenSSL.  e.g. if you give it cipher list "DEFAULT" and only RSA certs, it should be smart enough to only negotiate compatible ciphers.  That process is made more difficult by the use of a CA directory, where OpenSSL looks up certificates as needed.  And therefore doesn't even know what certificates there are until it needs them.  Which then makes negotiation difficult.

Yes, agree with all of this apart from the bug part.  The issue is that cipher lists in OpenSSL are completely static, there's no adaptation to the type of certificate chain.  It is difficult for OpenSSL to make the determination about how to dynamically modify the cipher lists because of ca_path.  Honestly, this seems to be to be a decision best made at the application level.

>  A counter-argument here is that the application knows what certs it has, and the application should filter out incompatible ciphers.  However, that's difficult in part due to the opaque OpenSSL API, and also because it's not straightforward to map ASCII cipher strings map to certificate properties.

I just dug into this a bit more.  The SSL_CIPHER API has gotten significantly better.  There's even a SSL_CIPHER_get_kx_nid() call we could use to very easily determine compatible ciphers.

https://www.openssl.org/docs/manmaster/man3/SSL_CIPHER_get_name.html

Notes there suggest maybe this is a non-issue for TLS 1.3?

Additionally, this all seems rather stupid.  It would be much better for the client to be able to indicate a preference for a particular certificate chain.  I'm surprised there's not a TLS extension that allows this... Maybe there is and it's just not supported or enabled in OpenSSL?

-Arran
_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux