FreeRADIUS EAP-TLS issues

Alan DeKok aland at deployingradius.com
Thu Nov 22 13:57:01 CET 2007


Jouni Malinen wrote:
>>   Hmm... I don't see that with the CVS head.
> 
> I still do. How large certificates are you using? I'm hitting the
> fragment limit in phase 2 and the bug is triggered when sending the
> second fragment of the message that includes server certificate.

  I'm using 1024 bit keys, ~3k .pem files.

>>   The phase 2 data doesn't get fragmented in FreeRADIUS.  The code
>> doesn't handle that at all.  It just gets truncated.
> 
> Not fragmenting phase 2 data sounds fine, but truncating it does not.. I
> would have expected this to be handled by fragmenting the long phase 2
> data in phase 1.

  Well, yes.  The issue is I don't know much about SSL, EAP-TLS... and
the code in rlm_eap is "interesting".  It's been hacked to work, and
then hacked further to shove policy management and proxying into the
middle of the EAP sessions.  It's ugly...

  I've just committed some more fixes that make TTLS/PEAP call the
tls_hanshake_recv() function, which takes care of fragments and ACKs.
That appears to work a little better.

>>   When trying PEAP with tunneled EAP-TLS, (and some additional patches),
>>   it gets to the point where the server is looking for a client
>> certificate, and doesn't get one.  In response to the server ACK,
>> wpa_supplicant just sends another ACK... and the cycle repeats until it
>> gives up.
> 
> How did you configure wpa_supplicant? The network block should have
> something like this:

  Pretty much.  I didn't have the ca_certs in there, but that doesn't
seem to make any difference.

> I started looking into more details and it looks like the bug is in how
> FreeRADIUS handles fragmentation for the encrypted phase 2 data. The
> issue I'm seeing is triggered by eappeap_authenticate() processing
> status==EAPTLS_SUCCESS by adding an EAP packet into
> tls_session->clean_in while there is pending data (the second fragment)
> of the tunneled EAP-TLS message. This will make clean_in->used > 0 check
> in tls_handshake_send() trigger and this new EAP message from
> eappeap_authenticate() is written into TLS data (SSL_write()) and
> dirty_out is now corrupted by using the encrypted, incorrect EAP packet
> (BIO_read in tls_handshake_send() overrides the pending second
> fragment).

  OK.  I've updated libeap/tls.c, eaptls_ack_handler() to look for
dirty_out.used, and return EAPTLS_REQUEST, rather than EAPTLS_SUCCESS.
That permits the phase 2 data to be fragmented.

> I did not understand what the EAPTLS_SUCCESS processing in
> eappeap_authenticate() was supposed to do, but in practice, the current
> implementation is corrupting any PEAP phase 2 data that needs to be
> fragmented. I would assume that eappeap_authenticate() would need to be
> modified not to add this new EAP packet if there is pending data to be
> sent out, but I don't know how exactly this should be done.

  I've made a bunch of changes which should fix that problem.

> Anyway, I
> tested a quick hack that prevented clean_in from being modified here and
> that allowed the fragmented message to go through successfully (i.e.,
> unmodified eapol_test received the frame and was able to decrypt it).
> This hack was not enough to handle further processing, so someone will
> need to figure out how to fix this properly.

  I've made some more hacks (uncommitted) to work around certain
assumptions in the internal implementation of the server.  I now see the
connection established, and then the inner EAP-TLS session says:

  rlm_eap_tls: >>> TLS 1.0 Handshake [length 00a8], CertificateRequest
    TLS_accept: SSLv3 write certificate request A
    TLS_accept: SSLv3 flush data
    TLS_accept: Need to read more data: SSLv3 read client certificate A

  wpa_supplicant sends the certificate in 3 fragments, including change
cipher specs, and FreeRADIUS receives the fragments. However, FreeRADIUS
doesn't process the data, and instead asks for more.

  Alan DeKok.



More information about the Freeradius-Devel mailing list