6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 * Copyright 2001 hereUare Communications, Inc. <raghud@hereuare.com>
21 * Copyright 2003 Alan DeKok <aland@freeradius.org>
22 * Copyright 2006 The FreeRADIUS server project
27 * TLS Packet Format in EAP
28 * --- ------ ------ -- ---
30 * 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
31 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
32 * | Code | Identifier | Length |
33 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34 * | Type | Flags | TLS Message Length
35 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36 * | TLS Message Length | TLS Data...
37 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42 USES_APPLE_DEPRECATED_API /* OpenSSL API has been deprecated by Apple */
48 * Send an initial eap-tls request to the peer.
50 * Frame eap reply packet.
51 * len = header + type + tls_typedata
52 * tls_typedata = flags(Start (S) bit set, and no data)
54 * Once having received the peer's Identity, the EAP server MUST
55 * respond with an EAP-TLS/Start packet, which is an
56 * EAP-Request packet with EAP-Type=EAP-TLS, the Start (S) bit
57 * set, and no data. The EAP-TLS conversation will then begin,
58 * with the peer sending an EAP-Response packet with
59 * EAP-Type = EAP-TLS. The data field of that packet will
62 * Fragment length is Framed-MTU - 4.
64 tls_session_t *eaptls_session(eap_handler_t *handler, fr_tls_server_conf_t *tls_conf, bool client_cert)
67 REQUEST *request = handler->request;
72 * Every new session is started only from EAP-TLS-START.
73 * Before Sending EAP-TLS-START, open a new SSL session.
74 * Create all the required data structures & store them
75 * in Opaque. So that we can use these data structures
76 * when we get the response
78 ssn = tls_new_session(handler, tls_conf, request, client_cert);
84 * Create a structure for all the items required to be
85 * verified for each client and set that as opaque data
88 * NOTE: If we want to set each item sepearately then
89 * this index should be global.
91 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_HANDLER, (void *)handler);
92 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_CONF, (void *)tls_conf);
93 SSL_set_ex_data(ssn->ssl, fr_tls_ex_index_certs, (void *)&(handler->certs));
94 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_IDENTITY, (void *)&(handler->identity));
95 #ifdef HAVE_OPENSSL_OCSP_H
96 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_STORE, (void *)tls_conf->ocsp_store);
98 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_SSN, (void *)ssn);
99 SSL_set_ex_data(ssn->ssl, FR_TLS_EX_INDEX_TALLOC, NULL);
101 return talloc_steal(handler, ssn); /* ssn */
105 The S flag is set only within the EAP-TLS start message
106 sent from the EAP server to the peer.
108 int eaptls_start(EAP_DS *eap_ds, int peap_flag)
112 reply.code = FR_TLS_START;
113 reply.length = TLS_HEADER_LEN + 1/*flags*/;
115 reply.flags = peap_flag;
116 reply.flags = SET_START(reply.flags);
121 eaptls_compose(eap_ds, &reply);
126 int eaptls_success(eap_handler_t *handler, int peap_flag)
129 REQUEST *request = handler->request;
130 tls_session_t *tls_session = handler->opaque;
132 handler->finished = true;
133 reply.code = FR_TLS_SUCCESS;
134 reply.length = TLS_HEADER_LEN;
135 reply.flags = peap_flag;
139 tls_success(tls_session, request);
142 * Call compose AFTER checking for cached data.
144 eaptls_compose(handler->eap_ds, &reply);
147 * Automatically generate MPPE keying material.
149 if (tls_session->prf_label) {
150 eaptls_gen_mppe_keys(handler->request,
151 tls_session->ssl, tls_session->prf_label);
153 RWDEBUG("Not adding MPPE keys because there is no PRF label");
156 eaptls_gen_eap_key(handler->request->reply, tls_session->ssl,
161 int eaptls_fail(eap_handler_t *handler, int peap_flag)
164 tls_session_t *tls_session = handler->opaque;
166 handler->finished = true;
167 reply.code = FR_TLS_FAIL;
168 reply.length = TLS_HEADER_LEN;
169 reply.flags = peap_flag;
173 tls_fail(tls_session);
175 eaptls_compose(handler->eap_ds, &reply);
181 A single TLS record may be up to 16384 octets in length, but a TLS
182 message may span multiple TLS records, and a TLS certificate message
183 may in principle be as long as 16MB.
187 * Frame the Dirty data that needs to be send to the client in an
188 * EAP-Request. We always embed the TLS-length in all EAP-TLS
189 * packets that we send, for easy reference purpose. Handle
190 * fragmentation and sending the next fragment etc.
192 int eaptls_request(EAP_DS *eap_ds, tls_session_t *ssn)
197 unsigned int lbit = 0;
199 /* This value determines whether we set (L)ength flag for
200 EVERY packet we send and add corresponding
201 "TLS Message Length" field.
204 This means we include L flag and "TLS Msg Len" in EVERY
208 This means we include L flag and "TLS Msg Len" **ONLY**
209 in First packet of a fragment series. We do not use
212 Having L flag in every packet is prefered.
215 if (ssn->length_flag) {
218 if (ssn->fragment == 0) {
219 ssn->tls_msg_len = ssn->dirty_out.used;
222 reply.code = FR_TLS_REQUEST;
223 reply.flags = ssn->peap_flag;
225 /* Send data, NOT more than the FRAGMENT size */
226 if (ssn->dirty_out.used > ssn->mtu) {
228 reply.flags = SET_MORE_FRAGMENTS(reply.flags);
229 /* Length MUST be included if it is the First Fragment */
230 if (ssn->fragment == 0) {
235 size = ssn->dirty_out.used;
239 reply.dlen = lbit + size;
240 reply.length = TLS_HEADER_LEN + 1/*flags*/ + reply.dlen;
242 reply.data = talloc_array(eap_ds, uint8_t, reply.length);
243 if (!reply.data) return 0;
246 nlen = htonl(ssn->tls_msg_len);
247 memcpy(reply.data, &nlen, lbit);
248 reply.flags = SET_LENGTH_INCLUDED(reply.flags);
250 (ssn->record_minus)(&ssn->dirty_out, reply.data + lbit, size);
252 eaptls_compose(eap_ds, &reply);
253 talloc_free(reply.data);
261 * Similarly, when the EAP server receives an EAP-Response with
262 * the M bit set, it MUST respond with an EAP-Request with
263 * EAP-Type=EAP-TLS and no data. This serves as a fragment ACK.
265 * In order to prevent errors in the processing of fragments, the
266 * EAP server MUST use increment the Identifier value for each
267 * fragment ACK contained within an EAP-Request, and the peer
268 * MUST include this Identifier value in the subsequent fragment
269 * contained within an EAP- Reponse.
271 * EAP server sends an ACK when it determines there are More
272 * fragments to receive to make the complete
273 * TLS-record/TLS-Message
275 static int eaptls_send_ack(eap_handler_t *handler, int peap_flag)
278 REQUEST *request = handler->request;
280 RDEBUG2("ACKing Peer's TLS record fragment");
281 reply.code = FR_TLS_ACK;
282 reply.length = TLS_HEADER_LEN + 1/*flags*/;
283 reply.flags = peap_flag;
287 eaptls_compose(handler->eap_ds, &reply);
293 * The S flag is set only within the EAP-TLS start message sent
294 * from the EAP server to the peer.
296 * Similarly, when the EAP server receives an EAP-Response with
297 * the M bit set, it MUST respond with an EAP-Request with
298 * EAP-Type=EAP-TLS and no data. This serves as a fragment
299 * ACK. The EAP peer MUST wait.
301 static fr_tls_status_t eaptls_verify(eap_handler_t *handler)
303 EAP_DS *eap_ds = handler->eap_ds;
304 tls_session_t *tls_session = handler->opaque;
305 EAP_DS *prev_eap_ds = handler->prev_eapds;
306 eaptls_packet_t *eaptls_packet, *eaptls_prev = NULL;
307 REQUEST *request = handler->request;
311 * We don't check ANY of the input parameters. It's all
312 * code which works together, so if something is wrong,
313 * we SHOULD core dump.
315 * e.g. if eap_ds is NULL, of if eap_ds->response is
316 * NULL, of if it's NOT an EAP-Response, or if the packet
317 * is too short. See eap_validation()., in ../../eap.c
319 * Also, eap_method_select() takes care of selecting the
320 * appropriate type, so we don't need to check
321 * eap_ds->response->type.num == PW_EAP_TLS, or anything
324 eaptls_packet = (eaptls_packet_t *)eap_ds->response->type.data;
325 if (prev_eap_ds && prev_eap_ds->response)
326 eaptls_prev = (eaptls_packet_t *)prev_eap_ds->response->type.data;
330 * First output the flags (for debugging)
332 RDEBUG3("Peer sent flags %c%c%c",
333 TLS_START(eaptls_packet->flags) ? 'S' : '-',
334 TLS_MORE_FRAGMENTS(eaptls_packet->flags) ? 'M' : '-',
335 TLS_LENGTH_INCLUDED(eaptls_packet->flags) ? 'L' : '-');
341 * If there's no TLS data, or there's 1 byte of TLS data,
342 * with the flags set to zero, then it's an ACK.
344 * Find if this is a reply to the previous request sent
346 if ((!eaptls_packet) ||
347 ((eap_ds->response->length == EAP_HEADER_LEN + 2) &&
348 ((eaptls_packet->flags & 0xc0) == 0x00))) {
350 if (prev_eap_ds && (prev_eap_ds->request->id == eap_ds->response->id)) {
351 return tls_ack_handler(handler->opaque, request);
353 REDEBUG("Received Invalid TLS ACK");
354 return FR_TLS_INVALID;
359 * We send TLS_START, but do not receive it.
361 if (TLS_START(eaptls_packet->flags)) {
362 REDEBUG("Peer sent EAP-TLS Start message (only the server is allowed to do this)");
363 return FR_TLS_INVALID;
367 * Calculate this fragment's length
369 frag_len = eap_ds->response->length -
370 (EAP_HEADER_LEN + (TLS_LENGTH_INCLUDED(eaptls_packet->flags) ? 6 : 2));
373 * The L bit (length included) is set to indicate the
374 * presence of the four octet TLS Message Length field,
375 * and MUST be set for the first fragment of a fragmented
376 * TLS message or set of messages.
378 * The M bit (more fragments) is set on all but the last
381 * The S bit (EAP-TLS start) is set in an EAP-TLS Start
382 * message. This differentiates the EAP-TLS Start message
383 * from a fragment acknowledgement.
385 if (TLS_LENGTH_INCLUDED(eaptls_packet->flags)) {
386 size_t total_len = eaptls_packet->data[2] * 256 | eaptls_packet->data[3];
388 if (frag_len > total_len) {
389 RWDEBUG("TLS fragment length (%zu bytes) greater than TLS record length (%zu bytes)", frag_len,
393 RDEBUG2("Peer indicated complete TLS record size will be %zu bytes", total_len);
394 if (TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
396 * The supplicant is free to send fragments of wildly varying
397 * lengths, but the vast majority won't.
399 * In this calculation we take into account the fact that the future
400 * fragments are likely to be 4 bytes larger than the initial one
401 * as they won't contain the length field.
403 if (frag_len + 4) { /* check for wrap, else clang scan gets excited */
404 RDEBUG2("Expecting %i TLS record fragments",
405 (int)((((total_len - frag_len) + ((frag_len + 4) - 1)) / (frag_len + 4)) + 1));
409 * FIRST_FRAGMENT is identified
410 * 1. If there is no previous EAP-response received.
411 * 2. If EAP-response received, then its M bit not set.
412 * (It is because Last fragment will not have M bit set)
414 if (!prev_eap_ds || (!prev_eap_ds->response) || (!eaptls_prev) ||
415 !TLS_MORE_FRAGMENTS(eaptls_prev->flags)) {
416 RDEBUG2("Got first TLS record fragment (%zu bytes). Peer indicated more fragments "
417 "to follow", frag_len);
418 tls_session->tls_record_in_total_len = total_len;
419 tls_session->tls_record_in_recvd_len = frag_len;
421 return FR_TLS_FIRST_FRAGMENT;
424 RDEBUG2("Got additional TLS record fragment with length (%zu bytes). "
425 "Peer indicated more fragments to follow", frag_len);
428 * Check we've not exceeded the originally indicated TLS record size.
430 tls_session->tls_record_in_recvd_len += frag_len;
431 if (tls_session->tls_record_in_recvd_len > tls_session->tls_record_in_total_len) {
432 RWDEBUG("Total received TLS record fragments (%zu bytes), exceeds "
433 "total TLS record length (%zu bytes)", frag_len, total_len);
436 return FR_TLS_MORE_FRAGMENTS_WITH_LENGTH;
440 * If it's a complete record, our fragment size should match the
441 * value of the four octet TLS length field.
443 if (total_len != frag_len) {
444 RWDEBUG("Peer indicated no more fragments, but TLS record length (%zu bytes) "
445 "does not match EAP-TLS data length (%zu bytes)", total_len, frag_len);
448 tls_session->tls_record_in_total_len = total_len;
449 tls_session->tls_record_in_recvd_len = frag_len;
450 RDEBUG2("Got complete TLS record (%zu bytes)", frag_len);
451 return FR_TLS_LENGTH_INCLUDED;
455 * The previous packet had the M flags set, but this one doesn't,
456 * this must be the final record fragment
458 if ((eaptls_prev && TLS_MORE_FRAGMENTS(eaptls_prev->flags)) && !TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
459 RDEBUG2("Got final TLS record fragment (%zu bytes)", frag_len);
460 tls_session->tls_record_in_recvd_len += frag_len;
461 if (tls_session->tls_record_in_recvd_len != tls_session->tls_record_in_total_len) {
462 RWDEBUG("Total received TLS record fragments (%zu bytes), does not equal indicated "
463 "TLS record length (%zu bytes)",
464 tls_session->tls_record_in_recvd_len, tls_session->tls_record_in_total_len);
468 if (TLS_MORE_FRAGMENTS(eaptls_packet->flags)) {
469 RDEBUG2("Got additional TLS record fragment (%zu bytes). Peer indicated more fragments to follow",
471 tls_session->tls_record_in_recvd_len += frag_len;
472 if (tls_session->tls_record_in_recvd_len > tls_session->tls_record_in_total_len) {
473 RWDEBUG("Total received TLS record fragments (%zu bytes), exceeds "
474 "indicated TLS record length (%zu bytes)",
475 tls_session->tls_record_in_recvd_len, tls_session->tls_record_in_total_len);
477 return FR_TLS_MORE_FRAGMENTS;
481 * None of the flags are set, but it's still a valid EAP-TLS packet.
490 * length = code + id + length + flags + tlsdata
491 * = 1 + 1 + 2 + 1 + X
492 * length = EAP-length - 1(EAP-Type = 1 octet)
493 * flags = EAP-typedata[0] (1 octet)
494 * dlen = EAP-typedata[1-4] (4 octets), if L flag set
495 * = length - 5(code+id+length+flags), otherwise
496 * data = EAP-typedata[5-n], if L flag set
497 * = EAP-typedata[1-n], otherwise
498 * packet = EAP-typedata (complete typedata)
500 * Points to consider during EAP-TLS data extraction
501 * 1. In the received packet, No data will be present incase of ACK-NAK
502 * 2. Incase if more fragments need to be received then ACK after retreiving this fragment.
504 * RFC 2716 Section 4.2. PPP EAP TLS Request Packet
507 * 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
508 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
509 * | Code | Identifier | Length |
510 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
511 * | Type | Flags | TLS Message Length
512 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
513 * | TLS Message Length | TLS Data...
514 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
516 * The Length field is two octets and indicates the length of the EAP
517 * packet including the Code, Identifir, Length, Type, and TLS data
520 static EAPTLS_PACKET *eaptls_extract(REQUEST *request, EAP_DS *eap_ds, fr_tls_status_t status)
522 EAPTLS_PACKET *tlspacket;
523 uint32_t data_len = 0;
525 uint8_t *data = NULL;
527 if (status == FR_TLS_INVALID) return NULL;
530 * The main EAP code & eaptls_verify() take care of
531 * ensuring that the packet is OK, and that we can
532 * extract the various fields we want.
534 * e.g. a TLS packet with zero data is allowed as an ACK,
535 * but we will never see it here, as we will simply
536 * send another fragment, instead of trying to extract
539 * MUST have TLS type octet, followed by flags, followed
542 assert(eap_ds->response->length > 2);
544 tlspacket = talloc(eap_ds, EAPTLS_PACKET);
545 if (!tlspacket) return NULL;
548 * Code & id for EAPTLS & EAP are same
549 * but eaptls_length = eap_length - 1(EAP-Type = 1 octet)
551 * length = code + id + length + type + tlsdata
552 * = 1 + 1 + 2 + 1 + X
554 tlspacket->code = eap_ds->response->code;
555 tlspacket->id = eap_ds->response->id;
556 tlspacket->length = eap_ds->response->length - 1; /* EAP type */
557 tlspacket->flags = eap_ds->response->type.data[0];
560 * A quick sanity check of the flags. If we've been told
561 * that there's a length, and there isn't one, then stop.
563 if (TLS_LENGTH_INCLUDED(tlspacket->flags) &&
564 (tlspacket->length < 5)) { /* flags + TLS message length */
565 REDEBUG("Invalid EAP-TLS packet received: Length bit is set, "
566 "but packet too short to contain length field");
567 talloc_free(tlspacket);
572 * If the final TLS packet is larger than we can handle, die
575 * Likewise, if the EAP packet says N bytes, and the TLS
576 * packet says there's fewer bytes, it's a problem.
578 if (TLS_LENGTH_INCLUDED(tlspacket->flags)) {
579 memcpy(&data_len, &eap_ds->response->type.data[1], 4);
580 data_len = ntohl(data_len);
581 if (data_len > MAX_RECORD_SIZE) {
582 REDEBUG("Reassembled TLS record will be %u bytes, "
583 "greater than our maximum record size (" STRINGIFY(MAX_RECORD_SIZE) " bytes)",
585 talloc_free(tlspacket);
592 * The TLS Message Length field is four octets, and
593 * provides the total length of the TLS message or set of
594 * messages that is being fragmented; this simplifies
597 * Dynamic allocation of buffers as & when we know the
598 * length should solve the problem.
600 case FR_TLS_FIRST_FRAGMENT:
601 case FR_TLS_LENGTH_INCLUDED:
602 case FR_TLS_MORE_FRAGMENTS_WITH_LENGTH:
603 if (tlspacket->length < 5) { /* flags + TLS message length */
604 REDEBUG("Invalid EAP-TLS packet received: Expected length, got none");
605 talloc_free(tlspacket);
610 * Extract all the TLS fragments from the
611 * previous eap_ds Start appending this
612 * fragment to the above ds
614 memcpy(&data_len, &eap_ds->response->type.data[1], sizeof(uint32_t));
615 data_len = ntohl(data_len);
616 data = (eap_ds->response->type.data + 5/*flags+TLS-Length*/);
617 len = eap_ds->response->type.length - 5/*flags+TLS-Length*/;
620 * Hmm... this should be an error, too.
622 if (data_len > len) {
628 * Data length is implicit, from the EAP header.
630 case FR_TLS_MORE_FRAGMENTS:
632 data_len = eap_ds->response->type.length - 1/*flags*/;
633 data = eap_ds->response->type.data + 1/*flags*/;
637 REDEBUG("Invalid EAP-TLS packet received");
638 talloc_free(tlspacket);
642 tlspacket->dlen = data_len;
644 tlspacket->data = talloc_array(tlspacket, uint8_t,
646 if (!tlspacket->data) {
647 talloc_free(tlspacket);
650 memcpy(tlspacket->data, data, data_len);
659 * To process the TLS,
661 * 1. EAP-TLS should get the compelete TLS data from the peer.
662 * 2. Store that data in a data structure with any other required info
663 * 3. Handle that data structure to the TLS module.
664 * 4. TLS module will perform its operations on the data and
665 * handle back to EAP-TLS
668 * 1. EAP-TLS if necessary will fragment it and send it to the
671 * During EAP-TLS initialization, TLS Context object will be
672 * initialized and stored. For every new authentication
673 * requests, TLS will open a new session object and that session
674 * object should be maintained even after the session is
675 * completed for session resumption. (Probably later as a feature
676 * as we donot know who maintains these session objects ie,
677 * SSL_CTX (internally) or TLS module(explicitly). If TLS module,
678 * then how to let SSL API know about these sessions.)
680 static fr_tls_status_t eaptls_operation(fr_tls_status_t status, eap_handler_t *handler)
682 REQUEST *request = handler->request;
683 tls_session_t *tls_session = handler->opaque;
685 if ((status == FR_TLS_MORE_FRAGMENTS) ||
686 (status == FR_TLS_MORE_FRAGMENTS_WITH_LENGTH) ||
687 (status == FR_TLS_FIRST_FRAGMENT)) {
691 eaptls_send_ack(handler, tls_session->peap_flag);
692 return FR_TLS_HANDLED;
697 * We have the complete TLS-data or TLS-message.
699 * Clean the dirty message.
701 * Authenticate the user and send
705 * is required then send another request.
707 if (!tls_handshake_recv(handler->request, tls_session)) {
708 REDEBUG("TLS receive handshake failed during operation");
709 tls_fail(tls_session);
714 * FIXME: return success/fail.
716 * TLS proper can decide what to do, then.
718 if (tls_session->dirty_out.used > 0) {
719 eaptls_request(handler->eap_ds, tls_session);
720 return FR_TLS_HANDLED;
724 * If there is no data to send i.e
725 * dirty_out.used <=0 and if the SSL
726 * handshake is finished, then return a
730 if (SSL_is_init_finished(tls_session->ssl)) {
732 * Init is finished. The rest is
735 tls_session->info.content_type = application_data;
736 return FR_TLS_SUCCESS;
740 * Who knows what happened...
742 REDEBUG("TLS failed during operation");
748 * In the actual authentication first verify the packet and then create the data structure
751 * To process the TLS,
753 * 1. EAP-TLS should get the compelete TLS data from the peer.
754 * 2. Store that data in a data structure with any other required info
755 * 3. Hand this data structure to the TLS module.
756 * 4. TLS module will perform its operations on the data and hands back to EAP-TLS
758 * 1. EAP-TLS if necessary will fragment it and send it to the destination.
760 * During EAP-TLS initialization, TLS Context object will be
761 * initialized and stored. For every new authentication
762 * requests, TLS will open a new session object and that
763 * session object SHOULD be maintained even after the session
764 * is completed, for session resumption. (Probably later as a
765 * feature, as we do not know who maintains these session
766 * objects ie, SSL_CTX (internally) or TLS module (explicitly). If
767 * TLS module, then how to let SSL API know about these
772 * Process an EAP request
774 fr_tls_status_t eaptls_process(eap_handler_t *handler)
776 tls_session_t *tls_session = (tls_session_t *) handler->opaque;
777 EAPTLS_PACKET *tlspacket;
778 fr_tls_status_t status;
779 REQUEST *request = handler->request;
781 if (!request) return FR_TLS_FAIL;
783 RDEBUG2("Continuing EAP-TLS");
785 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_REQUEST, request);
787 if (handler->certs) fr_pair_add(&request->packet->vps,
788 fr_pair_list_copy(request->packet, handler->certs));
791 * This case is when SSL generates Alert then we
792 * send that alert to the client and then send the EAP-Failure
794 status = eaptls_verify(handler);
795 if ((status == FR_TLS_INVALID) || (status == FR_TLS_FAIL)) {
796 REDEBUG("[eaptls verify] = %s", fr_int2str(fr_tls_status_table, status, "<INVALID>"));
798 RDEBUG2("[eaptls verify] = %s", fr_int2str(fr_tls_status_table, status, "<INVALID>"));
807 * Success means that we're done the initial
808 * handshake. For TTLS, this means send stuff
809 * back to the client, and the client sends us
810 * more tunneled data.
816 * Normal TLS request, continue with the "get rest
817 * of fragments" phase.
820 eaptls_request(handler->eap_ds, tls_session);
821 status = FR_TLS_HANDLED;
825 * The handshake is done, and we're in the "tunnel
829 RDEBUG2("Done initial handshake");
832 * Get the rest of the fragments.
834 case FR_TLS_FIRST_FRAGMENT:
835 case FR_TLS_MORE_FRAGMENTS:
836 case FR_TLS_LENGTH_INCLUDED:
837 case FR_TLS_MORE_FRAGMENTS_WITH_LENGTH:
842 * Extract the TLS packet from the buffer.
844 if ((tlspacket = eaptls_extract(request, handler->eap_ds, status)) == NULL) {
845 status = FR_TLS_FAIL;
850 * Get the session struct from the handler
852 * update the dirty_in buffer
854 * NOTE: This buffer will contain partial data when M bit is set.
856 * CAUTION while reinitializing this buffer, it should be
857 * reinitialized only when this M bit is NOT set.
859 if (tlspacket->dlen !=
860 (tls_session->record_plus)(&tls_session->dirty_in, tlspacket->data, tlspacket->dlen)) {
861 talloc_free(tlspacket);
862 REDEBUG("Exceeded maximum record size");
863 status = FR_TLS_FAIL;
870 talloc_free(tlspacket);
873 * SSL initalization is done. Return.
875 * The TLS data will be in the tls_session structure.
877 if (SSL_is_init_finished(tls_session->ssl)) {
879 * The initialization may be finished, but if
880 * there more fragments coming, then send ACK,
881 * and get the caller to continue the
884 if ((status == FR_TLS_MORE_FRAGMENTS) ||
885 (status == FR_TLS_MORE_FRAGMENTS_WITH_LENGTH) ||
886 (status == FR_TLS_FIRST_FRAGMENT)) {
890 eaptls_send_ack(handler, tls_session->peap_flag);
891 RDEBUG2("Init is done, but tunneled data is fragmented");
892 status = FR_TLS_HANDLED;
896 status = tls_application_data(tls_session, request);
901 * Continue the handshake.
903 status = eaptls_operation(status, handler);
904 if (status == FR_TLS_SUCCESS) {
905 #define MAX_SESSION_SIZE (256)
907 char buffer[2 * MAX_SESSION_SIZE + 1];
910 * Restore the cached VPs before processing the
913 tls_session_id(tls_session->ssl_session, buffer, MAX_SESSION_SIZE);
915 vps = SSL_SESSION_get_ex_data(tls_session->ssl_session, fr_tls_ex_index_vps);
917 RWDEBUG("No information in cached session %s", buffer);
922 RDEBUG("Adding cached attributes from session %s", buffer);
925 * The cbtls_get_session() function doesn't have
926 * access to sock->certs or handler->certs, which
927 * is where the certificates normally live. So
928 * the certs are all in the VPS list here, and
929 * have to be manually extracted.
932 for (vp = fr_cursor_init(&cursor, &vps);
934 vp = fr_cursor_next(&cursor)) {
936 * TLS-* attrs get added back to
939 if ((vp->da->vendor == 0) &&
940 (vp->da->attr >= PW_TLS_CERT_SERIAL) &&
941 (vp->da->attr <= PW_TLS_CLIENT_CERT_SUBJECT_ALT_NAME_UPN)) {
943 * Certs already exist. Don't re-add them.
945 if (!handler->certs) {
946 rdebug_pair(L_DBG_LVL_2, request, vp, "request:");
947 fr_pair_add(&request->packet->vps, fr_pair_copy(request->packet, vp));
950 rdebug_pair(L_DBG_LVL_2, request, vp, "reply:");
951 fr_pair_add(&request->reply->vps, fr_pair_copy(request->reply, vp));
959 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_REQUEST, NULL);
966 * compose the TLS reply packet in the EAP reply typedata
968 int eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply)
973 * Don't set eap_ds->request->type.num, as the main EAP
974 * handler will do that for us. This allows the TLS
975 * module to be called from TTLS & PEAP.
979 * When the EAP server receives an EAP-Response with the
980 * M bit set, it MUST respond with an EAP-Request with
981 * EAP-Type=EAP-TLS and no data. This serves as a
982 * fragment ACK. The EAP peer MUST wait until it receives
983 * the EAP-Request before sending another fragment.
985 * In order to prevent errors in the processing of
986 * fragments, the EAP server MUST use increment the
987 * Identifier value for each fragment ACK contained
988 * within an EAP-Request, and the peer MUST include this
989 * Identifier value in the subsequent fragment contained
990 * within an EAP- Reponse.
992 eap_ds->request->type.data = talloc_array(eap_ds->request, uint8_t,
993 reply->length - TLS_HEADER_LEN + 1);
994 if (!eap_ds->request->type.data) return 0;
996 /* EAPTLS Header length is excluded while computing EAP typelen */
997 eap_ds->request->type.length = reply->length - TLS_HEADER_LEN;
999 ptr = eap_ds->request->type.data;
1000 *ptr++ = (uint8_t)(reply->flags & 0xFF);
1002 if (reply->dlen) memcpy(ptr, reply->data, reply->dlen);
1004 switch (reply->code) {
1007 case FR_TLS_REQUEST:
1008 eap_ds->request->code = PW_EAP_REQUEST;
1011 case FR_TLS_SUCCESS:
1012 eap_ds->request->code = PW_EAP_SUCCESS;
1016 eap_ds->request->code = PW_EAP_FAILURE;
1020 /* Should never enter here */
1029 * Parse TLS configuration
1031 * If the option given by 'attr' is set, we find the config section
1032 * of that name and use that for the TLS configuration. If not, we
1033 * fall back to compatibility mode and read the TLS options from
1034 * the 'tls' section.
1036 fr_tls_server_conf_t *eaptls_conf_parse(CONF_SECTION *cs, char const *attr)
1038 char const *tls_conf_name;
1040 CONF_SECTION *parent;
1041 CONF_SECTION *tls_cs;
1042 fr_tls_server_conf_t *tls_conf;
1047 rad_assert(attr != NULL);
1049 parent = cf_item_parent(cf_section_to_item(cs));
1051 cp = cf_pair_find(cs, attr);
1053 tls_conf_name = cf_pair_value(cp);
1055 tls_cs = cf_section_sub_find_name2(parent, TLS_CONFIG_SECTION, tls_conf_name);
1058 ERROR("Cannot find tls config \"%s\"", tls_conf_name);
1063 * If we can't find the section given by the 'attr', we
1064 * fall-back to looking for the "tls" section, as in
1065 * previous versions.
1067 * We don't fall back if the 'attr' is specified, but we can't
1068 * find the section - that is just a config error.
1070 INFO("TLS section \"%s\" missing, trying to use legacy configuration", attr);
1071 tls_cs = cf_section_sub_find(parent, "tls");
1077 tls_conf = tls_server_conf_parse(tls_cs);
1083 * The EAP RFC's say 1020, but we're less picky.
1085 if (tls_conf->fragment_size < 100) {
1086 ERROR("Configured fragment size is too small, must be >= 100");
1091 * The maximum size for a RADIUS packet is 4096,
1092 * minus the header (20), Message-Authenticator (18),
1093 * and State (18), etc. results in about 4000 bytes of data
1094 * that can be devoted *solely* to EAP.
1096 if (tls_conf->fragment_size > 4000) {
1097 ERROR("Configured fragment size is too large, must be <= 4000");
1102 * Account for the EAP header (4), and the EAP-TLS header
1103 * (6), as per Section 4.2 of RFC 2716. What's left is
1104 * the maximum amount of data we read from a TLS buffer.
1106 tls_conf->fragment_size -= 10;