27 RCSID(
"$Id: 2b126812c0f442c6c6af6595d8ef55bc8b2d2350 $")
30 #include <freeradius-devel/util/md5.h>
90 { .out = &
dict_eap_fast, .base_dir =
"eap/fast", .proto =
"eap-fast" },
209 uint8_t seed[2 * SSL3_RANDOM_SIZE];
213 SSL_get_server_random(s, seed, SSL3_RANDOM_SIZE);
214 SSL_get_client_random(s, &seed[SSL3_RANDOM_SIZE], SSL3_RANDOM_SIZE);
217 seed,
sizeof(seed),
secret, SSL_MAX_MASTER_KEY_LENGTH);
218 *secret_len = SSL_MAX_MASTER_KEY_LENGTH;
222 UNUSED STACK_OF(SSL_CIPHER) *peer_ciphers,
223 UNUSED SSL_CIPHER
const **cipher,
void *arg)
227 request_t *request = fr_tls_session_request(s);
228 fr_tls_session_t *tls_session = arg;
231 if (!tls_session)
return 0;
235 if (!t->
pac.key)
return 0;
237 RDEBUG2(
"processing PAC-Opaque");
257 fr_tls_session_t *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
258 request_t *request = fr_tls_session_request(s);
268 if (!tls_session)
return 0;
273 RDEBUG2(
"PAC provided via ClientHello SessionTicket extension");
277 errmsg =
"PAC is not of type Opaque";
279 RERROR(
"%s, sending alert to client", errmsg);
280 if (fr_tls_session_alert(request, tls_session, SSL3_AL_FATAL, SSL_AD_BAD_CERTIFICATE)) {
281 RERROR(
"too many alerts");
286 memset(&t->
pac, 0,
sizeof(t->
pac));
297 if (len -
sizeof(opaque->
hdr) < length) {
298 errmsg =
"PAC has bad length in header";
302 if (length <
PAC_A_ID_LENGTH + EVP_MAX_IV_LENGTH + EVP_GCM_TLS_TAG_LEN + 1) {
303 errmsg =
"PAC file too short";
308 errmsg =
"PAC has incorrect A_ID";
312 dlen = length -
sizeof(opaque->
aad) -
sizeof(opaque->
iv) -
sizeof(opaque->
tag);
317 errmsg =
"PAC failed to decrypt";
321 RHEXDUMP3((
uint8_t const *)&opaque_plaintext, plen,
"PAC-Opaque plaintext data section");
333 t->
pac.type =
vp->vp_uint16;
336 t->
pac.expires =
fr_time_add(request->packet->timestamp,
vp->vp_time_delta);
337 t->
pac.expired =
false;
350 errmsg =
"unknown TLV";
358 errmsg =
"PAC missing type TLV";
363 errmsg =
"PAC is of not of tunnel type";
368 errmsg =
"PAC missing lifetime TLV";
373 errmsg =
"PAC missing key TLV";
377 if (!SSL_set_session_secret_cb(tls_session->ssl,
_session_secret, tls_session)) {
378 RERROR(
"Failed setting SSL session secret callback");
389 fr_tls_session_t *tls_session = eap_tls_session->
tls_session;
397 switch (eap_tls_session->
state) {
406 fr_tls_session_send(request, tls_session);
436 RDEBUG2(
"Session established. Proceeding to decode tunneled attributes");
450 fr_tls_session_send(request, tls_session);
482 return fr_tls_cache_pending_push(request, tls_session);
532 fr_tls_session_t *tls_session;
537 eap_session->
tls =
true;
545 client_cert =
vp->vp_uint32 ?
true :
false;
547 client_cert =
inst->req_client_cert;
555 if (
inst->cipher_list) {
556 RDEBUG2(
"Over-riding main cipher list with '%s'",
inst->cipher_list);
558 if (!SSL_set_cipher_list(tls_session->ssl,
inst->cipher_list)) {
559 REDEBUG(
"Failed over-riding cipher list to '%s'. EAP-FAST will likely not work",
564 #ifdef SSL_OP_NO_TLSv1_2
568 SSL_set_options(tls_session->ssl, SSL_OP_NO_TLSv1_2);
586 &tls_session->clean_in, tls_session->clean_in.used,
587 tls_session->clean_in.used) < 0) {
592 tls_session->record_init(&tls_session->clean_in);
596 if (!SSL_set_session_ticket_ext_cb(tls_session->ssl,
_session_ticket, tls_session)) {
597 RERROR(
"Failed setting SSL session ticket callback");
609 t->
ssl_ctx = fr_tls_ctx_alloc(
inst->tls_conf,
false);
634 if (!virtual_server) {
636 inst->virtual_server);
641 if (!
inst->server_cs) {
647 if (!
inst->default_provisioning_method) {
649 inst->default_provisioning_method_name);
659 if (!
inst->tls_conf) {
664 if (talloc_array_length(
inst->pac_opaque_key) - 1 != 32) {
673 if (
inst->tls_conf->tls_min_version > (
float) 1.1) {
686 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.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
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.
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]
eap_fast_pac_attr_hdr_t hdr
unsigned char tag[EVP_GCM_TLS_TAG_LEN]
char const * authority_identity
struct eap_fast_tunnel_t::@159 pac
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.
module_instance_t const * mi
Instance of the module being instantiated.
void * thread
Thread specific instance data.
void * rctx
Resume ctx that a module previously set.
void * thread
Thread instance data.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Instance of the module being instantiated.
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)
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
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_cs(virtual_server_t const *vs)
Return the configuration section for a virtual server.
virtual_server_t const * virtual_server_find(char const *name)
Return virtual server matching the specified name.