27 RCSID(
"$Id: 54fc2fc14b4f150236754ff16f1b126543bc61e3 $")
30 #include <freeradius-devel/util/md5.h>
89 { .out = &
dict_eap_fast, .base_dir =
"eap/fast", .proto =
"eap-fast" },
208 uint8_t seed[2 * SSL3_RANDOM_SIZE];
212 SSL_get_server_random(s, seed, SSL3_RANDOM_SIZE);
213 SSL_get_client_random(s, &seed[SSL3_RANDOM_SIZE], SSL3_RANDOM_SIZE);
216 seed,
sizeof(seed),
secret, SSL_MAX_MASTER_KEY_LENGTH);
217 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
221 UNUSED STACK_OF(SSL_CIPHER) *peer_ciphers,
222 UNUSED SSL_CIPHER
const **cipher,
void *arg)
226 request_t *request = fr_tls_session_request(s);
227 fr_tls_session_t *tls_session = arg;
230 if (!tls_session)
return 0;
234 if (!t->
pac.key)
return 0;
236 RDEBUG2(
"processing PAC-Opaque");
256 fr_tls_session_t *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
257 request_t *request = fr_tls_session_request(s);
267 if (!tls_session)
return 0;
272 RDEBUG2(
"PAC provided via ClientHello SessionTicket extension");
276 errmsg =
"PAC is not of type Opaque";
278 RERROR(
"%s, sending alert to client", errmsg);
279 if (fr_tls_session_alert(request, tls_session, SSL3_AL_FATAL, SSL_AD_BAD_CERTIFICATE)) {
280 RERROR(
"too many alerts");
285 memset(&t->
pac, 0,
sizeof(t->
pac));
296 if (len -
sizeof(opaque->
hdr) < length) {
297 errmsg =
"PAC has bad length in header";
301 if (length <
PAC_A_ID_LENGTH + EVP_MAX_IV_LENGTH + EVP_GCM_TLS_TAG_LEN + 1) {
302 errmsg =
"PAC file too short";
307 errmsg =
"PAC has incorrect A_ID";
311 dlen = length -
sizeof(opaque->
aad) -
sizeof(opaque->
iv) -
sizeof(opaque->
tag);
316 errmsg =
"PAC failed to decrypt";
320 RHEXDUMP3((
uint8_t const *)&opaque_plaintext, plen,
"PAC-Opaque plaintext data section");
332 t->
pac.type =
vp->vp_uint16;
335 t->
pac.expires =
fr_time_add(request->packet->timestamp,
vp->vp_time_delta);
336 t->
pac.expired =
false;
349 errmsg =
"unknown TLV";
357 errmsg =
"PAC missing type TLV";
362 errmsg =
"PAC is of not of tunnel type";
367 errmsg =
"PAC missing lifetime TLV";
372 errmsg =
"PAC missing key TLV";
376 if (!SSL_set_session_secret_cb(tls_session->ssl,
_session_secret, tls_session)) {
377 RERROR(
"Failed setting SSL session secret callback");
388 fr_tls_session_t *tls_session = eap_tls_session->
tls_session;
396 switch (eap_tls_session->
state) {
405 fr_tls_session_send(request, tls_session);
435 RDEBUG2(
"Session established. Proceeding to decode tunneled attributes");
449 fr_tls_session_send(request, tls_session);
481 return fr_tls_cache_pending_push(request, tls_session);
531 fr_tls_session_t *tls_session;
536 eap_session->
tls =
true;
544 client_cert =
vp->vp_uint32 ?
true :
false;
546 client_cert =
inst->req_client_cert;
554 if (
inst->cipher_list) {
555 RDEBUG2(
"Over-riding main cipher list with '%s'",
inst->cipher_list);
557 if (!SSL_set_cipher_list(tls_session->ssl,
inst->cipher_list)) {
558 REDEBUG(
"Failed over-riding cipher list to '%s'. EAP-FAST will likely not work",
563 #ifdef SSL_OP_NO_TLSv1_2
567 SSL_set_options(tls_session->ssl, SSL_OP_NO_TLSv1_2);
585 &tls_session->clean_in, tls_session->clean_in.used,
586 tls_session->clean_in.used) < 0) {
591 tls_session->record_init(&tls_session->clean_in);
595 if (!SSL_set_session_ticket_ext_cb(tls_session->ssl,
_session_ticket, tls_session)) {
596 RERROR(
"Failed setting SSL session ticket callback");
608 t->
ssl_ctx = fr_tls_ctx_alloc(
inst->tls_conf,
false);
634 inst->virtual_server);
639 if (!
inst->default_provisioning_method) {
641 inst->default_provisioning_method_name);
651 if (!
inst->tls_conf) {
656 if (talloc_array_length(
inst->pac_opaque_key) - 1 != 32) {
665 if (
inst->tls_conf->tls_min_version > (
float) 1.1) {
678 talloc_array_length(
inst->authority_identity) - 1);
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
#define USES_APPLE_DEPRECATED_API
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_NOT_EMPTY
CONF_PAIR is required to have a non zero length value.
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
#define cf_log_err_by_child(_parent, _child, _fmt,...)
Log an error message against a specified child.
@ FR_RADIUS_CODE_ACCESS_CHALLENGE
RFC2865 - Access-Challenge.
@ FR_RADIUS_CODE_STATUS_CLIENT
RFC2865/RFC5997 - Status Server (response)
@ FR_RADIUS_CODE_ACCESS_ACCEPT
RFC2865 - Access-Accept.
@ FR_RADIUS_CODE_ACCESS_REJECT
RFC2865 - Access-Reject.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
CONF_SECTION *_CONST conf
Module's instance configuration.
eap_type_t eap_name2type(char const *name)
Return an EAP-Type for a particular name.
ssize_t eap_fast_decode_pair(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent, uint8_t const *data, size_t data_len, void *decode_ctx)
FIXME do something with mandatory.
void eap_fast_tlv_append(fr_tls_session_t *tls_session, fr_dict_attr_t const *tlv, bool mandatory, int length, void const *data)
fr_radius_packet_code_t eap_fast_process(request_t *request, eap_session_t *eap_session, fr_tls_session_t *tls_session)
Function declarations and packet structures.
struct eap_fast_tunnel_t::@150 pac
unsigned char aad[PAC_A_ID_LENGTH]
fr_time_delta_t pac_lifetime
#define EAP_FAST_TLV_TYPE
int default_provisioning_method
unsigned char iv[EVP_MAX_IV_LENGTH]
char const * virtual_server
eap_fast_pac_attr_hdr_t hdr
unsigned char tag[EVP_GCM_TLS_TAG_LEN]
char const * authority_identity
uint8_t data[sizeof(eap_fast_attr_pac_opaque_plaintext_t) *2]
@ EAP_FAST_TLS_SESSION_HANDSHAKE
uint8_t const * pac_opaque_key
int eap_fast_decrypt(uint8_t const *ciphertext, size_t ciphertext_len, uint8_t const *aad, size_t aad_len, uint8_t const *tag, uint8_t const *key, uint8_t const *iv, uint8_t *plaintext)
USES_APPLE_DEPRECATED_API void T_PRF(unsigned char const *secret, unsigned int secret_len, char const *prf_label, unsigned char const *seed, unsigned int seed_len, unsigned char *out, unsigned int out_len)
Crypto function declarations.
void * opaque
Opaque data used by EAP methods.
bool tls
Whether EAP method uses TLS.
module_method_t process
Callback that should be used to process the next round.
static eap_session_t * eap_session_get(request_t *request)
Tracks the progress of a single session of any EAP method.
#define RHEXDUMP3(_data, _len, _fmt,...)
#define MD5_DIGEST_LENGTH
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_OCTETS
Raw octets.
void fr_md5_calc(uint8_t out[static MD5_DIGEST_LENGTH], uint8_t const *in, size_t inlen)
Perform a single digest operation on a single input buffer.
void * thread
Thread specific instance data.
void * rctx
Resume ctx that a module previously set.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
void * thread
Thread instance data.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Temporary structure to hold arguments for thread_instantiation calls.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
static const conf_parser_t config[]
#define RETURN_MODULE_HANDLED
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
int stage
Processing stage.
fr_dict_attr_t const * attr_eap_fast_pac_a_id_info
fr_dict_attr_t const * attr_eap_fast_pac_lifetime
fr_dict_autoload_t rlm_eap_fast_dict[]
fr_dict_attr_t const * attr_eap_fast_pac_i_id
fr_dict_attr_t const * attr_user_password
fr_dict_attr_t const * attr_eap_fast_pac_type
static unlang_action_t mod_handshake_resume(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
fr_dict_attr_t const * attr_freeradius_proxied_to
fr_dict_attr_t const * attr_eap_fast_pac_opaque_tlv
char const * cipher_list
cipher list specific to EAP-FAST
fr_dict_attr_t const * attr_eap_fast_intermediate_result
fr_dict_attr_t const * attr_eap_message
fr_dict_attr_t const * attr_eap_type
fr_dict_attr_t const * attr_eap_msk
fr_dict_attr_t const * attr_eap_fast_pac_opaque_pac_key
static unlang_action_t mod_handshake_process(UNUSED rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
fr_dict_attr_t const * attr_eap_fast_pac_info_i_id
fr_dict_attr_t const * attr_eap_fast_pac_info_a_id_info
fr_dict_attr_t const * attr_eap_fast_pac_info_pac_lifetime
fr_dict_attr_autoload_t rlm_eap_fast_dict_attr[]
static fr_dict_t const * dict_freeradius
fr_dict_attr_t const * attr_eap_tls_require_client_cert
fr_dict_attr_t const * attr_eap_fast_pac_tlv
char const * tls_conf_name
Name of shared TLS config.
SSL_CTX * ssl_ctx
Thread local SSL_CTX.
fr_dict_attr_t const * attr_eap_fast_eap_payload
static fr_dict_t const * dict_radius
fr_dict_attr_t const * attr_ms_chap_challenge
fr_dict_attr_t const * attr_eap_fast_pac_key
fr_dict_attr_t const * attr_eap_fast_crypto_binding
rlm_eap_submodule_t rlm_eap_fast
static int _session_secret(SSL *s, void *secret, int *secret_len, UNUSED STACK_OF(SSL_CIPHER) *peer_ciphers, UNUSED SSL_CIPHER const **cipher, void *arg)
fr_dict_attr_t const * attr_eap_fast_pac_acknowledge
fr_time_delta_t pac_lifetime
seconds to add to current time to describe PAC lifetime
static void eap_fast_session_ticket(fr_tls_session_t *tls_session, const SSL *s, uint8_t *secret, int *secret_len)
char const * pac_opaque_key
The key used to encrypt PAC-Opaque.
fr_dict_attr_t const * attr_eap_fast_pac_info_tlv
fr_dict_attr_t const * attr_eap_emsk
char const * default_provisioning_method_name
fr_dict_attr_t const * attr_ms_mppe_send_key
fr_dict_attr_t const * attr_eap_fast_pac_info_a_id
char const * virtual_server
Virtual server to use for processing inner EAP method.
char const * authority_identity
The identity we present in the EAP-TLS.
fr_dict_t const * dict_eap_fast
int default_provisioning_method
fr_dict_attr_t const * attr_eap_fast_pac_info_pac_type
fr_dict_attr_t const * attr_eap_fast_pac_a_id
static int mod_thread_instantiate(module_thread_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_eap_fast_nak
fr_dict_attr_t const * attr_eap_fast_pac_opaque_pac_type
fr_dict_attr_t const * attr_eap_fast_error
fr_dict_attr_t const * attr_eap_fast_pac_opaque_pac_lifetime
fr_dict_attr_t const * attr_user_name
fr_dict_attr_t const * attr_proxy_to_realm
fr_dict_attr_t const * attr_ms_mppe_recv_key
static conf_parser_t submodule_config[]
fr_dict_attr_t const * attr_eap_fast_result
fr_tls_conf_t * tls_conf
TLS config pointer.
bool req_client_cert
Whether we require a client cert in the outer tunnel.
fr_dict_attr_t const * attr_eap_fast_pac_opaque_i_id
fr_dict_attr_t const * attr_ms_chap_peer_challenge
static int mod_thread_detach(module_thread_inst_ctx_t const *mctx)
fr_dict_attr_t const * attr_eap_fast_vendor_specific
static int mod_instantiate(module_inst_ctx_t const *mctx)
static eap_fast_tunnel_t * eap_fast_alloc(TALLOC_CTX *ctx, rlm_eap_fast_t const *inst)
Allocate the FAST per-session data.
static int _session_ticket(SSL *s, uint8_t const *data, int len, void *arg)
static unlang_action_t mod_session_init(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static int instantiate(module_inst_ctx_t const *mctx)
unlang_action_t unlang_module_yield(request_t *request, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
Yield a request back to the interpreter from within a module.
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
module_t common
Common fields provided by all modules.
Interface exported by EAP submodules.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define talloc_get_type_abort_const
#define fr_time_wrap(_time)
#define fr_time_delta_ispos(_a)
#define fr_time_eq(_a, _b)
#define fr_time_add(_a, _b)
Add a time/time delta together.
A time delta, a difference in time measured in nanoseconds.
int eap_tls_success(request_t *request, eap_session_t *eap_session, eap_tls_prf_label_t *prf_label)
Send an EAP-TLS success.
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.
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.
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.
int eap_tls_fail(request_t *request, eap_session_t *eap_session)
Send an EAP-TLS failure.
USES_APPLE_DEPRECATED_API fr_table_num_ordered_t const eap_tls_status_table[]
fr_tls_conf_t * eap_tls_conf_parse(CONF_SECTION *cs, char const *attr)
Parse TLS configuration.
unlang_action_t eap_tls_process(request_t *request, eap_session_t *eap_session)
Process an EAP TLS request.
int base_flags
Some protocols use the reserved bits of the EAP-TLS flags (such as PEAP).
eap_tls_status_t state
The state of the EAP-TLS session.
@ EAP_TLS_INVALID
Invalid, don't reply.
@ EAP_TLS_HANDLED
TLS code has handled it.
@ EAP_TLS_RECORD_RECV_COMPLETE
Received final fragment of a record.
@ EAP_TLS_START_SEND
We're starting a new TLS session.
@ EAP_TLS_FAIL
Fail, send fail.
@ EAP_TLS_ESTABLISHED
Session established, send success (or start phase2).
fr_tls_session_t * tls_session
TLS session used to authenticate peer or tunnel sensitive data.
Tracks the state of an EAP-TLS session.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
bool fr_pair_list_empty(fr_pair_list_t const *list)
Is a valuepair list empty.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
char const * fr_strerror(void)
Get the last library error.
CONF_SECTION * virtual_server_find(char const *name)
Return virtual server matching the specified name.