The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
session.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: d478a046cde294d71360cae5cc42e4e7f2ce5192 $
19 *
20 * @file tls/session.c
21 * @brief Initialise OpenSSL sessions, and read/write data to/from them.
22 *
23 * @copyright 2001 hereUare Communications, Inc. (raghud@hereuare.com)
24 * @copyright 2003 Alan DeKok (aland@freeradius.org)
25 * @copyright 2006-2016 The FreeRADIUS server project
26 */
27#ifdef WITH_TLS
28#define LOG_PREFIX "tls"
29
30#include <freeradius-devel/server/pair.h>
31#include <freeradius-devel/server/log.h>
32
33#include <freeradius-devel/util/debug.h>
34#include <freeradius-devel/util/base16.h>
35#include <freeradius-devel/util/misc.h>
36#include <freeradius-devel/util/pair_legacy.h>
37
38#include <freeradius-devel/protocol/freeradius/freeradius.internal.h>
39
40#include <freeradius-devel/unlang/call.h>
41#include <freeradius-devel/unlang/subrequest.h>
42#include <freeradius-devel/unlang/interpret.h>
43
44#include <sys/stat.h>
45#include <ctype.h>
46#include <fcntl.h>
47
48#include "attrs.h"
49#include "base.h"
50#include "log.h"
51
52#include <openssl/x509v3.h>
53#include <openssl/ssl.h>
54
55static char const *tls_version_str[] = {
56 [SSL2_VERSION] = "SSL 2.0",
57 [SSL3_VERSION] = "SSL 3.0",
58 [TLS1_VERSION] = "TLS 1.0",
59#ifdef TLS1_1_VERSION
60 [TLS1_1_VERSION] = "TLS 1.1",
61#endif
62#ifdef TLS1_2_VERSION
63 [TLS1_2_VERSION] = "TLS 1.2",
64#endif
65#ifdef TLS1_3_VERSION
66 [TLS1_3_VERSION] = "TLS 1.3",
67#endif
68#ifdef TLS1_4_VERSION
69 [TLS1_4_VERSION] = "TLS 1.4",
70#endif
71};
72
73static char const *tls_content_type_str[] = {
74 [SSL3_RT_CHANGE_CIPHER_SPEC] = "change_cipher_spec",
75 [SSL3_RT_ALERT] = "alert",
76 [SSL3_RT_HANDSHAKE] = "handshake",
77 [SSL3_RT_APPLICATION_DATA] = "application_data",
78#ifdef SSL3_RT_HEADER
79 [SSL3_RT_HEADER] = "header",
80#endif
81#ifdef SSL3_RT_INNER_CONTENT_TYPE
82 [SSL3_RT_INNER_CONTENT_TYPE] = "inner_content_type",
83#endif
84};
85
86static char const *tls_alert_description_str[] = {
87 [SSL3_AD_CLOSE_NOTIFY] = "close_notify",
88 [SSL3_AD_UNEXPECTED_MESSAGE] = "unexpected_message",
89 [SSL3_AD_BAD_RECORD_MAC] = "bad_record_mac",
90 [TLS1_AD_DECRYPTION_FAILED] = "decryption_failed",
91 [TLS1_AD_RECORD_OVERFLOW] = "record_overflow",
92 [SSL3_AD_DECOMPRESSION_FAILURE] = "decompression_failure",
93 [SSL3_AD_HANDSHAKE_FAILURE] = "handshake_failure",
94 [SSL3_AD_BAD_CERTIFICATE] = "bad_certificate",
95 [SSL3_AD_UNSUPPORTED_CERTIFICATE] = "unsupported_certificate",
96 [SSL3_AD_CERTIFICATE_REVOKED] = "certificate_revoked",
97 [SSL3_AD_CERTIFICATE_EXPIRED] = "certificate_expired",
98 [SSL3_AD_CERTIFICATE_UNKNOWN] = "certificate_unknown",
99 [SSL3_AD_ILLEGAL_PARAMETER] = "illegal_parameter",
100 [TLS1_AD_UNKNOWN_CA] = "unknown_ca",
101 [TLS1_AD_ACCESS_DENIED] = "access_denied",
102 [TLS1_AD_DECODE_ERROR] = "decode_error",
103 [TLS1_AD_DECRYPT_ERROR] = "decrypt_error",
104 [TLS1_AD_EXPORT_RESTRICTION] = "export_restriction",
105 [TLS1_AD_PROTOCOL_VERSION] = "protocol_version",
106 [TLS1_AD_INSUFFICIENT_SECURITY] = "insufficient_security",
107 [TLS1_AD_INTERNAL_ERROR] = "internal_error",
108 [TLS1_AD_USER_CANCELLED] = "user_cancelled",
109 [TLS1_AD_NO_RENEGOTIATION] = "no_renegotiation",
110#ifdef TLS13_AD_MISSING_EXTENSION
111 [TLS13_AD_MISSING_EXTENSION] = "missing_extension",
112#endif
113#ifdef TLS13_AD_CERTIFICATE_REQUIRED
114 [TLS13_AD_CERTIFICATE_REQUIRED] = "certificate_required",
115#endif
116#ifdef TLS1_AD_UNSUPPORTED_EXTENSION
117 [TLS1_AD_UNSUPPORTED_EXTENSION] = "unsupported_extension",
118#endif
119#ifdef TLS1_AD_CERTIFICATE_UNOBTAINABLE
120 [TLS1_AD_CERTIFICATE_UNOBTAINABLE] = "certificate_unobtainable",
121#endif
122#ifdef TLS1_AD_UNRECOGNIZED_NAME
123 [TLS1_AD_UNRECOGNIZED_NAME] = "unrecognised_name",
124#endif
125#ifdef TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
126 [TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE] = "bad_certificate_status_response",
127#endif
128#ifdef TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
129 [TLS1_AD_BAD_CERTIFICATE_HASH_VALUE] = "bad_certificate_hash_value",
130#endif
131#ifdef TLS1_AD_UNKNOWN_PSK_IDENTITY
132 [TLS1_AD_UNKNOWN_PSK_IDENTITY] = "unknown_psk_identity",
133#endif
134#ifdef TLS1_AD_NO_APPLICATION_PROTOCOL
135 [TLS1_AD_NO_APPLICATION_PROTOCOL] = "no_application_protocol",
136#endif
137};
138
139static char const *tls_handshake_type_str[] = {
140 [SSL3_MT_HELLO_REQUEST] = "hello_request",
141 [SSL3_MT_CLIENT_HELLO] = "client_hello",
142 [SSL3_MT_SERVER_HELLO] = "server_hello",
143#ifdef SSL3_MT_NEWSESSION_TICKET
144 [SSL3_MT_NEWSESSION_TICKET] = "new_session_ticket",
145#endif
146#ifdef SSL3_MT_END_OF_EARLY_DATA
147 [SSL3_MT_END_OF_EARLY_DATA] = "end_of_early_data",
148#endif
149#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS
150 [SSL3_MT_ENCRYPTED_EXTENSIONS] = "encrypted_extensions",
151#endif
152 [SSL3_MT_CERTIFICATE] = "certificate",
153 [SSL3_MT_SERVER_KEY_EXCHANGE] = "server_key_exchange",
154 [SSL3_MT_CERTIFICATE_REQUEST] = "certificate_request",
155 [SSL3_MT_SERVER_DONE] = "server_hello_done",
156 [SSL3_MT_CERTIFICATE_VERIFY] = "certificate_verify",
157 [SSL3_MT_CLIENT_KEY_EXCHANGE] = "client_key_exchange",
158 [SSL3_MT_FINISHED] = "finished",
159#ifdef SSL3_MT_CERTIFICATE_URL
160 [SSL3_MT_CERTIFICATE_URL] = "certificate_url",
161#endif
162#ifdef SSL3_MT_CERTIFICATE_STATUS
163 [SSL3_MT_CERTIFICATE_STATUS] = "certificate_status",
164#endif
165#ifdef SSL3_MT_SUPPLEMENTAL_DATA
166 [SSL3_MT_SUPPLEMENTAL_DATA] = "supplemental_data",
167#endif
168#ifdef SSL3_MT_KEY_UPDATE
169 [SSL3_MT_KEY_UPDATE] = "key_update",
170#endif
171#ifdef SSL3_MT_NEXT_PROTO
172 [SSL3_MT_NEXT_PROTO] = "next_proto",
173#endif
174#ifdef SSL3_MT_MESSAGE_HASH
175 [SSL3_MT_MESSAGE_HASH] = "message_hash",
176#endif
177#ifdef DTLS1_MT_HELLO_VERIFY_REQUEST
178 [DTLS1_MT_HELLO_VERIFY_REQUEST] = "hello_verify_request",
179#endif
180#ifdef SSL3_MT_CHANGE_CIPHER_SPEC
181 [SSL3_MT_CHANGE_CIPHER_SPEC] = "change_cipher_spec",
182#endif
183};
184
185/** Clear a record buffer
186 *
187 * @param record buffer to clear.
188 */
189inline static void record_init(fr_tls_record_t *record)
190{
191 record->used = 0;
192}
193
194/** Destroy a record buffer
195 *
196 * @param record buffer to destroy clear.
197 */
198inline static void record_close(fr_tls_record_t *record)
199{
200 record->used = 0;
201}
202
203/** Copy data to the intermediate buffer, before we send it somewhere
204 *
205 * @param[in] record buffer to write to.
206 * @param[in] in data to write.
207 * @param[in] inlen Length of data to write.
208 * @return the amount of data written to the record buffer.
209 */
210inline static unsigned int record_from_buff(fr_tls_record_t *record, void const *in, unsigned int inlen)
211{
212 unsigned int added = FR_TLS_MAX_RECORD_SIZE - record->used;
213
214 if (added > inlen) added = inlen;
215 if (added == 0) return 0;
216
217 memcpy(record->data + record->used, in, added);
218 record->used += added;
219
220 return added;
221}
222
223/** Take data from the buffer, and give it to the caller
224 *
225 * @param[in] record buffer to read from.
226 * @param[out] out where to write data from record buffer.
227 * @param[in] outlen The length of the output buffer.
228 * @return the amount of data written to the output buffer.
229 */
230inline static unsigned int record_to_buff(fr_tls_record_t *record, void *out, unsigned int outlen)
231{
232 unsigned int taken = record->used;
233
234 if (taken > outlen) taken = outlen;
235 if (taken == 0) return 0;
236 if (out) memcpy(out, record->data, taken);
237
238 record->used -= taken;
239
240 /*
241 * This is pretty bad...
242 */
243 if (record->used > 0) memmove(record->data, record->data + taken, record->used);
244
245 return taken;
246}
247
248/** Return the static private key password we have configured
249 *
250 * @param[out] buf Where to write the password to.
251 * @param[in] size The length of buf.
252 * @param[in] rwflag
253 * - 0 if password used for decryption.
254 * - 1 if password used for encryption.
255 * @param[in] u The static password.
256 * @return
257 * - 0 on error.
258 * - >0 on success (the length of the password).
259 */
260int fr_tls_session_password_cb(char *buf, int size, int rwflag UNUSED, void *u)
261{
262 size_t len;
263
264 /*
265 * We do this instead of not registering the callback
266 * to ensure OpenSSL doesn't try and read a password
267 * from stdin (causes server to block).
268 */
269 if (!u) {
270 ERROR("Private key encrypted but no private_key_password configured");
271 return 0;
272 }
273
274 len = strlcpy(buf, (char *)u, size);
275 if (len > (size_t)size) {
276 ERROR("Password too long. Maximum length is %i bytes", size - 1);
277 return 0;
278 }
279
280 return len;
281}
282
283#ifdef PSK_MAX_IDENTITY_LEN
284/** Verify the PSK identity contains no reserved chars
285 *
286 * @param identity to check.
287 * @return
288 * - true identity does not contain reserved chars.
289 * - false identity contains reserved chars.
290 */
291static bool session_psk_identity_is_safe(const char *identity)
292{
293 char c;
294
295 if (!identity) return true;
296
297 while ((c = *(identity++)) != '\0') {
298 if (isalpha((uint8_t) c) || isdigit((uint8_t) c) || isspace((uint8_t) c) ||
299 (c == '@') || (c == '-') || (c == '_') || (c == '.')) {
300 continue;
301 }
302
303 return false;
304 }
305
306 return true;
307}
308
309/** Determine the PSK to use for an outgoing connection
310 *
311 * @param[in] ssl session.
312 * @param[in] identity The identity of the PSK to search for.
313 * @param[out] psk Where to write the PSK we found (if any).
314 * @param[in] max_psk_len The length of the buffer provided for PSK.
315 * @return
316 * - 0 if no PSK matching identity was found.
317 * - >0 if a PSK matching identity was found (the length of bytes written to psk).
318 */
319unsigned int fr_tls_session_psk_client_cb(SSL *ssl, UNUSED char const *hint,
320 char *identity, unsigned int max_identity_len,
321 unsigned char *psk, unsigned int max_psk_len)
322{
323 unsigned int psk_len;
324 fr_tls_conf_t *conf;
325
326 conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
327 if (!conf) return 0;
328
329 psk_len = strlen(conf->psk_password);
330 if (psk_len > (2 * max_psk_len)) return 0;
331
332 strlcpy(identity, conf->psk_identity, max_identity_len);
333
334 return fr_base16_decode(NULL,
335 &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
336 &FR_SBUFF_IN(conf->psk_password, (size_t)psk_len), false);
337}
338
339/** Determine the PSK to use for an incoming connection
340 *
341 * @param[in] ssl session.
342 * @param[in] identity The identity of the PSK to search for.
343 * @param[out] psk Where to write the PSK we found (if any).
344 * @param[in] max_psk_len The length of the buffer provided for PSK.
345 * @return
346 * - 0 if no PSK matching identity was found.
347 * - >0 if a PSK matching identity was found (the length of bytes written to psk).
348 */
349unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity,
350 unsigned char *psk, unsigned int max_psk_len)
351{
352 size_t psk_len = 0;
353 fr_tls_conf_t *conf;
354 request_t *request;
355
356 conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
357 if (!conf) return 0;
358
359 request = fr_tls_session_request(ssl);
360 if (request && conf->psk_query) {
361 size_t hex_len;
362 fr_pair_t *vp;
363 char buffer[2 * PSK_MAX_PSK_LEN + 4]; /* allow for too-long keys */
364
365 /*
366 * The passed identity is weird. Deny it.
367 */
368 if (!session_psk_identity_is_safe(identity)) {
369 RWDEBUG("Invalid characters in PSK identity %s", identity);
370 return 0;
371 }
372
374 if (fr_pair_value_from_str(vp, identity, strlen(identity), NULL, true) < 0) {
375 RPWDEBUG2("Failed parsing TLS PSK Identity");
377 return 0;
378 }
379
380 hex_len = xlat_eval(buffer, sizeof(buffer), request, conf->psk_query, NULL, NULL);
381 if (!hex_len) {
382 RWDEBUG("PSK expansion returned an empty string.");
383 return 0;
384 }
385
386 /*
387 * The returned key is truncated at MORE than
388 * OpenSSL can handle. That way we can detect
389 * the truncation, and complain about it.
390 */
391 if (hex_len > (2 * max_psk_len)) {
392 RWDEBUG("Returned PSK is too long (%u > %u)", (unsigned int) hex_len, 2 * max_psk_len);
393 return 0;
394 }
395
396 /*
397 * Leave the TLS-PSK-Identity in the request, and
398 * convert the expansion from printable string
399 * back to hex.
400 */
401 return fr_base16_decode(NULL,
402 &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
403 &FR_SBUFF_IN(buffer, hex_len), false);
404 }
405
406 if (!conf->psk_identity) {
407 DEBUG("No static PSK identity set. Rejecting the user");
408 return 0;
409 }
410
411 /*
412 * No request_t, or no dynamic query. Just look for a
413 * static identity.
414 */
415 if (strcmp(identity, conf->psk_identity) != 0) {
416 ERROR("Supplied PSK identity %s does not match configuration. Rejecting.",
417 identity);
418 return 0;
419 }
420
421 psk_len = strlen(conf->psk_password);
422 if (psk_len > (2 * max_psk_len)) return 0;
423
424 return fr_base16_decode(NULL,
425 &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
426 &FR_SBUFF_IN(conf->psk_password, psk_len), false);
427}
428#endif /* PSK_MAX_IDENTITY_LEN */
429
431DIAG_OFF(used-but-marked-unused) /* Fix spurious warnings for sk_ macros */
432/** Record session state changes
433 *
434 * Called by OpenSSL whenever the session state changes, an alert is received or an error occurs.
435 *
436 * @param[in] ssl session.
437 * @param[in] where Which context the callback is being called in.
438 * See https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_info_callback.html
439 * for additional info.
440 * @param[in] ret 0 if an error occurred, or the alert type if an alert was received.
441 */
442void fr_tls_session_info_cb(SSL const *ssl, int where, int ret)
443{
444 char const *role, *state;
445 request_t *request = SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_REQUEST);
446
447 if ((where & ~SSL_ST_MASK) & SSL_ST_CONNECT) {
448 role = "Client ";
449 } else if (((where & ~SSL_ST_MASK)) & SSL_ST_ACCEPT) {
450 role = "Server ";
451 } else {
452 role = "";
453 }
454
455 state = SSL_state_string_long(ssl);
456 state = state ? state : "<INVALID>";
457
458 if ((where & SSL_CB_LOOP) || (where & SSL_CB_HANDSHAKE_START) || (where & SSL_CB_HANDSHAKE_DONE)) {
460 char const *abbrv = SSL_state_string(ssl);
461 size_t len;
462
463 /*
464 * Trim crappy OpenSSL state strings...
465 */
466 len = strlen(abbrv);
467 if ((len > 1) && (abbrv[len - 1] == ' ')) len--;
468
469 ROPTIONAL(RDEBUG3, DEBUG3, "Handshake state [%.*s] - %s%s", (int)len, abbrv, role, state);
470
471#ifdef OPENSSL_NO_SSL_TRACE
472 {
473 STACK_OF(SSL_CIPHER) *server_ciphers;
474 STACK_OF(SSL_CIPHER) *client_ciphers;
475
476 /*
477 * After a ClientHello, list all the proposed ciphers
478 * from the client.
479 *
480 * Only do this if we don't have SSL_trace() as
481 * SSL_trace() prints this information and we don't
482 * want to duplicate it.
483 */
484 if (SSL_get_state(ssl) == TLS_ST_SR_CLNT_HELLO &&
485 (client_ciphers = SSL_get_client_ciphers(ssl))) {
486 int i;
487 int num_ciphers;
488 const SSL_CIPHER *this_cipher;
489
490 server_ciphers = SSL_get_ciphers(ssl);
491 /*
492 * These are printed on startup, so not usually
493 * required.
494 */
495 ROPTIONAL(RDEBUG4, DEBUG4, "Our preferred ciphers (by priority)");
497 if (request) RINDENT();
498 num_ciphers = sk_SSL_CIPHER_num(server_ciphers);
499 for (i = 0; i < num_ciphers; i++) {
500 this_cipher = sk_SSL_CIPHER_value(server_ciphers, i);
501 ROPTIONAL(RDEBUG4, DEBUG4, "[%i] %s", i, SSL_CIPHER_get_name(this_cipher));
502 }
503 if (request) REXDENT();
504 }
505
506 /*
507 * Print information about the client's
508 * handshake message.
509 */
511 ROPTIONAL(RDEBUG3, DEBUG3, "Client's preferred ciphers (by priority)");
512 if (request) RINDENT();
513 num_ciphers = sk_SSL_CIPHER_num(client_ciphers);
514 for (i = 0; i < num_ciphers; i++) {
515 this_cipher = sk_SSL_CIPHER_value(client_ciphers, i);
516 ROPTIONAL(RDEBUG3, DEBUG3, "[%i] %s", i, SSL_CIPHER_get_name(this_cipher));
517 }
518 if (request) REXDENT();
519 }
520 }
521 }
522# endif
523 } else {
524 ROPTIONAL(RDEBUG2, DEBUG2, "Handshake state - %s%s (%u)", role, state, SSL_get_state(ssl));
525 }
526 return;
527 }
528
529 if (where & SSL_CB_ALERT) {
530 if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) return;
531
532 /*
533 * We got an alert...
534 */
535 if (where & SSL_CB_READ) {
536 fr_pair_t *vp;
537
538 ROPTIONAL(REDEBUG, ERROR, "Client sent %s TLS alert (%i) - %s", SSL_alert_type_string_long(ret),
539 ret & 0xff, SSL_alert_desc_string_long(ret));
540
541 /*
542 * Offer helpful advice... Should be expanded.
543 */
544 switch (ret & 0xff) {
545 case TLS1_AD_UNKNOWN_CA:
546 REDEBUG("Verify the client has a copy of the server's Certificate "
547 "Authority (CA) installed, and trusts that CA");
548 break;
549
550 default:
551 break;
552 }
553
555 vp->vp_uint8 = ret & 0xff;
556 ROPTIONAL(RDEBUG2, DEBUG2, "TLS-Client-Error-Code := %pV", &vp->data);
557 /*
558 * We're sending the client an alert.
559 */
560 } else {
561 ROPTIONAL(REDEBUG, ERROR, "Sending client %s TLS alert (%i) - %s",
562 SSL_alert_type_string_long(ret), ret & 0xff, SSL_alert_desc_string_long(ret));
563
564 /*
565 * Offer helpful advice... Should be expanded.
566 */
567 switch (ret & 0xff) {
568 case TLS1_AD_PROTOCOL_VERSION:
569 ROPTIONAL(REDEBUG, ERROR, "Client requested a TLS protocol version that is not "
570 "enabled or not supported. Upgrade FreeRADIUS + OpenSSL to their latest "
571 "versions and/or adjust 'tls_max_version'/'tls_min_version' if you want "
572 "authentication to succeed");
573 break;
574
575 default:
576 break;
577 }
578 }
579 return;
580 }
581
582 if (where & SSL_CB_EXIT) {
583 if (ret == 0) {
584 ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
585 return;
586 }
587
588 if (ret < 0) {
589 if (SSL_want_read(ssl)) {
590 RDEBUG2("Need more data from client"); /* State same as previous call, don't print */
591 return;
592 }
593 ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
594 }
595 }
596}
597DIAG_ON(used-but-marked-unused)
599
600/** Print a message to the request or global log detailing handshake state
601 *
602 * @param[in] request The current #request_t.
603 * @param[in] tls_session The current TLS session.
604 */
605static void session_msg_log(request_t *request, fr_tls_session_t *tls_session, uint8_t const *data, size_t data_len)
606{
607 char const *version, *content_type;
608 char const *str_details1 = NULL;
609 char const *str_details2 = NULL;
610 char unknown_version[32];
611 char unknown_content_type[32];
612 char unknown_alert_level[32];
613 char unknown_alert_description[32];
614 char unknown_handshake_type[32];
615
616 /*
617 * Don't print this out in the normal course of
618 * operations.
619 */
621
622 if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
623 !tls_version_str[tls_session->info.version]) {
624 snprintf(unknown_version, sizeof(unknown_version), "unknown_tls_version_0x%04x",
625 (unsigned int) tls_session->info.version);
626 version = unknown_version;
627 } else {
628 version = tls_version_str[tls_session->info.version];
629 }
630
631 /*
632 * TLS 1.0, 1.1, 1.2 content types are the same as SSLv3
633 */
634 if (((size_t)tls_session->info.content_type >= NUM_ELEMENTS(tls_content_type_str)) ||
635 !tls_content_type_str[tls_session->info.content_type]) {
636 snprintf(unknown_content_type, sizeof(unknown_content_type),
637 "unknown_content_type_0x%04x", (unsigned int) tls_session->info.content_type);
638 content_type = unknown_content_type;
639 } else {
640 content_type = tls_content_type_str[tls_session->info.content_type];
641 }
642
643 if (tls_session->info.content_type == SSL3_RT_ALERT) {
644 if (tls_session->info.record_len == 2) {
645 switch (tls_session->info.alert_level) {
646 case SSL3_AL_WARNING:
647 str_details1 = "warning";
648 break;
649 case SSL3_AL_FATAL:
650 str_details1 = "fatal";
651 break;
652
653 default:
654 snprintf(unknown_alert_level, sizeof(unknown_alert_level),
655 "unknown_alert_level_0x%04x", tls_session->info.alert_level);
656 str_details1 = unknown_alert_level;
657 break;
658 }
659
660 if (((size_t)tls_session->info.alert_description >= NUM_ELEMENTS(tls_alert_description_str)) ||
661 !tls_alert_description_str[tls_session->info.alert_description]) {
662 snprintf(unknown_alert_description, sizeof(unknown_alert_description),
663 "unknown_alert_0x%04x", tls_session->info.alert_description);
664 str_details2 = unknown_alert_description;
665 } else {
666 str_details2 = tls_alert_description_str[tls_session->info.alert_description];
667 }
668 } else {
669 str_details1 = "unknown_alert_level";
670 str_details2 = "unknown_alert";
671 }
672 }
673
674 if ((size_t)tls_session->info.content_type == SSL3_RT_HANDSHAKE) {
675 if (tls_session->info.record_len > 0) {
676 /*
677 * Range guard not needed due to size of array
678 * and underlying type.
679 */
680 if (!tls_handshake_type_str[tls_session->info.handshake_type]) {
681 snprintf(unknown_handshake_type, sizeof(unknown_handshake_type),
682 "unknown_handshake_type_0x%02x", tls_session->info.handshake_type);
683 str_details1 = unknown_handshake_type;
684 } else {
685 str_details1 = tls_handshake_type_str[tls_session->info.handshake_type];
686 }
687 }
688 }
689
690 snprintf(tls_session->info.info_description, sizeof(tls_session->info.info_description),
691 "%s %s, %s[length %lu]%s%s%s%s",
692 tls_session->info.origin ? ">>> send" : "<<< recv",
693 version,
694 content_type,
695 (unsigned long)tls_session->info.record_len,
696 str_details1 ? ", " : "",
697 str_details1 ? str_details1 : "",
698 str_details2 ? ", " : "",
699 str_details2 ? str_details2 : "");
700
701 /*
702 * Print out information about the record and print the
703 * data at higher debug levels.
704 */
706 ROPTIONAL(RHEXDUMP4, HEXDUMP4, data, data_len, "%s", tls_session->info.info_description);
707 } else {
708 ROPTIONAL(RDEBUG2, DEBUG2, "%s", tls_session->info.info_description);
709 }
710}
711
712/** Record the progression of the TLS handshake
713 *
714 * This callback is called by OpenSSL whenever a protocol message relating to a handshake is sent
715 * or received.
716 *
717 * This function copies state information from the various arguments into the state->info
718 * structure of the #fr_tls_session_t, to allow us to track the progression of the handshake.
719 *
720 * @param[in] write_p
721 * - 0 when a message has been received.
722 * - 1 when a message has been sent.
723 *
724 * @param[in] msg_version The TLS version negotiated, should be one of:
725 * - TLS1_VERSION
726 * - TLS1_1_VERSION
727 * - TLS1_2_VERSION
728 * - TLS1_3_VERSION
729 *
730 * @param[in] content_type One of the contentType values defined for TLS:
731 * - SSL3_RT_CHANGE_CIPHER_SPEC (20)
732 * - SSL3_RT_ALERT (21)
733 * - SSL3_RT_HANDSHAKE (22)
734 * - TLS1_RT_HEARTBEAT (24)
735 *
736 * @param[in] inbuf The raw protocol message.
737 * @param[in] len Length of the raw protocol message.
738 * @param[in] ssl The SSL session.
739 * @param[in] arg The #fr_tls_session_t holding the SSL session.
740 */
741void fr_tls_session_msg_cb(int write_p, int msg_version, int content_type,
742 void const *inbuf, size_t len,
743 SSL *ssl, void *arg)
744{
745 uint8_t const *buf = inbuf;
746 fr_tls_session_t *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
747 request_t *request = fr_tls_session_request(tls_session->ssl);
748
749 /*
750 * Mostly to check for memory corruption...
751 */
752 if (!fr_cond_assert(tls_session->ssl = ssl)) {
753 ROPTIONAL(REDEBUG, ERROR, "fr_tls_session_t and ssl arg do not match in fr_tls_session_msg_cb");
754 tls_session->invalid = true;
755 return;
756 }
757
758 /*
759 * As per https://tools.ietf.org/html/rfc7568
760 *
761 * We explicitly disable SSLv2/v3, hence the asserts.
762 */
763#ifdef SSL2_VERSION
764 if (!fr_cond_assert(msg_version != SSL2_VERSION)) {
765 ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv2) in handshake");
766 tls_session->invalid = true;
767 return;
768 }
769#endif
770
771#ifdef SSL3_VERSION
772 if (!fr_cond_assert(msg_version != SSL3_VERSION)) {
773 ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv3) in handshake");
774 tls_session->invalid = true;
775 return;
776 }
777#endif
778
779 /*
780 * OpenSSL >= 1.0.2 calls this function with 'pseudo'
781 * content types. Which breaks our tracking of
782 * the SSL Session state.
783 */
784 if ((msg_version == 0) && (content_type > UINT8_MAX)) {
785 ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with pseudo content type %i, version %i",
786 content_type, msg_version);
787 return;
788 }
789
790 if ((write_p != 0) && (write_p != 1)) {
791 ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with invalid write_p %d", write_p);
792 return;
793 }
794
795 /*
796 * 0 - received (from peer)
797 * 1 - sending (to peer)
798 */
799 tls_session->info.origin = write_p;
800 tls_session->info.content_type = content_type;
801 tls_session->info.record_len = len;
802 tls_session->info.version = msg_version;
803 tls_session->info.initialized = true;
804
805 switch (content_type) {
806 case SSL3_RT_ALERT:
807 tls_session->info.alert_level = buf[0];
808 tls_session->info.alert_description = buf[1];
809 tls_session->info.handshake_type = 0x00;
810 break;
811
812 case SSL3_RT_HANDSHAKE:
813 tls_session->info.handshake_type = buf[0];
814 tls_session->info.alert_level = 0x00;
815 tls_session->info.alert_description = 0x00;
816 break;
817
818#ifdef SSL3_RT_HEARTBEAT
819 case TLS1_RT_HEARTBEAT:
820 uint8_t *p = buf;
821
822 if ((len >= 3) && (p[0] == 1)) {
823 size_t payload_len;
824
825 payload_len = fr_nbo_to_uint16(p + 1);
826 if ((payload_len + 3) > len) {
827 tls_session->invalid = true;
828 ROPTIONAL(REDEBUG, ERROR, "OpenSSL Heartbeat attack detected. Closing connection");
829 return;
830 }
831 }
832 break;
833#endif
834 default:
835 break;
836 }
837
838 session_msg_log(request, tls_session, (uint8_t const *)inbuf, len);
839
840#ifndef OPENSSL_NO_SSL_TRACE
842 SSL_trace(tls_session->info.origin,
843 tls_session->info.version,
844 tls_session->info.content_type,
845 inbuf, len,
846 ssl,
847 request ?
848 fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3) :
849 fr_tls_global_log_bio(L_DBG, L_DBG_LVL_3));
850 }
851#endif
852}
853
854/*
855 * By setting the environment variable SSLKEYLOGFILE to a filename keying
856 * material will be exported that you may use with Wireshark to decode any
857 * TLS flows. Please see the following for more details:
858 *
859 * https://gitlab.com/wireshark/wireshark/-/wikis/TLS#tls-decryption
860 *
861 * An example logging session is (you should delete the file on each run):
862 *
863 * rm -f /tmp/sslkey.log; env SSLKEYLOGFILE=/tmp/sslkey.log freeradius -X | tee /tmp/debug
864 *
865 * Note that we rely on the OS to check file permissions. If the
866 * caller can run radiusd, then they can only write to files which
867 * they own. If radiusd is running as root, then only root can
868 * change the environment variables for radiusd.
869 */
870void fr_tls_session_keylog_cb(const SSL *ssl, const char *line)
871{
872 int fd;
873 size_t len;
874 const char *filename;
875 char buffer[64 + 2*SSL3_RANDOM_SIZE + 2*SSL_MAX_MASTER_KEY_LENGTH];
876
877 /*
878 * Prefer the environment variable definition to the
879 * configuration file. This allows for "one-shot"
880 * dumping of EAP keys when you know you're not using
881 * RadSec, and you don't want to edit the configuration.
882 */
883 filename = getenv("SSLKEYLOGFILE");
884 if (!filename) {
885 fr_tls_conf_t *conf;
886
887 conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
888 if (!conf || !conf->keylog_file || !*conf->keylog_file) return;
889
890 filename = conf->keylog_file;
891 }
892
893 /*
894 * We write all of the data at once. This is *generally*
895 * atomic on most systems.
896 */
897 len = strlen(line);
898 if ((len + 1) > sizeof(buffer)) {
899 DEBUG("SSLKEYLOGFILE buffer not large enough, max %lu, required %lu", sizeof(buffer), len + 1);
900 return;
901 }
902
903 /*
904 * Add a \n, which means that in order to write() the
905 * buffer AND the trailing \n, we have to place both
906 * strings into the same buffer.
907 */
908 memcpy(buffer, line, len);
909 buffer[len] = '\n';
910
911 fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
912 if (fd < 0) {
913 DEBUG("Failed to open file %s: %s", filename, strerror(errno));
914 return;
915 }
916
917 /*
918 * This should work in most situations.
919 */
920 if (write(fd, buffer, len + 1) < 0) {
921 DEBUG("Failed to write to file %s: %s", filename, strerror(errno));
922 }
923
924 close(fd);
925}
926
927/** Decrypt application data
928 *
929 * @note Handshake must have completed before this function may be called.
930 *
931 * Feed data from dirty_in to OpenSSL, and read the clean data into clean_out.
932 *
933 * @param[in] request The current #request_t.
934 * @param[in] tls_session The current TLS session.
935 * @return
936 * - -1 on error.
937 * - 1 if more fragments are required to fully reassemble the record for decryption.
938 * - 0 if we decrypted a complete record.
939 */
940int fr_tls_session_recv(request_t *request, fr_tls_session_t *tls_session)
941{
942 int ret;
943
944 fr_tls_session_request_bind(tls_session->ssl, request);
945
946 if (!SSL_is_init_finished(tls_session->ssl)) {
947 REDEBUG("Attempted to read application data before handshake completed");
948 error:
949 ret = -1;
950 goto finish;
951 }
952
953 /*
954 * Decrypt the complete record.
955 */
956 if (tls_session->dirty_in.used) {
957 ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
958 if (ret != (int) tls_session->dirty_in.used) {
959 record_init(&tls_session->dirty_in);
960 REDEBUG("Failed writing %zu bytes to SSL BIO: %d", tls_session->dirty_in.used, ret);
961 goto error;
962 }
963
964 record_init(&tls_session->dirty_in);
965 }
966
967 /*
968 * Clear the dirty buffer now that we are done with it
969 * and init the clean_out buffer to store decrypted data
970 */
971 record_init(&tls_session->clean_out);
972
973 /*
974 * Prevent spurious errors on the thread local error
975 * stack causing SSL_get_error() to return SSL_ERROR_SSL
976 * instead of what of the SSL_ERROR_WANT_* values.
977 */
978 ERR_clear_error();
979
980 /*
981 * Read (and decrypt) the tunneled data from the
982 * SSL session, and put it into the decrypted
983 * data buffer.
984 */
985 ret = SSL_read(tls_session->ssl, tls_session->clean_out.data, sizeof(tls_session->clean_out.data));
986 if (ret < 0) {
987 int code;
988
989 code = SSL_get_error(tls_session->ssl, ret);
990 switch (code) {
991 case SSL_ERROR_WANT_READ:
992 RWDEBUG("Peer indicated record was complete, but OpenSSL returned SSL_WANT_READ. "
993 "Attempting to continue");
994 ret = 1;
995 goto finish;
996
997 case SSL_ERROR_WANT_WRITE:
998 REDEBUG("Error in fragmentation logic: SSL_WANT_WRITE");
999 goto error;
1000
1001 case SSL_ERROR_NONE:
1002 RDEBUG2("No application data received. Assuming handshake is continuing...");
1003 ret = 0;
1004 break;
1005
1006 default:
1007 REDEBUG("Error in fragmentation logic");
1008 fr_tls_log_io_error(request, code, "SSL_read (%s)", __FUNCTION__);
1009 goto error;
1010 }
1011 }
1012
1013 /*
1014 * Passed all checks, successfully decrypted data
1015 */
1016 tls_session->clean_out.used = ret;
1017 ret = 0;
1018
1019 if (RDEBUG_ENABLED3) {
1020 RHEXDUMP3(tls_session->clean_out.data, tls_session->clean_out.used,
1021 "Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1022 } else {
1023 RDEBUG2("Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1024 }
1025finish:
1026 fr_tls_session_request_unbind(tls_session->ssl);
1027
1028 return ret;
1029}
1030
1031/** Encrypt application data
1032 *
1033 * @note Handshake must have completed before this function may be called.
1034 *
1035 * Take cleartext data from clean_in, and feed it to OpenSSL, reading
1036 * the encrypted data into dirty_out.
1037 *
1038 * @param[in] request The current request.
1039 * @param[in] tls_session The current TLS session.
1040 * @return
1041 * - -1 on failure.
1042 * - 0 on success.
1043 */
1044int fr_tls_session_send(request_t *request, fr_tls_session_t *tls_session)
1045{
1046 int ret = 0;
1047
1048 fr_tls_session_request_bind(tls_session->ssl, request);
1049
1050 if (!SSL_is_init_finished(tls_session->ssl)) {
1051 REDEBUG("Attempted to write application data before handshake completed");
1052 ret = -1;
1053 goto finish;
1054 }
1055
1056 /*
1057 * If there's un-encrypted data in 'clean_in', then write
1058 * that data to the SSL session, and then call the BIO function
1059 * to get that encrypted data from the SSL session, into
1060 * a buffer which we can then package into an EAP packet.
1061 *
1062 * Based on Server's logic this clean_in is expected to
1063 * contain the data to send to the client.
1064 */
1065 if (tls_session->clean_in.used > 0) {
1066 /*
1067 * Ensure spurious errors aren't printed
1068 */
1069 ERR_clear_error();
1070
1071 if (RDEBUG_ENABLED3) {
1072 RHEXDUMP3(tls_session->clean_in.data, tls_session->clean_in.used,
1073 "TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1074 } else {
1075 RDEBUG2("TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1076 }
1077
1078 ret = SSL_write(tls_session->ssl, tls_session->clean_in.data, tls_session->clean_in.used);
1079 record_to_buff(&tls_session->clean_in, NULL, ret);
1080
1081 /* Get the dirty data from Bio to send it */
1082 ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1083 sizeof(tls_session->dirty_out.data));
1084 if (ret > 0) {
1085 tls_session->dirty_out.used = ret;
1086 ret = 0;
1087 } else {
1088 if (fr_tls_log_io_error(request, SSL_get_error(tls_session->ssl, ret),
1089 "SSL_write (%s)", __FUNCTION__) < 0) ret = -1;
1090 }
1091 }
1092
1093finish:
1094 fr_tls_session_request_unbind(tls_session->ssl);
1095
1096 return ret;
1097}
1098
1099/** Instruct fr_tls_session_async_handshake to create a synthesised TLS alert record and send it to the peer
1100 *
1101 */
1102int fr_tls_session_alert(UNUSED request_t *request, fr_tls_session_t *session, uint8_t level, uint8_t description)
1103{
1104 if (session->alerts_sent > 3) return -1; /* Some kind of state machine brokenness */
1105
1106 /*
1107 * Ignore less severe alerts
1108 */
1109 if (session->pending_alert && (level < session->pending_alert_level)) return 0;
1110
1111 session->pending_alert = true;
1112 session->pending_alert_level = level;
1113 session->pending_alert_description = description;
1114
1115 return 0;
1116}
1117
1118static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *session)
1119{
1120 /*
1121 * Update our internal view of the session
1122 */
1123 session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT;
1124 session->info.content_type = SSL3_RT_ALERT;
1125 session->info.alert_level = session->pending_alert_level;
1126 session->info.alert_description = session->pending_alert_description;
1127
1128 session->dirty_out.data[0] = session->info.content_type;
1129 session->dirty_out.data[1] = 3;
1130 session->dirty_out.data[2] = 1;
1131 session->dirty_out.data[3] = 0;
1132 session->dirty_out.data[4] = 2;
1133 session->dirty_out.data[5] = session->pending_alert_level;
1134 session->dirty_out.data[6] = session->pending_alert_description;
1135
1136 session->dirty_out.used = 7;
1137
1138 session->pending_alert = false;
1139 session->alerts_sent++;
1140
1141 SSL_clear(session->ssl); /* Reset the SSL *, to allow the client to restart the session */
1142
1143 session_msg_log(request, session, session->dirty_out.data, session->dirty_out.used);
1144}
1145
1146/** Process the result of `establish session { ... }`
1147 *
1148 * As this is just a logging session, it's result doesn't affect the parent.
1149 */
1150static unlang_action_t tls_establish_session_result(UNUSED rlm_rcode_t *p_result, UNUSED int *priority,
1151 UNUSED request_t *request, UNUSED void *uctx)
1152{
1154}
1155
1156/** Push an `establish session { ... }` call into the current request, using a subrequest
1157 *
1158 * @param[in] request The current request.
1159 * @param[in] conf TLS configuration.
1160 * @param[in] tls_session The current TLS session.
1161 * @return
1162 * - UNLANG_ACTION_PUSHED_CHILD on success.
1163 * - UNLANG_ACTION_FAIL on failure.
1164 */
1165static inline CC_HINT(always_inline)
1166unlang_action_t tls_establish_session_push(request_t *request, fr_tls_conf_t *conf, fr_tls_session_t *tls_session)
1167{
1168 request_t *child;
1169 fr_pair_t *vp;
1170 unlang_action_t ua;
1171
1172 MEM(child = unlang_subrequest_alloc(request, dict_tls));
1173 request = child;
1174
1175 /*
1176 * Setup the child request for reporting session
1177 */
1179 vp->vp_uint32 = enum_tls_packet_type_establish_session->vb_uint32;
1180
1181 /*
1182 * Allocate a child, and set it up to call
1183 * the TLS virtual server.
1184 */
1185 ua = fr_tls_call_push(child, tls_establish_session_result, conf, tls_session, false);
1186 if (ua < 0) {
1187 talloc_free(child);
1188 return UNLANG_ACTION_FAIL;
1189 }
1190
1191 return ua;
1192}
1193
1194/** Finish off a handshake round, possibly adding attributes to the request
1195 *
1196 */
1197static unlang_action_t tls_session_async_handshake_done_round(UNUSED rlm_rcode_t *p_result, UNUSED int *priority,
1198 request_t *request, void *uctx)
1199{
1200 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1201 int ret;
1202
1203 RDEBUG3("entered state %s", __FUNCTION__);
1204
1205 /*
1206 * This only occurs once per session, where calling
1207 * SSL_read updates the state of the SSL session, setting
1208 * this flag to true.
1209 *
1210 * Callbacks provide enough info so we don't need to
1211 * print debug statements when the handshake is in other
1212 * states.
1213 */
1214 if (SSL_is_init_finished(tls_session->ssl)) {
1215 SSL_CIPHER const *cipher;
1216 fr_pair_t *vp;
1217 char const *version;
1218
1219 char cipher_desc[256], cipher_desc_clean[256];
1220 char *p = cipher_desc, *q = cipher_desc_clean;
1221
1222 cipher = SSL_get_current_cipher(tls_session->ssl);
1223 SSL_CIPHER_description(cipher, cipher_desc, sizeof(cipher_desc));
1224
1225 /*
1226 * Cleanup the output from OpenSSL
1227 * Seems to print info in a tabular format.
1228 */
1229 while (*p != '\0') {
1230 if (isspace((uint8_t) *p)) {
1231 *q++ = *p;
1233 continue;
1234 }
1235 *q++ = *p++;
1236 }
1237 *q = '\0';
1238
1239 RDEBUG2("Cipher suite: %s", cipher_desc_clean);
1240
1241 RDEBUG2("Adding TLS session information to request");
1242 RINDENT();
1244 fr_pair_value_strdup(vp, SSL_CIPHER_get_name(cipher), false);
1245 RDEBUG2("session-state.%pP", vp);
1246
1247 if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
1248 !tls_version_str[tls_session->info.version]) {
1249 version = "UNKNOWN";
1250 } else {
1251 version = tls_version_str[tls_session->info.version];
1252 }
1253
1255 fr_pair_value_strdup(vp, version, false);
1256 RDEBUG2("session-state.%pP", vp);
1257 REXDENT();
1258
1259 /*
1260 * Cache the SSL_SESSION pointer.
1261 *
1262 * Which contains all the data we need for session resumption.
1263 */
1264 if (!tls_session->session) {
1265 tls_session->session = SSL_get_session(tls_session->ssl);
1266 if (!tls_session->session) {
1267 REDEBUG("Failed getting TLS session");
1268 error:
1269 tls_session->result = FR_TLS_RESULT_ERROR;
1270 fr_tls_session_request_unbind(tls_session->ssl);
1272 }
1273 }
1274
1275 if (RDEBUG_ENABLED3) {
1276 if (SSL_SESSION_print(fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3),
1277 tls_session->session) != 1) {
1278 } else {
1279 RDEBUG3("Failed retrieving session data");
1280 }
1281 }
1282
1283 /*
1284 * Session was resumed, add attribute to mark it as such.
1285 */
1286 if (SSL_session_reused(tls_session->ssl)) {
1287 /*
1288 * Mark the request as resumed.
1289 */
1291 vp->vp_bool = true;
1292 }
1293 }
1294
1295 /*
1296 * Get data to pack and send back to the TLS peer.
1297 */
1298 ret = BIO_ctrl_pending(tls_session->from_ssl);
1299 if (ret > 0) {
1300 ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1301 sizeof(tls_session->dirty_out.data));
1302 if (ret > 0) {
1303 tls_session->dirty_out.used = ret;
1304 } else if (BIO_should_retry(tls_session->from_ssl)) {
1305 record_init(&tls_session->dirty_in);
1306 RDEBUG2("Asking for more data in tunnel");
1307
1308 } else {
1309 fr_tls_log(NULL, NULL);
1310 record_init(&tls_session->dirty_in);
1311 goto error;
1312 }
1313 } else {
1314 /* Its clean application data, do whatever we want */
1315 record_init(&tls_session->clean_out);
1316 }
1317
1318 /*
1319 * Trash the current data in dirty_out, and synthesize
1320 * a TLS error record.
1321 *
1322 * OpensSL annoyingly provides no mechanism for us to
1323 * send alerts, and we need to send alerts as part of
1324 * RFC 5216, so this is our only option.
1325 */
1326 if (tls_session->pending_alert) fr_tls_session_alert_send(request, tls_session);
1327
1328 /* We are done with dirty_in, reinitialize it */
1329 record_init(&tls_session->dirty_in);
1330
1331 tls_session->result = FR_TLS_RESULT_SUCCESS;
1332 fr_tls_session_request_unbind(tls_session->ssl);
1333 if (SSL_is_init_finished(tls_session->ssl)) {
1334 fr_tls_conf_t *conf = fr_tls_session_conf(tls_session->ssl);
1335 if (conf->establish_session) return tls_establish_session_push(request, conf, tls_session);
1336 }
1338}
1339
1340/** Try very hard to get the SSL * into a consistent state where it's not yielded
1341 *
1342 * ...because if it's yielded, we'll probably leak thread contexts and all kinds of memory.
1343 *
1344 * @param[in] request being cancelled.
1345 * @param[in] action we're being signalled with.
1346 * @param[in] uctx the SSL * to cancel.
1347 */
1348static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
1349{
1350 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1351 int ret;
1352
1353 /*
1354 * We might want to set can_pause = false here
1355 * but that would trigger asserts in the
1356 * cache code.
1357 */
1358
1359 /*
1360 * If SSL_get_error returns SSL_ERROR_WANT_ASYNC
1361 * it means we're yielded in the middle of a
1362 * callback.
1363 *
1364 * Keep calling SSL_read() in a loop until we
1365 * no longer get SSL_ERROR_WANT_ASYNC, then
1366 * shut it down so it's in a consistent state.
1367 *
1368 * It'll get freed later when the request is
1369 * freed.
1370 */
1371 for (ret = tls_session->last_ret;
1372 SSL_get_error(tls_session->ssl, ret) == SSL_ERROR_WANT_ASYNC;
1373 ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1374 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used));
1375
1376 /*
1377 * Unbind the cancelled request from the SSL *
1378 */
1379 fr_tls_session_request_unbind(tls_session->ssl);
1380}
1381
1382/** Call SSL_read() to continue the TLS state machine
1383 *
1384 * This function may be called multiple times, once after every asynchronous request.
1385 *
1386 * @param[in,out] p_result UNUSED.
1387 * @param[out] priority UNUSED
1388 * @param[in] request The current request.
1389 * @param[in] uctx #fr_tls_session_t to continue.
1390 * @return
1391 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1392 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1393 */
1394static unlang_action_t tls_session_async_handshake_cont(rlm_rcode_t *p_result, int *priority,
1395 request_t *request, void *uctx)
1396{
1397 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1398 int err;
1399
1400 RDEBUG3("(re-)entered state %s", __FUNCTION__);
1401
1402 /*
1403 * Clear OpenSSL's thread local error stack.
1404 *
1405 * Why do we need to do this here? Although SSL_get_error
1406 * takes an `SSL *`, which would make you _think_ it was
1407 * operating on the error stack for that SSL, it will also
1408 * return SSL_ERROR_SSL if there are any errors in the stack.
1409 *
1410 * When operating normally SSL_read() can return < 0, to
1411 * indicate it wants more data, or that we need to perform
1412 * asynchronous processing.
1413 *
1414 * If spurious errors have been left on the thread local
1415 * stack they MUST be cleared before we can call SSL_get_error
1416 * otherwise stale errors mask the async notifications
1417 * and cause random handshake failures.
1418 */
1419 ERR_clear_error();
1420
1421 /*
1422 * Magic/More magic? Although SSL_read is normally
1423 * used to read application data, it will also
1424 * continue the TLS handshake. Removing this call will
1425 * cause the handshake to fail.
1426 *
1427 * We don't ever expect to actually *receive* application
1428 * data here.
1429 *
1430 * The reason why we call SSL_read instead of SSL_accept,
1431 * or SSL_connect, as it allows this function
1432 * to be used, irrespective or whether we're acting
1433 * as a client or a server.
1434 *
1435 * If acting as a client SSL_set_connect_state must have
1436 * been called before this function.
1437 *
1438 * If acting as a server SSL_set_accept_state must have
1439 * been called before this function.
1440 */
1441 tls_session->can_pause = true;
1442 tls_session->last_ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1443 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used);
1444 tls_session->can_pause = false;
1445 if (tls_session->last_ret > 0) {
1446 tls_session->clean_out.used += tls_session->last_ret;
1447
1448 /*
1449 * Round successful, and we don't need to do any
1450 * further processing.
1451 */
1452 tls_session->result = FR_TLS_RESULT_SUCCESS;
1453 finish:
1454 /*
1455 * Was bound by caller
1456 */
1457 fr_tls_session_request_unbind(tls_session->ssl);
1459 }
1460
1461 /*
1462 * Bug in OpenSSL 3.0 - Normal handshaking behaviour
1463 * results in spurious "BIO_R_UNSUPPORTED_METHOD"
1464 * errors.
1465 *
1466 * SSL_get_error apparently returns SSL_ERROR_SSL if
1467 * there are any errors in the stack. This masks
1468 * SSL_ERROR_WANT_ASYNC and causes the handshake to
1469 * fail.
1470 *
1471 * Note: We may want some version of this code
1472 * included for all OpenSSL versions.
1473 *
1474 * It would call ERR_GET_FATAL() on each of the errors
1475 * in the stack to drain non-fatal errors and prevent
1476 * the other (more useful) return codes of
1477 * SSL_get_error from being masked. I guess we'll see
1478 * if this occurs in other scenarios.
1479 */
1480 if (SSL_get_error(tls_session->ssl, tls_session->last_ret) == SSL_ERROR_SSL) {
1481 unsigned long ssl_err;
1482
1483 /*
1484 * Some weird OpenSSL thing marking ERR_GET_REASON
1485 * as "unused". Unclear why this is done as it's
1486 * not deprecated.
1487 */
1489DIAG_OFF(used-but-marked-unused)
1490 while ((ssl_err = ERR_peek_error()) && (ERR_GET_REASON(ssl_err) == BIO_R_UNSUPPORTED_METHOD)) {
1491 (void) ERR_get_error();
1492 }
1493DIAG_ON(used-but-marked-unused)
1495 }
1496
1497 /*
1498 * Deal with asynchronous requests from OpenSSL.
1499 * These aren't actually errors, they're the
1500 * result of one of our callbacks indicating that
1501 * it'd like to perform the operation
1502 * asynchronously.
1503 */
1504 switch (err = SSL_get_error(tls_session->ssl, tls_session->last_ret)) {
1505 case SSL_ERROR_WANT_ASYNC: /* Certification validation or cache loads */
1506 {
1507 unlang_action_t ua;
1508
1509 RDEBUG3("Performing async action for libssl");
1510
1511 /*
1512 * Call this function again once we're done
1513 * asynchronously satisfying the load request.
1514 */
1515 if (unlikely(unlang_function_repeat_set(request, tls_session_async_handshake_cont) < 0)) {
1516 error:
1517 tls_session->result = FR_TLS_RESULT_ERROR;
1518 goto finish;
1519 }
1520
1521 /*
1522 * First service any pending cache actions
1523 */
1524 ua = fr_tls_cache_pending_push(request, tls_session);
1525 switch (ua) {
1526 case UNLANG_ACTION_FAIL:
1527 IGNORE(unlang_function_clear(request), int);
1528 goto error;
1529
1531 return ua;
1532
1533 default:
1534 break;
1535 }
1536
1537 /*
1538 * Next service any pending certificate
1539 * validation actions.
1540 */
1541 ua = fr_tls_verify_cert_pending_push(request, tls_session);
1542 switch (ua) {
1543 case UNLANG_ACTION_FAIL:
1544 IGNORE(unlang_function_clear(request), int);
1545 goto error;
1546
1547 default:
1548 return ua;
1549 }
1550 }
1551
1552 case SSL_ERROR_WANT_ASYNC_JOB:
1553 RERROR("No async jobs available in pool, increase thread.openssl_async_pool_max");
1554 goto error;
1555
1556 default:
1557 /*
1558 * Returns 0 if we can continue processing the handshake
1559 * Returns -1 if we encountered a fatal error.
1560 */
1561 if (fr_tls_log_io_error(request,
1562 err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
1563 return tls_session_async_handshake_done_round(p_result, priority, request, uctx);
1564 }
1565}
1566
1567/** Ingest data for another handshake round
1568 *
1569 * Advance the TLS handshake by feeding OpenSSL data from dirty_in,
1570 * and reading data from OpenSSL into dirty_out.
1571 *
1572 * Calls #tls_session_async_handshake_read to perform the actual ingestion.
1573 * #tls_session_async_handshake_read is split out because we may need to call
1574 * it multiple times, once after every async action.
1575 *
1576 * @param[in,out] p_result UNUSED.
1577 * @param[out] priority UNUSED
1578 * @param[in] request The current request.
1579 * @param[in] uctx #fr_tls_session_t to continue.
1580 * @return
1581 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1582 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1583 */
1584static unlang_action_t tls_session_async_handshake(rlm_rcode_t *p_result, int *priority,
1585 request_t *request, void *uctx)
1586{
1587 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1588 int ret;
1589
1590 RDEBUG3("entered state %s", __FUNCTION__);
1591
1592 tls_session->result = FR_TLS_RESULT_IN_PROGRESS;
1593
1594 fr_tls_session_request_bind(tls_session->ssl, request); /* May be unbound in this function or asynchronously */
1595
1596 /*
1597 * This is a logic error. fr_tls_session_async_handshake
1598 * must not be called if the handshake is
1599 * complete fr_tls_session_recv must be
1600 * called instead.
1601 */
1602 if (SSL_is_init_finished(tls_session->ssl)) {
1603 REDEBUG("Attempted to continue TLS handshake, but handshake has completed");
1604 error:
1605 tls_session->result = FR_TLS_RESULT_ERROR;
1606 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1608 }
1609
1610 if (tls_session->invalid) {
1611 REDEBUG("Preventing invalid session from continuing");
1612 goto error;
1613 }
1614
1615 /*
1616 * Feed dirty data into OpenSSL, so that is can either
1617 * process it as Application data (decrypting it)
1618 * or continue the TLS handshake.
1619 */
1620 if (tls_session->dirty_in.used) {
1621 ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
1622 if (ret != (int)tls_session->dirty_in.used) {
1623 REDEBUG("Failed writing %zu bytes to TLS BIO: %d", tls_session->dirty_in.used, ret);
1624 record_init(&tls_session->dirty_in);
1625 goto error;
1626 }
1627 record_init(&tls_session->dirty_in);
1628 }
1629
1630 return tls_session_async_handshake_cont(p_result, priority, request, uctx); /* Must unbind request, possibly asynchronously */
1631}
1632
1633/** Push a handshake call onto the stack
1634 *
1635 * We push the handshake frame (as opposed to having the caller do it),
1636 * so that we guarantee there's a frame that the handshake function can
1637 * manipulate to manage its own state.
1638 *
1639 * The result of processing this handshake round can be found in
1640 * tls_session->result.
1641 *
1642 * @param[in] request The current request.
1643 * @param[in] tls_session to continue handshaking.
1644 * @return
1645 * - UNLANG_ACTION_PUSHED_CHILD on success.
1646 * - UNLANG_ACTION_FAIL on failure.
1647 */
1648unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
1649{
1650 return unlang_function_push(request,
1651 tls_session_async_handshake,
1652 NULL,
1653 tls_session_async_handshake_signal,
1656 tls_session);
1657}
1658
1659/** Free a TLS session and any associated OpenSSL data
1660 *
1661 * @param session to free.
1662 * @return 0.
1663 */
1664static int _fr_tls_session_free(fr_tls_session_t *session)
1665{
1666 if (session->ssl) {
1667 /*
1668 * The OpenSSL docs state:
1669 *
1670 * SSL_shutdown() can be modified to only set the
1671 * connection to "shutdown" state but not actually
1672 * send the "close notify" alert messages, see
1673 * SSL_CTX_set_quiet_shutdown(3). When "quiet shutdown"
1674 * is enabled, SSL_shutdown() will always succeed and
1675 * return 1.
1676 *
1677 * This is only partially correct. This call does mean
1678 * we don't notify the other party, but the SSL_shutdown
1679 * call can still fail if the handshake hasn't begun, leaving
1680 * spurious errors on the thread local error stack.
1681 */
1682 SSL_set_quiet_shutdown(session->ssl, 1);
1683
1684 /*
1685 * Don't leave spurious errors raised by SSL_shutdown on
1686 * the error stack.
1687 */
1688 if (SSL_shutdown(session->ssl) != 1) ERR_clear_error();
1689
1690 SSL_free(session->ssl);
1691 session->ssl = NULL;
1692 }
1693
1694 return 0;
1695}
1696
1697static void session_init(fr_tls_session_t *session)
1698{
1699 session->ssl = NULL;
1700 session->into_ssl = session->from_ssl = NULL;
1701 record_init(&session->clean_in);
1702 record_init(&session->clean_out);
1703 record_init(&session->dirty_in);
1704 record_init(&session->dirty_out);
1705
1706 memset(&session->info, 0, sizeof(session->info));
1707
1708 session->mtu = 0;
1709 session->opaque = NULL;
1710}
1711
1712/** Create a new client TLS session
1713 *
1714 * Configures a new client TLS session, configuring options, setting callbacks etc...
1715 *
1716 * @param[in] ctx to alloc session data in. Should usually be NULL unless the lifetime of the
1717 * session is tied to another talloc'd object.
1718 * @param[in] ssl_ctx containing the base configuration for this session.
1719 * @return
1720 * - A new session on success.
1721 * - NULL on error.
1722 */
1723fr_tls_session_t *fr_tls_session_alloc_client(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx)
1724{
1725 int verify_mode;
1726 fr_tls_session_t *tls_session = NULL;
1727 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1728
1729 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1730 talloc_set_destructor(tls_session, _fr_tls_session_free);
1731 fr_pair_list_init(&tls_session->extra_pairs);
1732
1733 tls_session->ssl = SSL_new(ssl_ctx);
1734 if (!tls_session->ssl) {
1735 talloc_free(tls_session);
1736 return NULL;
1737 }
1738
1739 /*
1740 * Add the message callback to identify what type of
1741 * message/handshake is passed
1742 */
1743 SSL_set_msg_callback(tls_session->ssl, fr_tls_session_msg_cb);
1744 SSL_set_msg_callback_arg(tls_session->ssl, tls_session);
1745 SSL_set_info_callback(tls_session->ssl, fr_tls_session_info_cb);
1746
1747 /*
1748 * In Client mode we only accept.
1749 *
1750 * This sets up the SSL session to work correctly with
1751 * fr_tls_session_handshake.
1752 */
1753 SSL_set_connect_state(tls_session->ssl);
1754
1755 /*
1756 * Always verify the peer certificate.
1757 */
1758 DEBUG2("Requiring Server certificate");
1759 verify_mode = SSL_VERIFY_PEER;
1760 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1761
1762 /*
1763 * Callback should be fr_tls_verify_cert_cb but this
1764 * requires support around SSL_connect for dealing
1765 * with async.
1766 *
1767 * If the callback is NULL OpenSSL uses its own validation
1768 * function, and the flags modifies that function's
1769 * behaviour.
1770 */
1771 SSL_set_verify(tls_session->ssl, verify_mode, NULL);
1772 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1773 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1774
1775 tls_session->mtu = conf->fragment_size;
1776
1777 return tls_session;
1778}
1779
1780/** Create a new server TLS session
1781 *
1782 * Configures a new server TLS session, configuring options, setting callbacks etc...
1783 *
1784 * @param[in] ctx to alloc session data in. Should usually be NULL
1785 * unless the lifetime of the session is tied to another
1786 * talloc'd object.
1787 * @param[in] ssl_ctx containing the base configuration for this session.
1788 * @param[in] request The current #request_t.
1789 * @param[in] dynamic_mtu If greater than 100, overrides the MTU configured for the SSL_CTX.
1790 * @param[in] client_cert Whether to require a client_cert.
1791 * @return
1792 * - A new session on success.
1793 * - NULL on error.
1794 */
1795fr_tls_session_t *fr_tls_session_alloc_server(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx, request_t *request, size_t dynamic_mtu, bool client_cert)
1796{
1797 fr_tls_session_t *tls_session = NULL;
1798 SSL *ssl = NULL;
1799 int verify_mode = 0;
1800 fr_pair_t *vp;
1801 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1802
1803 RDEBUG2("Initiating new TLS session");
1804
1805 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1806
1807 ssl = SSL_new(ssl_ctx);
1808 if (ssl == NULL) {
1809 fr_tls_log(request, "Error creating new TLS session");
1810 return NULL;
1811 }
1812 fr_pair_list_init(&tls_session->extra_pairs);
1813
1814 session_init(tls_session);
1815 tls_session->ctx = ssl_ctx;
1816 tls_session->ssl = ssl;
1817 talloc_set_destructor(tls_session, _fr_tls_session_free);
1818
1819 fr_tls_session_request_bind(tls_session->ssl, request); /* Is unbound in this function */
1820
1821 /*
1822 * Initialize callbacks
1823 */
1824 tls_session->record_init = record_init;
1825 tls_session->record_close = record_close;
1826 tls_session->record_from_buff = record_from_buff;
1827 tls_session->record_to_buff = record_to_buff;
1828
1829 /*
1830 * Create & hook the BIOs to handle the dirty side of the
1831 * SSL. This is *very important* as we want to handle
1832 * the transmission part. Now the only IO interface
1833 * that SSL is aware of, is our defined BIO buffers.
1834 *
1835 * This means that all SSL IO is done to/from memory,
1836 * and we can update those BIOs from the packets we've
1837 * received.
1838 */
1839 MEM(tls_session->into_ssl = BIO_new(BIO_s_mem()));
1840 MEM(tls_session->from_ssl = BIO_new(BIO_s_mem()));
1841 SSL_set_bio(tls_session->ssl, tls_session->into_ssl, tls_session->from_ssl);
1842
1843 /*
1844 * Add the message callback to identify what type of
1845 * message/handshake is passed
1846 */
1847 SSL_set_msg_callback(ssl, fr_tls_session_msg_cb);
1848 SSL_set_msg_callback_arg(ssl, tls_session);
1849 SSL_set_info_callback(ssl, fr_tls_session_info_cb);
1850
1851 /*
1852 * This sets the context sessions can be resumed in.
1853 * This is to prevent sessions being created by one application
1854 * and used by another. In our case it prevents sessions being
1855 * reused between modules, or TLS server components such as
1856 * RADSEC.
1857 *
1858 * A context must always be set when doing session resumption
1859 * otherwise session resumption will fail.
1860 *
1861 * As the context ID must be <= 32, we digest the context
1862 * data with sha256.
1863 *
1864 * This seems to only be used for stateful session resumption
1865 * not session-tickets
1866 */
1867 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1868 char *context_id;
1869 EVP_MD_CTX *md_ctx;
1870 uint8_t digest[SHA256_DIGEST_LENGTH];
1871
1872 static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
1873 "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");
1874 fr_assert(conf->cache.id_name);
1875
1876 if (tmpl_aexpand(tls_session, &context_id, request, conf->cache.id_name, NULL, NULL) < 0) {
1877 RPEDEBUG("Failed expanding session ID");
1878 error:
1879 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1880 talloc_free(tls_session);
1881 return NULL;
1882 }
1883
1884 MEM(md_ctx = EVP_MD_CTX_create());
1885 EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
1886 EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
1887 EVP_DigestFinal_ex(md_ctx, digest, NULL);
1888 EVP_MD_CTX_destroy(md_ctx);
1889 talloc_free(context_id);
1890
1891 if (!fr_cond_assert(SSL_set_session_id_context(tls_session->ssl,
1892 digest, sizeof(digest)) == 1)) goto error;
1893 }
1894
1895 /*
1896 * Add the session certificate to the session.
1897 */
1898 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_cert_file);
1899 if (vp) {
1900 RDEBUG2("Loading TLS session certificate \"%pV\"", &vp->data);
1901
1902 if (SSL_use_certificate_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1903 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1904 vp->vp_strvalue);
1905 goto error;
1906 }
1907
1908 if (SSL_use_PrivateKey_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1909 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1910 vp->vp_strvalue);
1911 goto error;
1912 }
1913
1914 if (SSL_check_private_key(tls_session->ssl) != 1) {
1915 fr_tls_log(request, "Failed validating TLS session certificate \"%s\"",
1916 vp->vp_strvalue);
1917 goto error;
1918 }
1919 /*
1920 * Better to perform explicit checks, than rely
1921 * on OpenSSL's opaque error messages.
1922 */
1923 } else {
1924 if (!conf->chains || !conf->chains[0]->private_key_file) {
1925 ERROR("TLS Server requires a private key file");
1926 goto error;
1927 }
1928
1929 if (!conf->chains || !conf->chains[0]->certificate_file) {
1930 ERROR("TLS Server requires a certificate file");
1931 goto error;
1932 }
1933 }
1934
1935 /** Dynamic toggle for allowing disallowing client certs
1936 *
1937 * This is mainly used for testing in environments where we can't
1938 * get test credentials for the host.
1939 */
1940 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_require_client_cert);
1941 if (vp) client_cert = vp->vp_bool;
1942
1943 /*
1944 * In Server mode we only accept.
1945 *
1946 * This sets up the SSL session to work correctly with
1947 * fr_tls_session_handshake.
1948 */
1949 SSL_set_accept_state(tls_session->ssl);
1950
1951 /*
1952 * Verify the peer certificate, if asked.
1953 */
1954 if (client_cert) {
1955 RDEBUG2("Setting verify mode to require certificate from client");
1956 verify_mode = SSL_VERIFY_PEER;
1957 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1958 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1959 }
1960 tls_session->verify_client_cert = client_cert;
1961
1962 SSL_set_verify(tls_session->ssl, verify_mode, fr_tls_verify_cert_cb);
1963 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1964 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1965
1966 tls_session->mtu = conf->fragment_size;
1967 if (dynamic_mtu > 100 && dynamic_mtu < tls_session->mtu) {
1968 RDEBUG2("Setting fragment_len to %zu from dynamic_mtu", dynamic_mtu);
1969 tls_session->mtu = dynamic_mtu;
1970 }
1971
1972 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1973 tls_session->allow_session_resumption = true; /* otherwise it's false */
1974 fr_tls_cache_session_alloc(tls_session);
1975 }
1976
1977 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1978
1979 return tls_session;
1980}
1981
1982static unlang_action_t tls_new_session_result(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, UNUSED void *uctx)
1983{
1984 request_t *parent = request->parent;
1985
1987
1988 /*
1989 * Copy control attributes back to the parent.
1990 */
1991 if (fr_pair_list_copy(parent->control_ctx, &parent->control_pairs, &request->control_pairs) < 0) return UNLANG_ACTION_FAIL;
1992
1994}
1995
1996unlang_action_t fr_tls_new_session_push(request_t *request, fr_tls_conf_t const *tls_conf) {
1997 request_t *child;
1998 fr_pair_t *vp;
1999
2000 MEM(child = unlang_subrequest_alloc(request, dict_tls));
2001 request = child;
2002
2004 vp->vp_uint32 = enum_tls_packet_type_new_session->vb_uint32;
2005
2006 if (unlang_subrequest_child_push(NULL, child,
2008 .enable = true,
2009 .unique_ptr = child->parent
2010 },
2011 true, UNLANG_SUB_FRAME) < 0) {
2012 return UNLANG_ACTION_FAIL;
2013 }
2014 if (unlang_function_push(child, NULL, tls_new_session_result, NULL, 0, UNLANG_SUB_FRAME, NULL) < 0) return UNLANG_ACTION_FAIL;
2015
2016 if (unlang_call_push(child, tls_conf->virtual_server, UNLANG_SUB_FRAME) < 0) {
2017 return UNLANG_ACTION_FAIL;
2018 }
2020}
2021#endif /* WITH_TLS */
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
Definition action.h:39
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
Definition action.h:36
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition action.h:37
static int const char char buffer[256]
Definition acutest.h:576
int const char int line
Definition acutest.h:702
#define fr_base16_decode(_err, _out, _in, _no_trailing)
Definition base16.h:95
#define IGNORE(_expr, _type)
Definition build.h:509
#define DIAG_UNKNOWN_PRAGMAS
Definition build.h:458
#define DIAG_ON(_x)
Definition build.h:460
#define unlikely(_x)
Definition build.h:383
#define UNUSED
Definition build.h:317
#define NUM_ELEMENTS(_t)
Definition build.h:339
#define DIAG_OFF(_x)
Definition build.h:459
unlang_action_t unlang_call_push(request_t *request, CONF_SECTION *server_cs, bool top_frame)
Push a call frame onto the stack.
Definition call.c:147
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:514
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:139
#define MEM(x)
Definition debug.h:36
#define ERROR(fmt,...)
Definition dhcpclient.c:41
#define DEBUG(fmt,...)
Definition dhcpclient.c:39
static fr_slen_t err
Definition dict.h:833
static fr_slen_t in
Definition dict.h:833
int unlang_function_clear(request_t *request)
Clear pending repeat function calls, and remove the signal handler.
Definition function.c:160
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
Definition function.h:89
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:111
#define UNLANG_SUB_FRAME
Definition interpret.h:36
fr_dict_t const * dict_tls
Definition base.c:79
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:443
#define DEBUG_ENABLED2
True if global debug level 1-2 messages are enabled.
Definition log.h:258
#define DEBUG3(_fmt,...)
Definition log.h:266
#define ROPTIONAL(_l_request, _l_global, _fmt,...)
Use different logging functions depending on whether request is NULL or not.
Definition log.h:528
#define RWDEBUG(fmt,...)
Definition log.h:361
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:335
#define RDEBUG3(fmt,...)
Definition log.h:343
#define DEBUG_ENABLED4
True if global debug level 1-3 messages are enabled.
Definition log.h:260
#define RHEXDUMP4(_data, _len, _fmt,...)
Definition log.h:706
#define RERROR(fmt,...)
Definition log.h:298
#define DEBUG4(_fmt,...)
Definition log.h:267
#define ROPTIONAL_ENABLED(_e_request, _e_global)
Check if a debug level is set by the request (if !NULL) or by the global log.
Definition log.h:542
#define RPEDEBUG(fmt,...)
Definition log.h:376
#define RHEXDUMP3(_data, _len, _fmt,...)
Definition log.h:705
#define RDEBUG4(fmt,...)
Definition log.h:344
#define DEBUG_ENABLED3
True if global debug level 1-3 messages are enabled.
Definition log.h:259
#define RDEBUG_ENABLED4
True if request debug level 1-4 messages are enabled.
Definition log.h:336
#define HEXDUMP4(_data, _len, _fmt,...)
Definition log.h:724
#define RPWDEBUG2(fmt,...)
Definition log.h:367
#define REDEBUG4(fmt,...)
Definition log.h:374
#define RINDENT()
Indent R* messages by one level.
Definition log.h:430
HIDDEN fr_dict_attr_t const * attr_tls_packet_type
HIDDEN fr_dict_attr_t const * attr_session_resumed
HIDDEN fr_dict_attr_t const * attr_tls_session_version
HIDDEN fr_dict_attr_t const * attr_tls_session_require_client_cert
fr_value_box_t const * enum_tls_packet_type_new_session
HIDDEN fr_dict_attr_t const * attr_tls_client_error_code
fr_value_box_t const * enum_tls_packet_type_establish_session
HIDDEN fr_dict_attr_t const * attr_tls_session_cipher_suite
HIDDEN fr_dict_attr_t const * attr_tls_psk_identity
HIDDEN fr_dict_attr_t const * attr_tls_session_cert_file
talloc_free(reap)
@ L_DBG_LVL_3
3rd highest priority debug messages (-xxx | -Xx).
Definition log.h:72
@ L_DBG
Only displayed when debugging is enabled.
Definition log.h:59
ssize_t xlat_eval(char *out, size_t outlen, request_t *request, char const *fmt, xlat_escape_legacy_t escape, void const *escape_ctx)
unsigned char uint8_t
#define UINT8_MAX
static size_t used
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
Definition misc.h:59
static uint16_t fr_nbo_to_uint16(uint8_t const data[static sizeof(uint16_t)])
Read an unsigned 16bit integer from wire format (big endian)
Definition nbo.h:146
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition pair.c:2321
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2637
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, UNUSED bool tainted)
Convert string value to native attribute value.
Definition pair.c:2591
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.
Definition pair.c:695
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
#define fr_assert(_expr)
Definition rad_assert.h:38
#define pair_update_request(_attr, _da)
#define REDEBUG(fmt,...)
Definition radclient.h:52
#define RDEBUG_ENABLED2()
Definition radclient.h:50
#define RDEBUG2(fmt,...)
Definition radclient.h:54
#define DEBUG2(fmt,...)
Definition radclient.h:43
static rs_t * conf
Definition radsniff.c:53
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:40
#define FR_SBUFF_IN(_start, _len_or_end)
#define pair_prepend_request(_attr, _da)
Allocate and prepend a fr_pair_t to the request list.
Definition pair.h:77
#define pair_update_session_state(_attr, _da)
Return or allocate a fr_pair_t in the session_state list.
Definition pair.h:151
#define tmpl_aexpand(_ctx, _out, _request, _vpt, _escape, _escape_ctx)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
Definition tmpl.h:1062
fr_signal_t
Signals that can be generated/processed by request signal handlers.
Definition signal.h:38
@ FR_SIGNAL_CANCEL
Request has been cancelled.
Definition signal.h:40
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
fr_pair_t * vp
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
request_t * unlang_subrequest_alloc(request_t *parent, fr_dict_t const *namespace)
Allocate a subrequest to run through a virtual server at some point in the future.
Definition subrequest.c:287
int unlang_subrequest_child_push(rlm_rcode_t *out, request_t *child, unlang_subrequest_session_t const *session, bool free_child, bool top_frame)
Push a pre-existing child back onto the stack as a subrequest.
close(uq->fd)
static fr_slen_t parent
Definition pair.h:845
static fr_slen_t data
Definition value.h:1274
static size_t char fr_sbuff_t size_t inlen
Definition value.h:1012
static size_t char ** out
Definition value.h:1012