The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Functions | Variables
tls.c File Reference

Implements the EAP part of EAP-TLS. More...

#include <freeradius-devel/unlang/function.h>
#include "tls.h"
#include "attrs.h"
+ Include dependency graph for tls.c:

Go to the source code of this file.

Functions

static int eap_tls_ack (request_t *request, eap_session_t *eap_session)
 ACK a fragment of the TLS record from the peer. More...
 
int eap_tls_compose (request_t *request, eap_session_t *eap_session, eap_tls_status_t status, uint8_t flags, fr_tls_record_t *record, size_t record_len, size_t frag_len)
 Convert the EAP-TLS reply packet into an EAP packet. More...
 
fr_tls_conf_t * eap_tls_conf_parse (CONF_SECTION *cs, char const *attr)
 Parse TLS configuration. More...
 
int eap_tls_fail (request_t *request, eap_session_t *eap_session)
 Send an EAP-TLS failure. More...
 
static unlang_action_t eap_tls_handshake_push (request_t *request, eap_session_t *eap_session)
 Push functions to continue the handshake asynchronously. More...
 
static unlang_action_t eap_tls_handshake_resume (UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, void *uctx)
 Process the result from the last TLS handshake round. More...
 
unlang_action_t eap_tls_process (request_t *request, eap_session_t *eap_session)
 Process an EAP TLS request. More...
 
int eap_tls_request (request_t *request, eap_session_t *eap_session)
 Frames the OpenSSL data that needs to be sent to the client in an EAP-Request. More...
 
eap_tls_session_teap_tls_session_init (request_t *request, eap_session_t *eap_session, SSL_CTX *ssl_ctx, bool client_cert)
 Create a new fr_tls_session_t associated with an eap_session_t. More...
 
static eap_tls_status_t eap_tls_session_status (request_t *request, eap_session_t *eap_session)
 Reduce session states down into an easy to use status. More...
 
int eap_tls_start (request_t *request, eap_session_t *eap_session)
 Send an initial EAP-TLS request to the peer. More...
 
int eap_tls_success (request_t *request, eap_session_t *eap_session, eap_tls_prf_label_t *prf_label)
 Send an EAP-TLS success. More...
 
static eap_tls_status_t eap_tls_verify (request_t *request, eap_session_t *eap_session)
 Check that this EAP-TLS packet is correct and the progression of EAP-TLS packets is sane. More...
 

Variables

USES_APPLE_DEPRECATED_API fr_table_num_ordered_t const eap_tls_status_table []
 
size_t eap_tls_status_table_len = NUM_ELEMENTS(eap_tls_status_table)
 

Detailed Description

Implements the EAP part of EAP-TLS.

Id
1d71573a9a6f8e91f2f58efa8cdfdfe0042828c1

RFC 2716 Section 4.2. PPP EAP TLS Request Packet

   0               1               2               3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Code      |   Identifier  |        Length           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     Type      |     Flags     |      TLS Message Length
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     TLS Message Length     |       TLS Data...
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Structure of an EAP-TLS packet

  code    = EAP-code
  id      = EAP-id
  length  = code + id + length + flags + tlsdata
           =  1   +  1 +   2    +  1    +  X
  length  = EAP-length - 1(EAP-Type = 1 octet)
  flags   = EAP-typedata[0] (1 octet)
  data_len    = EAP-typedata[1-4] (4 octets), if L flag set
           = length - 5(code+id+length+flags), otherwise
  data    = EAP-typedata[5-n], if L flag set
           = EAP-typedata[1-n], otherwise
  packet  = EAP-typedata (complete typedata)

The S flag is set only within the EAP-TLS start message sent from the EAP server to the peer.

Similarly, when the EAP server receives an EAP-Response with the M bit set, it MUST respond with an EAP-Request with EAP-Type = EAP-TLS and no data. This serves as a fragment ACK. The EAP peer MUST wait.

The Length field is two octets and indicates the length of the EAP packet including the Code, Identifier, Length, Type, and TLS data fields.

The TLS Message Length field is four octets and indicates the complete reassembled length of the TLS record fragment.

Definition in file tls.c.

Function Documentation

◆ eap_tls_ack()

static int eap_tls_ack ( request_t request,
eap_session_t eap_session 
)
static

ACK a fragment of the TLS record from the peer.

EAP server sends an ACK when it determines there are More fragments to receive to make the complete TLS-record.

When the EAP server receives an EAP-Response with the M bit set, it MUST respond with an EAP-Request with EAP-Type = EAP-TLS and no data. This serves as a fragment ACK.

In order to prevent errors in the processing of fragments, the EAP server MUST use increment the Identifier value for each fragment ACK contained within an EAP-Request, and the peer MUST include this Identifier value in the subsequent fragment contained within an EAP-Reponse.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionthat we're acking the fragment for.

Definition at line 462 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_compose()

int eap_tls_compose ( request_t request,
eap_session_t eap_session,
eap_tls_status_t  status,
uint8_t  flags,
fr_tls_record_t *  record,
size_t  record_len,
size_t  frag_len 
)

Convert the EAP-TLS reply packet into an EAP packet.

The EAP packet will be written to eap_round->request, with the original reply being untouched.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionto continue.
[in]statusWhat type of packet we're sending.
[in]flagsto set. This is checked to determine if we need to include a length field.
[in]recordThe record buffer to read from. This most only be set for EAP_TLS_RECORD_SEND packets.
[in]record_lenthe length of the record we're sending.
[in]frag_lenthe length of the fragment we're sending.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 112 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_conf_parse()

fr_tls_conf_t* eap_tls_conf_parse ( CONF_SECTION cs,
char const *  attr 
)

Parse TLS configuration.

If the option given by 'attr' is set, we find the config section of that name and use that for the TLS configuration. If not, we fall back to compatibility mode and read the TLS options from the 'tls' section.

Parameters
csto derive the configuration from.
attridentifier for common TLS configuration.
Returns
  • NULL on error.
  • A new fr_tls_conf_t on success.

Definition at line 1210 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_fail()

int eap_tls_fail ( request_t request,
eap_session_t eap_session 
)

Send an EAP-TLS failure.

Composes an EAP-TLS-Failure. This is a message with code EAP_TLS_FAILURE. It contains no cryptographic material, and is not protected.

In addition to sending the failure, will destroy any cached session data.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionthat failed.
Returns
  • 0 on success.
  • -1 on failure (to compose a valid packet).

Definition at line 320 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_handshake_push()

static unlang_action_t eap_tls_handshake_push ( request_t request,
eap_session_t eap_session 
)
inlinestatic

Push functions to continue the handshake asynchronously.

Parameters
[in]requestthe current subrequest.
[in]eap_sessionto continue.
Returns
  • UNLANG_ACTION_PUSHED_CHILD

Definition at line 916 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_handshake_resume()

static unlang_action_t eap_tls_handshake_resume ( UNUSED rlm_rcode_t p_result,
UNUSED int *  priority,
request_t request,
void *  uctx 
)
static

Process the result from the last TLS handshake round.

Returns
  • eap_tls_session->state = EAP_TLS_FAIL if the message is invalid.
  • eap_tls_session->state = EAP_TLS_HANDLED if we need to send an additional request to the peer.
  • eap_tls_session->state = EAP_TLS_ESTABLISHED if the handshake completed successfully, and there's no more data to send.

Definition at line 800 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_process()

unlang_action_t eap_tls_process ( request_t request,
eap_session_t eap_session 
)

Process an EAP TLS request.

Here we implement a basic state machine. The state machine is implicit and is driven by the state of the TLS session and the flags sent. INCOMING DATA:

  1. EAP-TLS should get the complete TLS data from the peer.
  2. Store that data in a data structure with any other required info
  3. Hand this data structure to the TLS module.
  4. TLS module will perform its operations on the data and hands back to EAP-TLS OUTGOING DATA:
  1. EAP-TLS if necessary will fragment it and send it to the destination.

During EAP-TLS initialization, TLS Context object will be initialised and stored. For every new authentication request, TLS will open a new session object and that session object SHOULD be maintained even after the session is completed, for session resumption.

Parameters
requestthe request
eap_sessionto continue.
Returns
  • EAP_TLS_ESTABLISHED
  • EAP_TLS_HANDLED

Definition at line 957 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_request()

int eap_tls_request ( request_t request,
eap_session_t eap_session 
)

Frames the OpenSSL data that needs to be sent to the client in an EAP-Request.

A single TLS record may be up to 16384 octets in length, but a TLS message may span multiple TLS records, and a TLS certificate message may theoretically, be as big as 16MB.

In EAP-TLS with no inner method, this is used primarily to send our certificate chain to the peer.

In other methods this function is also called to package up application data for the inner tunnel method.

The eap_tls_session->length_included flag determines whether we include the extra four byte length field in the request and set the L flag.

If present, the tls_length field indicates the total length of the reassembled TLS record.

If eap_tls_session->length_included this means we include L flag and the tls_length field in EVERY packet we send out.

If !eap_tls_session->length_included this means we include L flag and tls_length field ONLY in First packet of a fragment series. We do not use it anywhere else.

Parameters
requestthe request
eap_sessionthat's continuing.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 370 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_session_init()

eap_tls_session_t* eap_tls_session_init ( request_t request,
eap_session_t eap_session,
SSL_CTX *  ssl_ctx,
bool  client_cert 
)

Create a new fr_tls_session_t associated with an eap_session_t.

Creates a new server fr_tls_session_t and associates it with an eap_session_t adding EAP specific opaque data to the SSL session created during fr_tls_session_t initialisation.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionto use as a context for the eap_tls_session_t
[in]ssl_ctxto use to configure the fr_tls_session_t.
[in]client_certWhether we require the peer to prevent a certificate.
Returns
  • A new eap_tls_session on success.
  • NULL on error.

Definition at line 1125 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_session_status()

static eap_tls_status_t eap_tls_session_status ( request_t request,
eap_session_t eap_session 
)
static

Reduce session states down into an easy to use status.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionthat we're acking the fragment for.
Returns
  • EAP_TLS_ESTABLISHED - Handshake completed.
  • EAP_TLS_FAIL - Fatal alert from the client.
  • EAP_TLS_RECORD_SEND - Need more data, or previous fragment was acked.

Definition at line 482 of file tls.c.

+ Here is the caller graph for this function:

◆ eap_tls_start()

int eap_tls_start ( request_t request,
eap_session_t eap_session 
)

Send an initial EAP-TLS request to the peer.

Once having received the peer's Identity, the EAP server MUST respond with an EAP-TLS/Start packet, which is an EAP-Request packet with EAP-Type = EAP-TLS, the Start (S) bit set, and no data.

The EAP-TLS conversation will then begin, with the peer sending an EAP-Response packet with EAP-Type = EAP-TLS. The data field of that packet will be the TLS data.

The S flag is set only within the EAP-TLS start message sent from the EAP server to the peer.

  • len = header + type + tls_typedata
  • tls_typedata = flags(Start (S) bit set, and no data)

Fragment length is Framed-MTU - 4.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionto initiate.
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 237 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_success()

int eap_tls_success ( request_t request,
eap_session_t eap_session,
eap_tls_prf_label_t prf_label 
)

Send an EAP-TLS success.

Composes an EAP-TLS-Success. This is a message with code EAP_TLS_ESTABLISHED. It contains no cryptographic material, and is not protected.

We add the MPPE keys here. These are used by the NAS. The supplicant will derive the same keys separately.

Parameters
[in]requestThe current subrequest.
[in]eap_sessionthat completed successfully.
[in]prf_labelPRF label struct
Returns
  • 0 on success.
  • -1 on failure.

Definition at line 262 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ eap_tls_verify()

static eap_tls_status_t eap_tls_verify ( request_t request,
eap_session_t eap_session 
)
static

Check that this EAP-TLS packet is correct and the progression of EAP-TLS packets is sane.

Note
In the received packet, No data will be present in case of ACK or NAK in this case the packet->data pointer will be NULL.
Parameters
[in]requestthe current subrequest.
[in]eap_sessionthe current EAP session state.
Returns
  • EAP_TLS_INVALID if the TLS record or progression is invalid.
  • EAP_TLS_FAIL handshake failed.
  • EAP_TLS_RECORD_RECV_FIRST this is the start of a new sequence of record fragments.
  • EAP_TLS_RECORD_RECV_MORE this is a continuation of a sequence of fragments.
  • EAP_TLS_RECORD_RECV_COMPLETE we received a completed record.
  • EAP_TLS_RECORD_SEND send more data to peer.
  • EAP_TLS_ESTABLISHED handshake is complete, TLS session has been established.

Definition at line 553 of file tls.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ eap_tls_status_table

USES_APPLE_DEPRECATED_API fr_table_num_ordered_t const eap_tls_status_table[]
Initial value:
= {
{ L("invalid"), EAP_TLS_INVALID },
{ L("established"), EAP_TLS_ESTABLISHED },
{ L("fail"), EAP_TLS_FAIL },
{ L("handled"), EAP_TLS_HANDLED },
{ L("start"), EAP_TLS_START_SEND },
{ L("request"), EAP_TLS_RECORD_SEND },
{ L("ack"), EAP_TLS_ACK_SEND },
}
#define L(_str)
Helper for initialising arrays of string literals.
Definition: build.h:207
@ EAP_TLS_RECORD_RECV_FIRST
Received first fragment of a record.
Definition: tls.h:109
@ EAP_TLS_INVALID
Invalid, don't reply.
Definition: tls.h:91
@ EAP_TLS_HANDLED
TLS code has handled it.
Definition: tls.h:94
@ EAP_TLS_RECORD_RECV_MORE
Received additional fragment of a record.
Definition: tls.h:110
@ EAP_TLS_ACK_SEND
Acknowledge receipt of a record or record fragment.
Definition: tls.h:102
@ EAP_TLS_RECORD_SEND
We're sending a record.
Definition: tls.h:101
@ EAP_TLS_RECORD_RECV_COMPLETE
Received final fragment of a record.
Definition: tls.h:111
@ EAP_TLS_START_SEND
We're starting a new TLS session.
Definition: tls.h:100
@ EAP_TLS_FAIL
Fail, send fail.
Definition: tls.h:93
@ EAP_TLS_ESTABLISHED
Session established, send success (or start phase2).
Definition: tls.h:92

Definition at line 78 of file tls.c.

◆ eap_tls_status_table_len

size_t eap_tls_status_table_len = NUM_ELEMENTS(eap_tls_status_table)

Definition at line 92 of file tls.c.