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: f6233b420ee62997bd5ef63f5d297f421a8b936a $
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/skip.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 uint8_t const *session_id;
1172 unsigned int len;
1173
1174 MEM(child = unlang_subrequest_alloc(request, dict_tls));
1175 request = child;
1176
1177 /*
1178 * Setup the child request for reporting session
1179 */
1181 vp->vp_uint32 = enum_tls_packet_type_establish_session->vb_uint32;
1182
1183 session_id = SSL_SESSION_get_id(tls_session->session, &len);
1184 if (session_id && (len > 0)) {
1186 fr_pair_value_memdup(vp, session_id, len, false);
1187 }
1188
1189 /*
1190 * Allocate a child, and set it up to call
1191 * the TLS virtual server.
1192 */
1193 ua = fr_tls_call_push(child, tls_establish_session_result, conf, tls_session, false);
1194 if (ua < 0) {
1195 talloc_free(child);
1196 return UNLANG_ACTION_FAIL;
1197 }
1198
1199 return ua;
1200}
1201
1202/** Finish off a handshake round, possibly adding attributes to the request
1203 *
1204 */
1205static unlang_action_t tls_session_async_handshake_done_round(UNUSED rlm_rcode_t *p_result, UNUSED int *priority,
1206 request_t *request, void *uctx)
1207{
1208 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1209 int ret;
1210
1211 RDEBUG3("entered state %s", __FUNCTION__);
1212
1213 /*
1214 * This only occurs once per session, where calling
1215 * SSL_read updates the state of the SSL session, setting
1216 * this flag to true.
1217 *
1218 * Callbacks provide enough info so we don't need to
1219 * print debug statements when the handshake is in other
1220 * states.
1221 */
1222 if (SSL_is_init_finished(tls_session->ssl)) {
1223 SSL_CIPHER const *cipher;
1224 fr_pair_t *vp;
1225 char const *version;
1226
1227 char cipher_desc[256], cipher_desc_clean[256];
1228 char *p = cipher_desc, *q = cipher_desc_clean;
1229
1230 cipher = SSL_get_current_cipher(tls_session->ssl);
1231 SSL_CIPHER_description(cipher, cipher_desc, sizeof(cipher_desc));
1232
1233 /*
1234 * Cleanup the output from OpenSSL
1235 * Seems to print info in a tabular format.
1236 */
1237 while (*p != '\0') {
1238 if (isspace((uint8_t) *p)) {
1239 *q++ = *p;
1241 continue;
1242 }
1243 *q++ = *p++;
1244 }
1245 *q = '\0';
1246
1247 RDEBUG2("Cipher suite: %s", cipher_desc_clean);
1248
1249 RDEBUG2("Adding TLS session information to request");
1250 RINDENT();
1252 fr_pair_value_strdup(vp, SSL_CIPHER_get_name(cipher), false);
1253 RDEBUG2("session-state.%pP", vp);
1254
1255 if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
1256 !tls_version_str[tls_session->info.version]) {
1257 version = "UNKNOWN";
1258 } else {
1259 version = tls_version_str[tls_session->info.version];
1260 }
1261
1263 fr_pair_value_strdup(vp, version, false);
1264 RDEBUG2("session-state.%pP", vp);
1265 REXDENT();
1266
1267 /*
1268 * Cache the SSL_SESSION pointer.
1269 *
1270 * Which contains all the data we need for session resumption.
1271 */
1272 if (!tls_session->session) {
1273 tls_session->session = SSL_get_session(tls_session->ssl);
1274 if (!tls_session->session) {
1275 REDEBUG("Failed getting TLS session");
1276 error:
1277 tls_session->result = FR_TLS_RESULT_ERROR;
1278 fr_tls_session_request_unbind(tls_session->ssl);
1280 }
1281 }
1282
1283 if (RDEBUG_ENABLED3) {
1284 if (SSL_SESSION_print(fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3),
1285 tls_session->session) != 1) {
1286 } else {
1287 RDEBUG3("Failed retrieving session data");
1288 }
1289 }
1290
1291 /*
1292 * Session was resumed, add attribute to mark it as such.
1293 */
1294 if (SSL_session_reused(tls_session->ssl)) {
1295 /*
1296 * Mark the request as resumed.
1297 */
1299 vp->vp_bool = true;
1300 }
1301 }
1302
1303 /*
1304 * Get data to pack and send back to the TLS peer.
1305 */
1306 ret = BIO_ctrl_pending(tls_session->from_ssl);
1307 if (ret > 0) {
1308 ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1309 sizeof(tls_session->dirty_out.data));
1310 if (ret > 0) {
1311 tls_session->dirty_out.used = ret;
1312 } else if (BIO_should_retry(tls_session->from_ssl)) {
1313 record_init(&tls_session->dirty_in);
1314 RDEBUG2("Asking for more data in tunnel");
1315
1316 } else {
1317 fr_tls_log(NULL, NULL);
1318 record_init(&tls_session->dirty_in);
1319 goto error;
1320 }
1321 } else {
1322 /* Its clean application data, do whatever we want */
1323 record_init(&tls_session->clean_out);
1324 }
1325
1326 /*
1327 * Trash the current data in dirty_out, and synthesize
1328 * a TLS error record.
1329 *
1330 * OpensSL annoyingly provides no mechanism for us to
1331 * send alerts, and we need to send alerts as part of
1332 * RFC 5216, so this is our only option.
1333 */
1334 if (tls_session->pending_alert) fr_tls_session_alert_send(request, tls_session);
1335
1336 /* We are done with dirty_in, reinitialize it */
1337 record_init(&tls_session->dirty_in);
1338
1339 tls_session->result = FR_TLS_RESULT_SUCCESS;
1340 fr_tls_session_request_unbind(tls_session->ssl);
1341 if (SSL_is_init_finished(tls_session->ssl)) {
1342 fr_tls_conf_t *conf = fr_tls_session_conf(tls_session->ssl);
1343 if (conf->establish_session) return tls_establish_session_push(request, conf, tls_session);
1344 }
1346}
1347
1348/** Try very hard to get the SSL * into a consistent state where it's not yielded
1349 *
1350 * ...because if it's yielded, we'll probably leak thread contexts and all kinds of memory.
1351 *
1352 * @param[in] request being cancelled.
1353 * @param[in] action we're being signalled with.
1354 * @param[in] uctx the SSL * to cancel.
1355 */
1356static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
1357{
1358 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1359 int ret;
1360
1361 /*
1362 * We might want to set can_pause = false here
1363 * but that would trigger asserts in the
1364 * cache code.
1365 */
1366
1367 /*
1368 * If SSL_get_error returns SSL_ERROR_WANT_ASYNC
1369 * it means we're yielded in the middle of a
1370 * callback.
1371 *
1372 * Keep calling SSL_read() in a loop until we
1373 * no longer get SSL_ERROR_WANT_ASYNC, then
1374 * shut it down so it's in a consistent state.
1375 *
1376 * It'll get freed later when the request is
1377 * freed.
1378 */
1379 for (ret = tls_session->last_ret;
1380 SSL_get_error(tls_session->ssl, ret) == SSL_ERROR_WANT_ASYNC;
1381 ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1382 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used));
1383
1384 /*
1385 * Unbind the cancelled request from the SSL *
1386 */
1387 fr_tls_session_request_unbind(tls_session->ssl);
1388}
1389
1390/** Call SSL_read() to continue the TLS state machine
1391 *
1392 * This function may be called multiple times, once after every asynchronous request.
1393 *
1394 * @param[in,out] p_result UNUSED.
1395 * @param[out] priority UNUSED
1396 * @param[in] request The current request.
1397 * @param[in] uctx #fr_tls_session_t to continue.
1398 * @return
1399 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1400 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1401 */
1402static unlang_action_t tls_session_async_handshake_cont(rlm_rcode_t *p_result, int *priority,
1403 request_t *request, void *uctx)
1404{
1405 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1406 int err;
1407
1408 RDEBUG3("(re-)entered state %s", __FUNCTION__);
1409
1410 /*
1411 * Clear OpenSSL's thread local error stack.
1412 *
1413 * Why do we need to do this here? Although SSL_get_error
1414 * takes an `SSL *`, which would make you _think_ it was
1415 * operating on the error stack for that SSL, it will also
1416 * return SSL_ERROR_SSL if there are any errors in the stack.
1417 *
1418 * When operating normally SSL_read() can return < 0, to
1419 * indicate it wants more data, or that we need to perform
1420 * asynchronous processing.
1421 *
1422 * If spurious errors have been left on the thread local
1423 * stack they MUST be cleared before we can call SSL_get_error
1424 * otherwise stale errors mask the async notifications
1425 * and cause random handshake failures.
1426 */
1427 ERR_clear_error();
1428
1429 /*
1430 * Magic/More magic? Although SSL_read is normally
1431 * used to read application data, it will also
1432 * continue the TLS handshake. Removing this call will
1433 * cause the handshake to fail.
1434 *
1435 * We don't ever expect to actually *receive* application
1436 * data here.
1437 *
1438 * The reason why we call SSL_read instead of SSL_accept,
1439 * or SSL_connect, as it allows this function
1440 * to be used, irrespective or whether we're acting
1441 * as a client or a server.
1442 *
1443 * If acting as a client SSL_set_connect_state must have
1444 * been called before this function.
1445 *
1446 * If acting as a server SSL_set_accept_state must have
1447 * been called before this function.
1448 */
1449 tls_session->can_pause = true;
1450 tls_session->last_ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1451 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used);
1452 tls_session->can_pause = false;
1453 if (tls_session->last_ret > 0) {
1454 tls_session->clean_out.used += tls_session->last_ret;
1455
1456 /*
1457 * Round successful, and we don't need to do any
1458 * further processing.
1459 */
1460 tls_session->result = FR_TLS_RESULT_SUCCESS;
1461 finish:
1462 /*
1463 * Was bound by caller
1464 */
1465 fr_tls_session_request_unbind(tls_session->ssl);
1467 }
1468
1469 /*
1470 * Bug in OpenSSL 3.0 - Normal handshaking behaviour
1471 * results in spurious "BIO_R_UNSUPPORTED_METHOD"
1472 * errors.
1473 *
1474 * SSL_get_error apparently returns SSL_ERROR_SSL if
1475 * there are any errors in the stack. This masks
1476 * SSL_ERROR_WANT_ASYNC and causes the handshake to
1477 * fail.
1478 *
1479 * Note: We may want some version of this code
1480 * included for all OpenSSL versions.
1481 *
1482 * It would call ERR_GET_FATAL() on each of the errors
1483 * in the stack to drain non-fatal errors and prevent
1484 * the other (more useful) return codes of
1485 * SSL_get_error from being masked. I guess we'll see
1486 * if this occurs in other scenarios.
1487 */
1488 if (SSL_get_error(tls_session->ssl, tls_session->last_ret) == SSL_ERROR_SSL) {
1489 unsigned long ssl_err;
1490
1491 /*
1492 * Some weird OpenSSL thing marking ERR_GET_REASON
1493 * as "unused". Unclear why this is done as it's
1494 * not deprecated.
1495 */
1497DIAG_OFF(used-but-marked-unused)
1498 while ((ssl_err = ERR_peek_error()) && (ERR_GET_REASON(ssl_err) == BIO_R_UNSUPPORTED_METHOD)) {
1499 (void) ERR_get_error();
1500 }
1501DIAG_ON(used-but-marked-unused)
1503 }
1504
1505 /*
1506 * Deal with asynchronous requests from OpenSSL.
1507 * These aren't actually errors, they're the
1508 * result of one of our callbacks indicating that
1509 * it'd like to perform the operation
1510 * asynchronously.
1511 */
1512 switch (err = SSL_get_error(tls_session->ssl, tls_session->last_ret)) {
1513 case SSL_ERROR_WANT_ASYNC: /* Certification validation or cache loads */
1514 {
1515 unlang_action_t ua;
1516
1517 RDEBUG3("Performing async action for libssl");
1518
1519 /*
1520 * Call this function again once we're done
1521 * asynchronously satisfying the load request.
1522 */
1523 if (unlikely(unlang_function_repeat_set(request, tls_session_async_handshake_cont) < 0)) {
1524 error:
1525 tls_session->result = FR_TLS_RESULT_ERROR;
1526 goto finish;
1527 }
1528
1529 /*
1530 * First service any pending cache actions
1531 */
1532 ua = fr_tls_cache_pending_push(request, tls_session);
1533 switch (ua) {
1534 case UNLANG_ACTION_FAIL:
1535 IGNORE(unlang_function_clear(request), int);
1536 goto error;
1537
1539 return ua;
1540
1541 default:
1542 break;
1543 }
1544
1545 /*
1546 * Next service any pending certificate
1547 * validation actions.
1548 */
1549 ua = fr_tls_verify_cert_pending_push(request, tls_session);
1550 switch (ua) {
1551 case UNLANG_ACTION_FAIL:
1552 IGNORE(unlang_function_clear(request), int);
1553 goto error;
1554
1555 default:
1556 return ua;
1557 }
1558 }
1559
1560 case SSL_ERROR_WANT_ASYNC_JOB:
1561 RERROR("No async jobs available in pool, increase thread.openssl_async_pool_max");
1562 goto error;
1563
1564 default:
1565 /*
1566 * Returns 0 if we can continue processing the handshake
1567 * Returns -1 if we encountered a fatal error.
1568 */
1569 if (fr_tls_log_io_error(request,
1570 err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
1571 return tls_session_async_handshake_done_round(p_result, priority, request, uctx);
1572 }
1573}
1574
1575/** Ingest data for another handshake round
1576 *
1577 * Advance the TLS handshake by feeding OpenSSL data from dirty_in,
1578 * and reading data from OpenSSL into dirty_out.
1579 *
1580 * Calls #tls_session_async_handshake_read to perform the actual ingestion.
1581 * #tls_session_async_handshake_read is split out because we may need to call
1582 * it multiple times, once after every async action.
1583 *
1584 * @param[in,out] p_result UNUSED.
1585 * @param[out] priority UNUSED
1586 * @param[in] request The current request.
1587 * @param[in] uctx #fr_tls_session_t to continue.
1588 * @return
1589 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1590 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1591 */
1592static unlang_action_t tls_session_async_handshake(rlm_rcode_t *p_result, int *priority,
1593 request_t *request, void *uctx)
1594{
1595 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1596 int ret;
1597
1598 RDEBUG3("entered state %s", __FUNCTION__);
1599
1600 tls_session->result = FR_TLS_RESULT_IN_PROGRESS;
1601
1602 fr_tls_session_request_bind(tls_session->ssl, request); /* May be unbound in this function or asynchronously */
1603
1604 /*
1605 * This is a logic error. fr_tls_session_async_handshake
1606 * must not be called if the handshake is
1607 * complete fr_tls_session_recv must be
1608 * called instead.
1609 */
1610 if (SSL_is_init_finished(tls_session->ssl)) {
1611 REDEBUG("Attempted to continue TLS handshake, but handshake has completed");
1612 error:
1613 tls_session->result = FR_TLS_RESULT_ERROR;
1614 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1616 }
1617
1618 if (tls_session->invalid) {
1619 REDEBUG("Preventing invalid session from continuing");
1620 goto error;
1621 }
1622
1623 /*
1624 * Feed dirty data into OpenSSL, so that is can either
1625 * process it as Application data (decrypting it)
1626 * or continue the TLS handshake.
1627 */
1628 if (tls_session->dirty_in.used) {
1629 ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
1630 if (ret != (int)tls_session->dirty_in.used) {
1631 REDEBUG("Failed writing %zu bytes to TLS BIO: %d", tls_session->dirty_in.used, ret);
1632 record_init(&tls_session->dirty_in);
1633 goto error;
1634 }
1635 record_init(&tls_session->dirty_in);
1636 }
1637
1638 return tls_session_async_handshake_cont(p_result, priority, request, uctx); /* Must unbind request, possibly asynchronously */
1639}
1640
1641/** Push a handshake call onto the stack
1642 *
1643 * We push the handshake frame (as opposed to having the caller do it),
1644 * so that we guarantee there's a frame that the handshake function can
1645 * manipulate to manage its own state.
1646 *
1647 * The result of processing this handshake round can be found in
1648 * tls_session->result.
1649 *
1650 * @param[in] request The current request.
1651 * @param[in] tls_session to continue handshaking.
1652 * @return
1653 * - UNLANG_ACTION_PUSHED_CHILD on success.
1654 * - UNLANG_ACTION_FAIL on failure.
1655 */
1656unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
1657{
1658 return unlang_function_push(request,
1659 tls_session_async_handshake,
1660 NULL,
1661 tls_session_async_handshake_signal,
1664 tls_session);
1665}
1666
1667/** Free a TLS session and any associated OpenSSL data
1668 *
1669 * @param session to free.
1670 * @return 0.
1671 */
1672static int _fr_tls_session_free(fr_tls_session_t *session)
1673{
1674 if (session->ssl) {
1675 /*
1676 * The OpenSSL docs state:
1677 *
1678 * SSL_shutdown() can be modified to only set the
1679 * connection to "shutdown" state but not actually
1680 * send the "close notify" alert messages, see
1681 * SSL_CTX_set_quiet_shutdown(3). When "quiet shutdown"
1682 * is enabled, SSL_shutdown() will always succeed and
1683 * return 1.
1684 *
1685 * This is only partially correct. This call does mean
1686 * we don't notify the other party, but the SSL_shutdown
1687 * call can still fail if the handshake hasn't begun, leaving
1688 * spurious errors on the thread local error stack.
1689 */
1690 SSL_set_quiet_shutdown(session->ssl, 1);
1691
1692 /*
1693 * Don't leave spurious errors raised by SSL_shutdown on
1694 * the error stack.
1695 */
1696 if (SSL_shutdown(session->ssl) != 1) ERR_clear_error();
1697
1698 SSL_free(session->ssl);
1699 session->ssl = NULL;
1700 }
1701
1702 return 0;
1703}
1704
1705static void session_init(fr_tls_session_t *session)
1706{
1707 session->ssl = NULL;
1708 session->into_ssl = session->from_ssl = NULL;
1709 record_init(&session->clean_in);
1710 record_init(&session->clean_out);
1711 record_init(&session->dirty_in);
1712 record_init(&session->dirty_out);
1713
1714 memset(&session->info, 0, sizeof(session->info));
1715
1716 session->mtu = 0;
1717 session->opaque = NULL;
1718}
1719
1720/** Create a new client TLS session
1721 *
1722 * Configures a new client TLS session, configuring options, setting callbacks etc...
1723 *
1724 * @param[in] ctx to alloc session data in. Should usually be NULL unless the lifetime of the
1725 * session is tied to another talloc'd object.
1726 * @param[in] ssl_ctx containing the base configuration for this session.
1727 * @return
1728 * - A new session on success.
1729 * - NULL on error.
1730 */
1731fr_tls_session_t *fr_tls_session_alloc_client(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx)
1732{
1733 int verify_mode;
1734 fr_tls_session_t *tls_session = NULL;
1735 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1736
1737 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1738 talloc_set_destructor(tls_session, _fr_tls_session_free);
1739 fr_pair_list_init(&tls_session->extra_pairs);
1740
1741 tls_session->ssl = SSL_new(ssl_ctx);
1742 if (!tls_session->ssl) {
1743 talloc_free(tls_session);
1744 return NULL;
1745 }
1746
1747 /*
1748 * Add the message callback to identify what type of
1749 * message/handshake is passed
1750 */
1751 SSL_set_msg_callback(tls_session->ssl, fr_tls_session_msg_cb);
1752 SSL_set_msg_callback_arg(tls_session->ssl, tls_session);
1753 SSL_set_info_callback(tls_session->ssl, fr_tls_session_info_cb);
1754
1755 /*
1756 * In Client mode we only accept.
1757 *
1758 * This sets up the SSL session to work correctly with
1759 * fr_tls_session_handshake.
1760 */
1761 SSL_set_connect_state(tls_session->ssl);
1762
1763 /*
1764 * Always verify the peer certificate.
1765 */
1766 DEBUG2("Requiring Server certificate");
1767 verify_mode = SSL_VERIFY_PEER;
1768 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1769
1770 /*
1771 * Callback should be fr_tls_verify_cert_cb but this
1772 * requires support around SSL_connect for dealing
1773 * with async.
1774 *
1775 * If the callback is NULL OpenSSL uses its own validation
1776 * function, and the flags modifies that function's
1777 * behaviour.
1778 */
1779 SSL_set_verify(tls_session->ssl, verify_mode, NULL);
1780 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1781 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1782
1783 tls_session->mtu = conf->fragment_size;
1784
1785 return tls_session;
1786}
1787
1788/** Create a new server TLS session
1789 *
1790 * Configures a new server TLS session, configuring options, setting callbacks etc...
1791 *
1792 * @param[in] ctx to alloc session data in. Should usually be NULL
1793 * unless the lifetime of the session is tied to another
1794 * talloc'd object.
1795 * @param[in] ssl_ctx containing the base configuration for this session.
1796 * @param[in] request The current #request_t.
1797 * @param[in] dynamic_mtu If greater than 100, overrides the MTU configured for the SSL_CTX.
1798 * @param[in] client_cert Whether to require a client_cert.
1799 * @return
1800 * - A new session on success.
1801 * - NULL on error.
1802 */
1803fr_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)
1804{
1805 fr_tls_session_t *tls_session = NULL;
1806 SSL *ssl = NULL;
1807 int verify_mode = 0;
1808 fr_pair_t *vp;
1809 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1810
1811 RDEBUG2("Initiating new TLS session");
1812
1813 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1814
1815 ssl = SSL_new(ssl_ctx);
1816 if (ssl == NULL) {
1817 fr_tls_log(request, "Error creating new TLS session");
1818 return NULL;
1819 }
1820 fr_pair_list_init(&tls_session->extra_pairs);
1821
1822 session_init(tls_session);
1823 tls_session->ctx = ssl_ctx;
1824 tls_session->ssl = ssl;
1825 talloc_set_destructor(tls_session, _fr_tls_session_free);
1826
1827 fr_tls_session_request_bind(tls_session->ssl, request); /* Is unbound in this function */
1828
1829 /*
1830 * Initialize callbacks
1831 */
1832 tls_session->record_init = record_init;
1833 tls_session->record_close = record_close;
1834 tls_session->record_from_buff = record_from_buff;
1835 tls_session->record_to_buff = record_to_buff;
1836
1837 /*
1838 * Create & hook the BIOs to handle the dirty side of the
1839 * SSL. This is *very important* as we want to handle
1840 * the transmission part. Now the only IO interface
1841 * that SSL is aware of, is our defined BIO buffers.
1842 *
1843 * This means that all SSL IO is done to/from memory,
1844 * and we can update those BIOs from the packets we've
1845 * received.
1846 */
1847 MEM(tls_session->into_ssl = BIO_new(BIO_s_mem()));
1848 MEM(tls_session->from_ssl = BIO_new(BIO_s_mem()));
1849 SSL_set_bio(tls_session->ssl, tls_session->into_ssl, tls_session->from_ssl);
1850
1851 /*
1852 * Add the message callback to identify what type of
1853 * message/handshake is passed
1854 */
1855 SSL_set_msg_callback(ssl, fr_tls_session_msg_cb);
1856 SSL_set_msg_callback_arg(ssl, tls_session);
1857 SSL_set_info_callback(ssl, fr_tls_session_info_cb);
1858
1859 /*
1860 * This sets the context sessions can be resumed in.
1861 * This is to prevent sessions being created by one application
1862 * and used by another. In our case it prevents sessions being
1863 * reused between modules, or TLS server components such as
1864 * RADSEC.
1865 *
1866 * A context must always be set when doing session resumption
1867 * otherwise session resumption will fail.
1868 *
1869 * As the context ID must be <= 32, we digest the context
1870 * data with sha256.
1871 *
1872 * This seems to only be used for stateful session resumption
1873 * not session-tickets
1874 */
1875 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1876 char *context_id;
1877 EVP_MD_CTX *md_ctx;
1878 uint8_t digest[SHA256_DIGEST_LENGTH];
1879
1880 static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
1881 "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");
1882 fr_assert(conf->cache.id_name);
1883
1884 if (tmpl_aexpand(tls_session, &context_id, request, conf->cache.id_name, NULL, NULL) < 0) {
1885 RPEDEBUG("Failed expanding session ID");
1886 error:
1887 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1888 talloc_free(tls_session);
1889 return NULL;
1890 }
1891
1892 MEM(md_ctx = EVP_MD_CTX_create());
1893 EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
1894 EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
1895 EVP_DigestFinal_ex(md_ctx, digest, NULL);
1896 EVP_MD_CTX_destroy(md_ctx);
1897 talloc_free(context_id);
1898
1899 if (!fr_cond_assert(SSL_set_session_id_context(tls_session->ssl,
1900 digest, sizeof(digest)) == 1)) goto error;
1901 }
1902
1903 /*
1904 * Add the session certificate to the session.
1905 */
1906 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_cert_file);
1907 if (vp) {
1908 RDEBUG2("Loading TLS session certificate \"%pV\"", &vp->data);
1909
1910 if (SSL_use_certificate_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1911 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1912 vp->vp_strvalue);
1913 goto error;
1914 }
1915
1916 if (SSL_use_PrivateKey_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1917 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1918 vp->vp_strvalue);
1919 goto error;
1920 }
1921
1922 if (SSL_check_private_key(tls_session->ssl) != 1) {
1923 fr_tls_log(request, "Failed validating TLS session certificate \"%s\"",
1924 vp->vp_strvalue);
1925 goto error;
1926 }
1927 /*
1928 * Better to perform explicit checks, than rely
1929 * on OpenSSL's opaque error messages.
1930 */
1931 } else {
1932 if (!conf->chains || !conf->chains[0]->private_key_file) {
1933 ERROR("TLS Server requires a private key file");
1934 goto error;
1935 }
1936
1937 if (!conf->chains || !conf->chains[0]->certificate_file) {
1938 ERROR("TLS Server requires a certificate file");
1939 goto error;
1940 }
1941 }
1942
1943 /** Dynamic toggle for allowing disallowing client certs
1944 *
1945 * This is mainly used for testing in environments where we can't
1946 * get test credentials for the host.
1947 */
1948 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_require_client_cert);
1949 if (vp) client_cert = vp->vp_bool;
1950
1951 /*
1952 * In Server mode we only accept.
1953 *
1954 * This sets up the SSL session to work correctly with
1955 * fr_tls_session_handshake.
1956 */
1957 SSL_set_accept_state(tls_session->ssl);
1958
1959 /*
1960 * Verify the peer certificate, if asked.
1961 */
1962 if (client_cert) {
1963 RDEBUG2("Setting verify mode to require certificate from client");
1964 verify_mode = SSL_VERIFY_PEER;
1965 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1966 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1967 }
1968 tls_session->verify_client_cert = client_cert;
1969
1970 SSL_set_verify(tls_session->ssl, verify_mode, fr_tls_verify_cert_cb);
1971 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1972 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1973
1974 tls_session->mtu = conf->fragment_size;
1975 if (dynamic_mtu > 100 && dynamic_mtu < tls_session->mtu) {
1976 RDEBUG2("Setting fragment_len to %zu from dynamic_mtu", dynamic_mtu);
1977 tls_session->mtu = dynamic_mtu;
1978 }
1979
1980 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1981 tls_session->allow_session_resumption = true; /* otherwise it's false */
1982 fr_tls_cache_session_alloc(tls_session);
1983 }
1984
1985 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1986
1987 return tls_session;
1988}
1989
1990static unlang_action_t tls_new_session_result(UNUSED rlm_rcode_t *p_result, UNUSED int *priority, request_t *request, UNUSED void *uctx)
1991{
1992 request_t *parent = request->parent;
1993
1995
1996 /*
1997 * Copy control attributes back to the parent.
1998 */
1999 if (fr_pair_list_copy(parent->control_ctx, &parent->control_pairs, &request->control_pairs) < 0) return UNLANG_ACTION_FAIL;
2000
2002}
2003
2004unlang_action_t fr_tls_new_session_push(request_t *request, fr_tls_conf_t const *tls_conf) {
2005 request_t *child;
2006 fr_pair_t *vp;
2007
2008 MEM(child = unlang_subrequest_alloc(request, dict_tls));
2009 request = child;
2010
2012 vp->vp_uint32 = enum_tls_packet_type_new_session->vb_uint32;
2013
2014 if (unlang_subrequest_child_push(child, NULL, child->parent, true, UNLANG_SUB_FRAME) < 0) {
2015 return UNLANG_ACTION_FAIL;
2016 }
2017 if (unlang_function_push(child, NULL, tls_new_session_result, NULL, 0, UNLANG_SUB_FRAME, NULL) < 0) return UNLANG_ACTION_FAIL;
2018
2019 if (unlang_call_push(child, tls_conf->virtual_server, UNLANG_SUB_FRAME) < 0) {
2020 return UNLANG_ACTION_FAIL;
2021 }
2023}
2024#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:840
static fr_slen_t in
Definition dict.h:840
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_id
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
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:2329
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition pair.c:2945
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2645
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:2599
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:697
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_append_request(_attr, _da)
Allocate and append a fr_pair_t to the request list.
Definition pair.h:37
#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
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
Definition skip.h:37
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
int unlang_subrequest_child_push(request_t *child, rlm_rcode_t *p_result, void const *unique_session_ptr, bool free_child, bool top_frame)
Push a pre-existing child back onto the stack as a subrequest.
Definition subrequest.c:422
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:303
close(uq->fd)
static fr_slen_t parent
Definition pair.h:845
static fr_slen_t data
Definition value.h:1288
static size_t char fr_sbuff_t size_t inlen
Definition value.h:1020
static size_t char ** out
Definition value.h:1020