Template:EAP part 2

Jump to: navigation, search

Configure EAP by calling tfEapSetOption(). See the examples in the following EAP sections. If your application is a server (EAP authenticator) that accepts incoming connections, use option TM_EAP_USE_PROTO to request a particular authentication method. If your application is a client (EAP peer) that connects to a server, you only need to set the parameters for the methods you intend to support. A client may use option TM_EAP_REQ_PROTO to require a particular authentication method, which causes the client to fail if the server does not request the method.

Note Note: Options set via tfEapSetOption() will remain set after closing and reopening the interface (tfCloseInterface() and tfNgOpenInterface() or tfNgConfigInterface()).

EAP Timeout options

Treck sets default time limits on message exchanges for each EAP method and for the entire session, as recommended by the specification. You may change the following limits by calling tfEapSetOption().

Session timeout 
(Default: 120s) The maximum time to complete all methods.
Message retransmission 
Failing to receive a response within a time interval (default: 3s), each method will retransmit the last message a maximum number of times (default: 10). Message timeout is typically the responsibility of the authenticator (if a message is lost in either direction, the lock-step exchange stops for both ends).

EAP Identity method

As the name suggests, the Identity method is used by the authenticator to establish the peer's identity. The authenticator can then choose the authentication method and parameters that are suitable for the peer. Since EAP Identity is not useful for authentication, it is usually configured in conjunction with one of the authentication methods described in the following sections.

Configuring EAP Identity.
Client example Server example
ttUserInterface myInterface;
static char eapIdentity[] = "user@example.com";
int errorCode;
 
/* Set the EAP identity */
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_IDENT_STR,
                            eapIdentity,
                            strlen(eapIdentity) );
assert(errorCode == TM_ENOERROR);
 
ttUserInterface myInterface;
ttUser8Bit eapOpt;
int errorCode;
 
/* Request the peer's identity */
eapOpt = TM_EAP_IDENTITY;
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_USE_PROTO,
                            (char *)&eapOpt,
                            sizeof(eapOpt) );
assert(errorCode == TM_ENOERROR);
 

EAP MD5-Challenge Authentication method

A challenge-handshake exchange that uses the MD5 algorithm and a shared secret to authenticate the peer.

EAP MD5-Challenge specific function:

tfEapMd5RegisterAuthenticate() 
(Authenticator only) Register a function that will return the MD5-Challenge secret for a username.

Code examples to configure EAP MD5-Challenge:

Configuring EAP MD5-Challenge.
Client example Server example
ttUserInterface myInterface;
static char eapUsername[] = "user@example.com";
static char eapPassword[] = "password";
int errorCode;
 
/* Username and password for MD5-Challenge */
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_MD5_USERNAME,
                            eapUsername,
                            strlen(eapUsername) );
assert(errorCode == TM_ENOERROR);
 
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_MD5_PASSWORD,
                            eapPassword,
                            strlen(eapPassword) );
assert(errorCode == TM_ENOERROR);
 
ttUserInterface myInterface;
ttUser8Bit eapOpt;
static char eapName[] = "authenticator";
int errorCode;
 
/* Request MD5-Challenge exchange */
eapOpt = TM_EAP_MD5_CHALLENGE;
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_USE_PROTO,
                            (char *)&eapOpt,
                            sizeof(eapOpt) );
assert(errorCode == TM_ENOERROR);
 
/* Authenticator's name for MD5-Challenge */
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_MD5_AUTHNAME,
                            eapName,
                            strlen(eapName) );
assert(errorCode == TM_ENOERROR);
 
/* Register a function to provide MD5-Challenge secrets */
errorCode = tfEapMd5RegisterAuthenticate( myInterface,
                                          myMd5AuthFn );
assert(errorCode == TM_ENOERROR);
 
  . . .
 
static char * myMd5AuthFn(char * md5Name, int * errPtr)
{
    char * secretStr;  /* an ASCII NUL terminated string */
/*
 * Lookup the secret for md5Name.
 * If successful, set *errPtr = TM_ENOERROR and return the secret.
 * If unsuccessful, set *errPtr = TM_EACCES and return "".
 */
    return secretStr;
}
 

EAP-TLS Authentication method

The EAP-TLS method uses Treck TLS/SSL for authentication (using public key certificates). Note the following distinctions versus traditional TLS/SSL (RFC 5246):

TLS/SSL EAP-TLS
  • TLS/SSL offers authentication and data channel protection (encryption and integrity).
  • The client often remains anonymous to the server (client-side certificates are rare). The server application will often authenticate the client with other means, after the channel is secure (e.g. sign-on with username and password).
  • The session begins when client sends a TLS Client Hello after the transport layer connection is made (e.g. TCP handshake).
  • EAP Peer == TLS Client.
  • EAP Authenticator == TLS Server.
  • EAP-TLS offers authentication only. Once authentication is complete, the TLS session is destroyed.
  • The EAP peer will often need a signing certificate to prove it's identity to the authenticator.
  • The session begins with a method request from the EAP authenticator. The EAP peer responds with a TLS Client Hello.
  • Cryptographic key material can be exported, e.g. for data channel protection by some other means.
  • The minimum requirement is TLS v1.0. SSL v3.0 is not supported.

The EAP-TLS option is not compiled, by default. To use EAP-TLS, uncomment the following compile-time macros in trsystem.h and recompile the Treck library.

#define TM_USE_EAPTLS
#define TM_USE_SSL_CLIENT  /* if you need to connect as a client (peer) */
#define TM_USE_SSL_SERVER  /* if you need to connect as a server (authenticator) */
 

You will also need to initialize TLS/SSL, PKI and provide public key certificates (see SSL Programmer's Reference and Cryptography). The sample below shows the TLS client (EAP peer) providing a signing certificate. If the authenticator allows the EAP peer to remain anonymous, this step may be omitted.

The EAP-TLS option has the following additional code options in trsystem.h. By default, the options are compiled and available at runtime. If you have no need for the option, it can be disabled to reduce the Treck code size and, in the case of key export, execution time. The options are related to information that can be found in the EAP-TLS specification (RFC 5216). Additional runtime configuration may be required to enable the feature (see below and tfEapSetOption()).

#define TM_DISABLE_EAPTLS_AUTHENTICATOR   /* Authenticator (EAP-TLS server) support */
#define TM_DISABLE_EAPTLS_PEER            /* Peer (EAP-TLS client) support */
#define TM_DISABLE_EAPTLS_KEY_GEN         /* Export of EAP key material (MSK, EMSK, etc.) */
#define TM_DISABLE_EAPTLS_ID_PRIVACY      /* Identity privacy (2 successive TLS handshakes) */
 

EAP-TLS specific options you can set (see tfEapSetOption() for details):

TLS session id index 
(Required) This is the value returned by tfSslNewSession(). It defines the TLS parameters to be used (cipher suites, certificates and other TLS options).
TLS session id bytes 
From 0 to 32 random bytes supplied by the server during the TLS handshake and saved. The value may be used to shorten a subsequent TLS handshake with the same server if the server caches the session parameters. Set a zero-length value to disable the TLS resume feature, e.g. if you changed a session parameter since the last time you connected to the server.
User handshake process 
Defer processing of the TLS receive queue (see Deferring EAP-TLS processing of received TLS records below).
Identity privacy 
This feature allows client certificates to be sent encrypted (see Identity privacy in EAP-TLS below).
Key lengths 
The amount of EAP key material exported by the EAP-TLS can be overridden with these options. For example, your application may only require the Master Session Key (MSK) and, hence, set EMSK and IV lengths to zero.

EAP-TLS specific values you can retrieve (see tfEapGetOption() for details):

TLS session id index 
This is the value returned by tfSslNewSession() and set via tfEapSetOption().
TLS session id bytes 
From 0 to 32 random bytes supplied by the server during the TLS handshake and saved. You do not need to reload this value prior to the next connection attempt—the value saved from the previous TLS handshake will be used automatically.
Key values 
The EAP key material produced by the EAP-TLS method: MSK, EMSK, IV (see RFC 5216, section 2.3 and RFC 5247).
TLS identities 
The RFC 5216 specification discusses several values produced by the EAP-TLS method: peer and server identities (extracted from the peer and server certificates used in the TLS handshake) and session id (derived from the client and server nonces used in the TLS handshake, not the session id values mentioned above).
Timeout values 
(Authenticator only) The remaining retransmission downcount and interval can be read.

EAP-TLS specific functions:

tfEapTlsRegisterNotify() 
Register a function to receive EAP-TLS event notifications (see Deferring EAP-TLS processing of received TLS records below).
tfEapTlsProcessHandshake() 
Process TLS messages that are in the receive queue (see Deferring EAP-TLS processing of received TLS records below).

Deferring EAP-TLS processing of received TLS records

If you have a receive task that concurrently handles packet traffic unrelated to EAP-TLS, that traffic could be affected by the cryptographic processing that occurs when EAP-TLS packets are received. Normally, this isn't a problem but if it is you can defer this processing by doing the following after adding the interface:

  1. Register a callback function by calling tfEapTlsRegisterNotify().
  2. Enable option TM_EAPTLS_USER_PROCESS by calling tfEapSetOption().
  3. Open the interface.
  4. Your callback function will receive one or more TM_CB_SSL_HANDSHK_PROCESS events (signaled in the context of the receive task). Pass this signal on to a lower priority application task, however you do this for your operating system.
  5. When your application task receives the signal, call tfEapTlsProcessHandshake().

Key material exported by EAP-TLS

Besides authentication, the Treck EAP-TLS method can export key material for cryptographic protection. The specification for method-independent EAP cryptographic key material can be found in RFC 5247. How the key material is derived from the TLS master secret is specified in RFC 5216. Upon successful completion, the EAP-TLS method destroys all TLS cryptographic material but leaves all exported EAP key material available for the application to use.

If you have no need for this feature, you can reduce code size and execution time by defining the following compile time macro in trsystem.h:

#define TM_DISABLE_EAPTLS_KEY_GEN

The following material is exported, by default. You can retrieve the data via tfEapGetOption(). You can control the process via tfEapSetOption().

  • Master Session Key (MSK), which is split into:
    • Enc-RECV-Key (also known as MS-MPPE-Recv-Key or PMK)
    • Enc-SEND-Key (also known as MS-MPPE-Send-Key)
  • Extended Master Session Key (EMSK)
  • Initialization Vector (IV), which is split into:
    • RECV-IV
    • SEND-IV
  • Session-Id (derived from the TLS handshake nonces)
  • Peer-Id (extracted from the EAP Peer's certificate)
  • Server-Id (extracted from the EAP Authenticator's certificate)

Identity privacy in EAP-TLS

Peer identity privacy, described in the EAP-TLS specification (RFC 5216), is supported but disabled by default (for EAP Peer and Authenticator). The feature requires two consecutive TLS handshakes in which the client sends an empty certificate chain in the first (unencrypted) handshake. This relies on the server to initially accept the anonymous client then immediately send a Hello Request to start a second handshake (encrypted). The client must send it's credentials in the second round.

Note: Using this feature may cause the authentication to fail if the client cannot, or is not permitted to, send an empty certificate chain.

If you have no need for this feature, you can reduce code size by defining the following compile time macro in trsystem.h:

#define TM_DISABLE_EAPTLS_ID_PRIVACY

To enable this feature, you must set option TM_EAPTLS_PEER_PRIVACY via tfEapSetOption():

ttUserInterface myInterface;
int eaptlsOpt;
int errorCode;
  . . .
eaptlsOpt = 1;
errorCode = tfEapSetOption( myInterface,
                            TM_EAPTLS_PEER_PRIVACY,
                            (char *)&eaptlsOpt,
                            sizeof(eaptlsOpt) );
assert(errorCode == TM_ENOERROR);
 

Code examples to configure EAP-TLS

Configuring EAP-TLS.
Client example Server example
ttUserInterface myInterface;
int tlsSessionId;
int errorCode;
  . . .
/* Load PKI certificates (see PKI page) */
errorCode = tfUsePki();
assert(errorCode == TM_ENOERROR);
 
/* Trusted root CA certificates */
errorCode = tfPkiCertificateAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Client's public/private keys */
errorCode = tfPkiOwnKeyPairAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Client's signing certificate */
errorCode = tfPkiCertificateAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Create a TLS session (see SSL page) */
errorCode = tfUseSsl(...);
assert(errorCode == TM_ENOERROR);
 
tlsSessionId = tfSslNewSession(...);
assert(tlsSessionId >= 0);
 
/* TLS session id */
errorCode = tfEapSetOption( myInterface,
                            TM_EAPTLS_SESSION_INDEX,
                            (char *)&tlsSessionId,
                            sizeof(tlsSessionId) );
assert(errorCode == TM_ENOERROR);
 
/* Set any additional EAP-TLS options */
 
ttUserInterface myInterface;
int tlsSessionId;
ttUser8Bit eapOpt;
int errorCode;
  . . .
/* Load PKI certificates (see PKI page) */
errorCode = tfUsePki();
assert(errorCode == TM_ENOERROR);
 
/* Trusted root CA certificates */
errorCode = tfPkiCertificateAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Server's public/private keys */
errorCode = tfPkiOwnKeyPairAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Server's signing certificate */
errorCode = tfPkiCertificateAdd(...);
assert(errorCode == TM_ENOERROR);
 
/* Create a TLS session (see SSL page) */
errorCode = tfUseSsl(...);
assert(errorCode == TM_ENOERROR);
 
tlsSessionId = tfSslNewSession(...);
assert(tlsSessionId >= 0);
 
/* TLS session id */
errorCode = tfEapSetOption( myInterface,
                            TM_EAPTLS_SESSION_INDEX,
                            (char *)&tlsSessionId,
                            sizeof(tlsSessionId) );
assert(errorCode == TM_ENOERROR);
 
/* Request EAP-TLS exchange */
eapOpt = TM_EAP_TLS;
errorCode = tfEapSetOption( myInterface,
                            TM_EAP_USE_PROTO,
                            (char *)&eapOpt,
                            sizeof(eapOpt) );
assert(errorCode == TM_ENOERROR);
 
/* Set any additional EAP-TLS options */