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: 4951dab20b96f988e540e68bb9f0f40a410307b5 $
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
554 if (request) {
556 vp->vp_uint8 = ret & 0xff;
557 RDEBUG2("TLS-Client-Error-Code := %pV", &vp->data);
558 }
559 /*
560 * We're sending the client an alert.
561 */
562 } else {
563 ROPTIONAL(REDEBUG, ERROR, "Sending client %s TLS alert (%i) - %s",
564 SSL_alert_type_string_long(ret), ret & 0xff, SSL_alert_desc_string_long(ret));
565
566 /*
567 * Offer helpful advice... Should be expanded.
568 */
569 switch (ret & 0xff) {
570 case TLS1_AD_PROTOCOL_VERSION:
571 ROPTIONAL(REDEBUG, ERROR, "Client requested a TLS protocol version that is not "
572 "enabled or not supported. Upgrade FreeRADIUS + OpenSSL to their latest "
573 "versions and/or adjust 'tls_max_version'/'tls_min_version' if you want "
574 "authentication to succeed");
575 break;
576
577 default:
578 break;
579 }
580 }
581 return;
582 }
583
584 if (where & SSL_CB_EXIT) {
585 if (ret == 0) {
586 ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
587 return;
588 }
589
590 if (ret < 0) {
591 if (SSL_want_read(ssl)) {
592 RDEBUG2("Need more data from client"); /* State same as previous call, don't print */
593 return;
594 }
595 ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
596 }
597 }
598}
599DIAG_ON(used-but-marked-unused)
601
602/** Print a message to the request or global log detailing handshake state
603 *
604 * @param[in] request The current #request_t.
605 * @param[in] tls_session The current TLS session.
606 */
607static void session_msg_log(request_t *request, fr_tls_session_t *tls_session, uint8_t const *data, size_t data_len)
608{
609 char const *version, *content_type;
610 char const *str_details1 = NULL;
611 char const *str_details2 = NULL;
612 char unknown_version[32];
613 char unknown_content_type[32];
614 char unknown_alert_level[32];
615 char unknown_alert_description[32];
616 char unknown_handshake_type[32];
617
618 /*
619 * Don't print this out in the normal course of
620 * operations.
621 */
623
624 if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
625 !tls_version_str[tls_session->info.version]) {
626 snprintf(unknown_version, sizeof(unknown_version), "unknown_tls_version_0x%04x",
627 (unsigned int) tls_session->info.version);
628 version = unknown_version;
629 } else {
630 version = tls_version_str[tls_session->info.version];
631 }
632
633 /*
634 * TLS 1.0, 1.1, 1.2 content types are the same as SSLv3
635 */
636 if (((size_t)tls_session->info.content_type >= NUM_ELEMENTS(tls_content_type_str)) ||
637 !tls_content_type_str[tls_session->info.content_type]) {
638 snprintf(unknown_content_type, sizeof(unknown_content_type),
639 "unknown_content_type_0x%04x", (unsigned int) tls_session->info.content_type);
640 content_type = unknown_content_type;
641 } else {
642 content_type = tls_content_type_str[tls_session->info.content_type];
643 }
644
645 if (tls_session->info.content_type == SSL3_RT_ALERT) {
646 if (tls_session->info.record_len == 2) {
647 switch (tls_session->info.alert_level) {
648 case SSL3_AL_WARNING:
649 str_details1 = "warning";
650 break;
651 case SSL3_AL_FATAL:
652 str_details1 = "fatal";
653 break;
654
655 default:
656 snprintf(unknown_alert_level, sizeof(unknown_alert_level),
657 "unknown_alert_level_0x%04x", tls_session->info.alert_level);
658 str_details1 = unknown_alert_level;
659 break;
660 }
661
662 if (((size_t)tls_session->info.alert_description >= NUM_ELEMENTS(tls_alert_description_str)) ||
663 !tls_alert_description_str[tls_session->info.alert_description]) {
664 snprintf(unknown_alert_description, sizeof(unknown_alert_description),
665 "unknown_alert_0x%04x", tls_session->info.alert_description);
666 str_details2 = unknown_alert_description;
667 } else {
668 str_details2 = tls_alert_description_str[tls_session->info.alert_description];
669 }
670 } else {
671 str_details1 = "unknown_alert_level";
672 str_details2 = "unknown_alert";
673 }
674 }
675
676 if ((size_t)tls_session->info.content_type == SSL3_RT_HANDSHAKE) {
677 if (tls_session->info.record_len > 0) {
678 /*
679 * Range guard not needed due to size of array
680 * and underlying type.
681 */
682 if (!tls_handshake_type_str[tls_session->info.handshake_type]) {
683 snprintf(unknown_handshake_type, sizeof(unknown_handshake_type),
684 "unknown_handshake_type_0x%02x", tls_session->info.handshake_type);
685 str_details1 = unknown_handshake_type;
686 } else {
687 str_details1 = tls_handshake_type_str[tls_session->info.handshake_type];
688 }
689 }
690 }
691
692 snprintf(tls_session->info.info_description, sizeof(tls_session->info.info_description),
693 "%s %s, %s[length %lu]%s%s%s%s",
694 tls_session->info.origin ? ">>> send" : "<<< recv",
695 version,
696 content_type,
697 (unsigned long)tls_session->info.record_len,
698 str_details1 ? ", " : "",
699 str_details1 ? str_details1 : "",
700 str_details2 ? ", " : "",
701 str_details2 ? str_details2 : "");
702
703 /*
704 * Print out information about the record and print the
705 * data at higher debug levels.
706 */
708 ROPTIONAL(RHEXDUMP4, HEXDUMP4, data, data_len, "%s", tls_session->info.info_description);
709 } else {
710 ROPTIONAL(RDEBUG2, DEBUG2, "%s", tls_session->info.info_description);
711 }
712}
713
714/** Record the progression of the TLS handshake
715 *
716 * This callback is called by OpenSSL whenever a protocol message relating to a handshake is sent
717 * or received.
718 *
719 * This function copies state information from the various arguments into the state->info
720 * structure of the #fr_tls_session_t, to allow us to track the progression of the handshake.
721 *
722 * @param[in] write_p
723 * - 0 when a message has been received.
724 * - 1 when a message has been sent.
725 *
726 * @param[in] msg_version The TLS version negotiated, should be one of:
727 * - TLS1_VERSION
728 * - TLS1_1_VERSION
729 * - TLS1_2_VERSION
730 * - TLS1_3_VERSION
731 *
732 * @param[in] content_type One of the contentType values defined for TLS:
733 * - SSL3_RT_CHANGE_CIPHER_SPEC (20)
734 * - SSL3_RT_ALERT (21)
735 * - SSL3_RT_HANDSHAKE (22)
736 * - TLS1_RT_HEARTBEAT (24)
737 *
738 * @param[in] inbuf The raw protocol message.
739 * @param[in] len Length of the raw protocol message.
740 * @param[in] ssl The SSL session.
741 * @param[in] arg The #fr_tls_session_t holding the SSL session.
742 */
743void fr_tls_session_msg_cb(int write_p, int msg_version, int content_type,
744 void const *inbuf, size_t len,
745 SSL *ssl, void *arg)
746{
747 uint8_t const *buf = inbuf;
748 fr_tls_session_t *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
749 request_t *request = fr_tls_session_request(tls_session->ssl);
750
751 /*
752 * Mostly to check for memory corruption...
753 */
754 if (!fr_cond_assert(tls_session->ssl == ssl)) {
755 ROPTIONAL(REDEBUG, ERROR, "fr_tls_session_t and ssl arg do not match in fr_tls_session_msg_cb");
756 tls_session->invalid = true;
757 return;
758 }
759
760 /*
761 * As per https://tools.ietf.org/html/rfc7568
762 *
763 * We explicitly disable SSLv2/v3, hence the asserts.
764 */
765#ifdef SSL2_VERSION
766 if (!fr_cond_assert(msg_version != SSL2_VERSION)) {
767 ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv2) in handshake");
768 tls_session->invalid = true;
769 return;
770 }
771#endif
772
773#ifdef SSL3_VERSION
774 if (!fr_cond_assert(msg_version != SSL3_VERSION)) {
775 ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv3) in handshake");
776 tls_session->invalid = true;
777 return;
778 }
779#endif
780
781 /*
782 * OpenSSL >= 1.0.2 calls this function with 'pseudo'
783 * content types. Which breaks our tracking of
784 * the SSL Session state.
785 */
786 if ((msg_version == 0) && (content_type > UINT8_MAX)) {
787 ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with pseudo content type %i, version %i",
788 content_type, msg_version);
789 return;
790 }
791
792 if ((write_p != 0) && (write_p != 1)) {
793 ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with invalid write_p %d", write_p);
794 return;
795 }
796
797 /*
798 * 0 - received (from peer)
799 * 1 - sending (to peer)
800 */
801 tls_session->info.origin = write_p;
802 tls_session->info.content_type = content_type;
803 tls_session->info.record_len = len;
804 tls_session->info.version = msg_version;
805 tls_session->info.initialized = true;
806
807 switch (content_type) {
808 case SSL3_RT_ALERT:
809 if (len < 2) {
810 ROPTIONAL(REDEBUG, ERROR, "Invalid TLS Alert. Closing connection");
811 tls_session->invalid = true;
812 return;
813 }
814
815 tls_session->info.alert_level = buf[0];
816 tls_session->info.alert_description = buf[1];
817 tls_session->info.handshake_type = 0x00;
818 break;
819
820 case SSL3_RT_HANDSHAKE:
821 tls_session->info.handshake_type = buf[0];
822 tls_session->info.alert_level = 0x00;
823 tls_session->info.alert_description = 0x00;
824 break;
825
826#ifdef SSL3_RT_HEARTBEAT
827 case TLS1_RT_HEARTBEAT:
828 uint8_t *p = buf;
829
830 if ((len >= 3) && (p[0] == 1)) {
831 size_t payload_len;
832
833 payload_len = fr_nbo_to_uint16(p + 1);
834 if ((payload_len + 3) > len) {
835 tls_session->invalid = true;
836 ROPTIONAL(REDEBUG, ERROR, "OpenSSL Heartbeat attack detected. Closing connection");
837 return;
838 }
839 }
840 break;
841#endif
842 default:
843 break;
844 }
845
846 session_msg_log(request, tls_session, (uint8_t const *)inbuf, len);
847
848#ifndef OPENSSL_NO_SSL_TRACE
850 SSL_trace(tls_session->info.origin,
851 tls_session->info.version,
852 tls_session->info.content_type,
853 inbuf, len,
854 ssl,
855 request ?
856 fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3) :
857 fr_tls_global_log_bio(L_DBG, L_DBG_LVL_3));
858 }
859#endif
860}
861
862/*
863 * By setting the environment variable SSLKEYLOGFILE to a filename keying
864 * material will be exported that you may use with Wireshark to decode any
865 * TLS flows. Please see the following for more details:
866 *
867 * https://gitlab.com/wireshark/wireshark/-/wikis/TLS#tls-decryption
868 *
869 * An example logging session is (you should delete the file on each run):
870 *
871 * rm -f /tmp/sslkey.log; env SSLKEYLOGFILE=/tmp/sslkey.log freeradius -X | tee /tmp/debug
872 *
873 * Note that we rely on the OS to check file permissions. If the
874 * caller can run radiusd, then they can only write to files which
875 * they own. If radiusd is running as root, then only root can
876 * change the environment variables for radiusd.
877 */
878void fr_tls_session_keylog_cb(const SSL *ssl, const char *line)
879{
880 int fd;
881 size_t len;
882 const char *filename;
883 char buffer[64 + 2*SSL3_RANDOM_SIZE + 2*SSL_MAX_MASTER_KEY_LENGTH];
884
885 /*
886 * Prefer the environment variable definition to the
887 * configuration file. This allows for "one-shot"
888 * dumping of EAP keys when you know you're not using
889 * RadSec, and you don't want to edit the configuration.
890 */
891 filename = getenv("SSLKEYLOGFILE");
892 if (!filename) {
893 fr_tls_conf_t *conf;
894
895 conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
896 if (!conf || !conf->keylog_file || !*conf->keylog_file) return;
897
898 filename = conf->keylog_file;
899 }
900
901 /*
902 * We write all of the data at once. This is *generally*
903 * atomic on most systems.
904 */
905 len = strlen(line);
906 if ((len + 1) > sizeof(buffer)) {
907 DEBUG("SSLKEYLOGFILE buffer not large enough, max %lu, required %lu", sizeof(buffer), len + 1);
908 return;
909 }
910
911 /*
912 * Add a \n, which means that in order to write() the
913 * buffer AND the trailing \n, we have to place both
914 * strings into the same buffer.
915 */
916 memcpy(buffer, line, len);
917 buffer[len] = '\n';
918
919 fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
920 if (fd < 0) {
921 DEBUG("Failed to open file %s: %s", filename, strerror(errno));
922 return;
923 }
924
925 /*
926 * This should work in most situations.
927 */
928 if (write(fd, buffer, len + 1) < 0) {
929 DEBUG("Failed to write to file %s: %s", filename, strerror(errno));
930 }
931
932 close(fd);
933}
934
935/** Decrypt application data
936 *
937 * @note Handshake must have completed before this function may be called.
938 *
939 * Feed data from dirty_in to OpenSSL, and read the clean data into clean_out.
940 *
941 * @param[in] request The current #request_t.
942 * @param[in] tls_session The current TLS session.
943 * @return
944 * - -1 on error.
945 * - 1 if more fragments are required to fully reassemble the record for decryption.
946 * - 0 if we decrypted a complete record.
947 */
948int fr_tls_session_recv(request_t *request, fr_tls_session_t *tls_session)
949{
950 int ret;
951
952 fr_tls_session_request_bind(tls_session->ssl, request);
953
954 if (!SSL_is_init_finished(tls_session->ssl)) {
955 REDEBUG("Attempted to read application data before handshake completed");
956 error:
957 ret = -1;
958 goto finish;
959 }
960
961 /*
962 * Decrypt the complete record.
963 */
964 if (tls_session->dirty_in.used) {
965 ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
966 if (ret != (int) tls_session->dirty_in.used) {
967 REDEBUG("Failed writing %zu bytes to SSL BIO: %d", tls_session->dirty_in.used, ret);
968 record_init(&tls_session->dirty_in);
969 goto error;
970 }
971
972 record_init(&tls_session->dirty_in);
973 }
974
975 /*
976 * Clear the dirty buffer now that we are done with it
977 * and init the clean_out buffer to store decrypted data
978 */
979 record_init(&tls_session->clean_out);
980
981 /*
982 * Prevent spurious errors on the thread local error
983 * stack causing SSL_get_error() to return SSL_ERROR_SSL
984 * instead of what of the SSL_ERROR_WANT_* values.
985 */
986 ERR_clear_error();
987
988 /*
989 * Read (and decrypt) the tunneled data from the
990 * SSL session, and put it into the decrypted
991 * data buffer.
992 */
993 ret = SSL_read(tls_session->ssl, tls_session->clean_out.data, sizeof(tls_session->clean_out.data));
994 if (ret < 0) {
995 int code;
996
997 code = SSL_get_error(tls_session->ssl, ret);
998 switch (code) {
999 case SSL_ERROR_WANT_READ:
1000 RWDEBUG("Peer indicated record was complete, but OpenSSL returned SSL_WANT_READ. "
1001 "Attempting to continue");
1002 ret = 1;
1003 goto finish;
1004
1005 case SSL_ERROR_WANT_WRITE:
1006 REDEBUG("Error in fragmentation logic: SSL_WANT_WRITE");
1007 goto error;
1008
1009 case SSL_ERROR_NONE:
1010 RDEBUG2("No application data received. Assuming handshake is continuing...");
1011 ret = 0;
1012 break;
1013
1014 default:
1015 REDEBUG("Error in fragmentation logic");
1016 fr_tls_log_io_error(request, code, "SSL_read (%s)", __FUNCTION__);
1017 goto error;
1018 }
1019 }
1020
1021 /*
1022 * Passed all checks, successfully decrypted data
1023 */
1024 tls_session->clean_out.used = ret;
1025 ret = 0;
1026
1027 if (RDEBUG_ENABLED3) {
1028 RHEXDUMP3(tls_session->clean_out.data, tls_session->clean_out.used,
1029 "Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1030 } else {
1031 RDEBUG2("Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1032 }
1033finish:
1034 fr_tls_session_request_unbind(tls_session->ssl);
1035
1036 return ret;
1037}
1038
1039/** Encrypt application data
1040 *
1041 * @note Handshake must have completed before this function may be called.
1042 *
1043 * Take cleartext data from clean_in, and feed it to OpenSSL, reading
1044 * the encrypted data into dirty_out.
1045 *
1046 * @param[in] request The current request.
1047 * @param[in] tls_session The current TLS session.
1048 * @return
1049 * - -1 on failure.
1050 * - 0 on success.
1051 */
1052int fr_tls_session_send(request_t *request, fr_tls_session_t *tls_session)
1053{
1054 int ret = 0;
1055
1056 fr_tls_session_request_bind(tls_session->ssl, request);
1057
1058 if (!SSL_is_init_finished(tls_session->ssl)) {
1059 REDEBUG("Attempted to write application data before handshake completed");
1060 ret = -1;
1061 goto finish;
1062 }
1063
1064 /*
1065 * If there's un-encrypted data in 'clean_in', then write
1066 * that data to the SSL session, and then call the BIO function
1067 * to get that encrypted data from the SSL session, into
1068 * a buffer which we can then package into an EAP packet.
1069 *
1070 * Based on Server's logic this clean_in is expected to
1071 * contain the data to send to the client.
1072 */
1073 if (tls_session->clean_in.used > 0) {
1074 /*
1075 * Ensure spurious errors aren't printed
1076 */
1077 ERR_clear_error();
1078
1079 if (RDEBUG_ENABLED3) {
1080 RHEXDUMP3(tls_session->clean_in.data, tls_session->clean_in.used,
1081 "TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1082 } else {
1083 RDEBUG2("TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1084 }
1085
1086 ret = SSL_write(tls_session->ssl, tls_session->clean_in.data, tls_session->clean_in.used);
1087 if (ret < 0) goto log_io_error;
1088 record_to_buff(&tls_session->clean_in, NULL, ret);
1089
1090 /* Get the dirty data from Bio to send it */
1091 ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1092 sizeof(tls_session->dirty_out.data));
1093 if (ret < 0) {
1094 log_io_error:
1095 ret = fr_tls_log_io_error(request, SSL_get_error(tls_session->ssl, ret),
1096 "SSL_write (%s)", __FUNCTION__);
1097 /*
1098 * ret<0 means that we have a real error.
1099 *
1100 * ret=0 means the "error" is SSL_WANT_READ, SSL_WANT_WRITE, etc.
1101 */
1102 } else {
1103 tls_session->dirty_out.used = ret;
1104 ret = 0;
1105 }
1106 }
1107
1108finish:
1109 fr_tls_session_request_unbind(tls_session->ssl);
1110
1111 return ret;
1112}
1113
1114/** Instruct fr_tls_session_async_handshake to create a synthesised TLS alert record and send it to the peer
1115 *
1116 */
1117int fr_tls_session_alert(UNUSED request_t *request, fr_tls_session_t *session, uint8_t level, uint8_t description)
1118{
1119 if (session->alerts_sent > 3) return -1; /* Some kind of state machine brokenness */
1120
1121 /*
1122 * Ignore less severe alerts
1123 */
1124 if (session->pending_alert && (level < session->pending_alert_level)) return 0;
1125
1126 session->pending_alert = true;
1127 session->pending_alert_level = level;
1128 session->pending_alert_description = description;
1129
1130 return 0;
1131}
1132
1133static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *session)
1134{
1135 /*
1136 * Update our internal view of the session
1137 */
1138 session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT;
1139 session->info.content_type = SSL3_RT_ALERT;
1140 session->info.alert_level = session->pending_alert_level;
1141 session->info.alert_description = session->pending_alert_description;
1142
1143 session->dirty_out.data[0] = session->info.content_type;
1144 session->dirty_out.data[1] = 3;
1145 session->dirty_out.data[2] = 1;
1146 session->dirty_out.data[3] = 0;
1147 session->dirty_out.data[4] = 2;
1148 session->dirty_out.data[5] = session->pending_alert_level;
1149 session->dirty_out.data[6] = session->pending_alert_description;
1150
1151 session->dirty_out.used = 7;
1152
1153 session->pending_alert = false;
1154 session->alerts_sent++;
1155
1156 SSL_clear(session->ssl); /* Reset the SSL *, to allow the client to restart the session */
1157
1158 session_msg_log(request, session, session->dirty_out.data, session->dirty_out.used);
1159}
1160
1161/** Process the result of `establish session { ... }`
1162 *
1163 * As this is just a logging session, it's result doesn't affect the parent.
1164 */
1165static unlang_action_t tls_establish_session_result(UNUSED request_t *request, UNUSED void *uctx)
1166{
1168}
1169
1170/** Push an `establish session { ... }` call into the current request, using a subrequest
1171 *
1172 * @param[in] request The current request.
1173 * @param[in] conf TLS configuration.
1174 * @param[in] tls_session The current TLS session.
1175 * @return
1176 * - UNLANG_ACTION_PUSHED_CHILD on success.
1177 * - UNLANG_ACTION_FAIL on failure.
1178 */
1179static inline CC_HINT(always_inline)
1180unlang_action_t tls_establish_session_push(request_t *request, fr_tls_conf_t *conf, fr_tls_session_t *tls_session)
1181{
1182 request_t *child;
1183 fr_pair_t *vp;
1184 unlang_action_t ua;
1185 uint8_t const *session_id;
1186 unsigned int len;
1187
1188 MEM(child = unlang_subrequest_alloc(request, dict_tls));
1189 request = child;
1190
1191 /*
1192 * Setup the child request for reporting session
1193 */
1195 vp->vp_uint32 = enum_tls_packet_type_establish_session->vb_uint32;
1196
1197 session_id = SSL_SESSION_get_id(tls_session->session, &len);
1198 if (session_id && (len > 0)) {
1200 fr_pair_value_memdup(vp, session_id, len, false);
1201 }
1202
1203 /*
1204 * Allocate a child, and set it up to call
1205 * the TLS virtual server.
1206 */
1207 ua = fr_tls_call_push(child, tls_establish_session_result, conf, tls_session, false);
1208 if (ua < 0) {
1209 talloc_free(child);
1210 return UNLANG_ACTION_FAIL;
1211 }
1212
1213 return ua;
1214}
1215
1216/** Finish off a handshake round, possibly adding attributes to the request
1217 *
1218 */
1219static unlang_action_t tls_session_async_handshake_done_round(request_t *request, void *uctx)
1220{
1221 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1222 int ret;
1223
1224 RDEBUG3("entered state %s", __FUNCTION__);
1225
1226 /*
1227 * This only occurs once per session, where calling
1228 * SSL_read updates the state of the SSL session, setting
1229 * this flag to true.
1230 *
1231 * Callbacks provide enough info so we don't need to
1232 * print debug statements when the handshake is in other
1233 * states.
1234 */
1235 if (SSL_is_init_finished(tls_session->ssl)) {
1236 SSL_CIPHER const *cipher;
1237 fr_pair_t *vp;
1238 char const *version;
1239
1240 char cipher_desc[256], cipher_desc_clean[256];
1241 char *p = cipher_desc, *q = cipher_desc_clean;
1242
1243 cipher = SSL_get_current_cipher(tls_session->ssl);
1244 SSL_CIPHER_description(cipher, cipher_desc, sizeof(cipher_desc));
1245
1246 /*
1247 * Cleanup the output from OpenSSL
1248 * Seems to print info in a tabular format.
1249 */
1250 while (*p != '\0') {
1251 if (isspace((uint8_t) *p)) {
1252 *q++ = *p;
1254 continue;
1255 }
1256 *q++ = *p++;
1257 }
1258 *q = '\0';
1259
1260 RDEBUG2("Cipher suite: %s", cipher_desc_clean);
1261
1262 RDEBUG2("Adding TLS session information to request");
1263 RINDENT();
1265 fr_pair_value_strdup(vp, SSL_CIPHER_get_name(cipher), false);
1266 RDEBUG2("session-state.%pP", vp);
1267
1268 if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
1269 !tls_version_str[tls_session->info.version]) {
1270 version = "UNKNOWN";
1271 } else {
1272 version = tls_version_str[tls_session->info.version];
1273 }
1274
1276 fr_pair_value_strdup(vp, version, false);
1277 RDEBUG2("session-state.%pP", vp);
1278 REXDENT();
1279
1280 /*
1281 * Cache the SSL_SESSION pointer.
1282 *
1283 * Which contains all the data we need for session resumption.
1284 */
1285 if (!tls_session->session) {
1286 tls_session->session = SSL_get_session(tls_session->ssl);
1287 if (!tls_session->session) {
1288 REDEBUG("Failed getting TLS session");
1289 error:
1290 tls_session->result = FR_TLS_RESULT_ERROR;
1291 fr_tls_session_request_unbind(tls_session->ssl);
1293 }
1294 }
1295
1296 if (RDEBUG_ENABLED3) {
1297 if (SSL_SESSION_print(fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3),
1298 tls_session->session) != 1) {
1299 RDEBUG3("Failed retrieving session data");
1300 }
1301 }
1302
1303 /*
1304 * Session was resumed, add attribute to mark it as such.
1305 */
1306 if (SSL_session_reused(tls_session->ssl)) {
1307 /*
1308 * Mark the request as resumed.
1309 */
1311 vp->vp_bool = true;
1312 }
1313 }
1314
1315 /*
1316 * Get data to pack and send back to the TLS peer.
1317 */
1318 ret = BIO_ctrl_pending(tls_session->from_ssl);
1319 if (ret > 0) {
1320 ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1321 sizeof(tls_session->dirty_out.data));
1322 if (ret > 0) {
1323 tls_session->dirty_out.used = ret;
1324 } else if (BIO_should_retry(tls_session->from_ssl)) {
1325 record_init(&tls_session->dirty_in);
1326 RDEBUG2("Asking for more data in tunnel");
1327
1328 } else {
1329 fr_tls_log(NULL, NULL);
1330 record_init(&tls_session->dirty_in);
1331 goto error;
1332 }
1333 } else {
1334 /* Its clean application data, do whatever we want */
1335 record_init(&tls_session->clean_out);
1336 }
1337
1338 /*
1339 * Trash the current data in dirty_out, and synthesize
1340 * a TLS error record.
1341 *
1342 * OpensSL annoyingly provides no mechanism for us to
1343 * send alerts, and we need to send alerts as part of
1344 * RFC 5216, so this is our only option.
1345 */
1346 if (tls_session->pending_alert) fr_tls_session_alert_send(request, tls_session);
1347
1348 /* We are done with dirty_in, reinitialize it */
1349 record_init(&tls_session->dirty_in);
1350
1351 tls_session->result = FR_TLS_RESULT_SUCCESS;
1352 fr_tls_session_request_unbind(tls_session->ssl);
1353 if (SSL_is_init_finished(tls_session->ssl)) {
1354 fr_tls_conf_t *conf = fr_tls_session_conf(tls_session->ssl);
1355 if (conf->establish_session) return tls_establish_session_push(request, conf, tls_session);
1356 }
1358}
1359
1360/** Try very hard to get the SSL * into a consistent state where it's not yielded
1361 *
1362 * ...because if it's yielded, we'll probably leak thread contexts and all kinds of memory.
1363 *
1364 * @param[in] request being cancelled.
1365 * @param[in] action we're being signalled with.
1366 * @param[in] uctx the SSL * to cancel.
1367 */
1368static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
1369{
1370 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1371 int ret;
1372
1373 /*
1374 * We might want to set can_pause = false here
1375 * but that would trigger asserts in the
1376 * cache code.
1377 */
1378
1379 /*
1380 * If SSL_get_error returns SSL_ERROR_WANT_ASYNC
1381 * it means we're yielded in the middle of a
1382 * callback.
1383 *
1384 * Keep calling SSL_read() in a loop until we
1385 * no longer get SSL_ERROR_WANT_ASYNC, then
1386 * shut it down so it's in a consistent state.
1387 *
1388 * It'll get freed later when the request is
1389 * freed.
1390 */
1391 for (ret = tls_session->last_ret;
1392 SSL_get_error(tls_session->ssl, ret) == SSL_ERROR_WANT_ASYNC;
1393 ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1394 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used));
1395
1396 /*
1397 * Unbind the cancelled request from the SSL *
1398 */
1399 fr_tls_session_request_unbind(tls_session->ssl);
1400}
1401
1402/** Call SSL_read() to continue the TLS state machine
1403 *
1404 * This function may be called multiple times, once after every asynchronous request.
1405 *
1406 * @param[in] request The current request.
1407 * @param[in] uctx #fr_tls_session_t to continue.
1408 * @return
1409 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1410 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1411 */
1412static unlang_action_t tls_session_async_handshake_cont(request_t *request, void *uctx)
1413{
1414 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1415 int err;
1416
1417 RDEBUG3("(re-)entered state %s", __FUNCTION__);
1418
1419 /*
1420 * Clear OpenSSL's thread local error stack.
1421 *
1422 * Why do we need to do this here? Although SSL_get_error
1423 * takes an `SSL *`, which would make you _think_ it was
1424 * operating on the error stack for that SSL, it will also
1425 * return SSL_ERROR_SSL if there are any errors in the stack.
1426 *
1427 * When operating normally SSL_read() can return < 0, to
1428 * indicate it wants more data, or that we need to perform
1429 * asynchronous processing.
1430 *
1431 * If spurious errors have been left on the thread local
1432 * stack they MUST be cleared before we can call SSL_get_error
1433 * otherwise stale errors mask the async notifications
1434 * and cause random handshake failures.
1435 */
1436 ERR_clear_error();
1437
1438 /*
1439 * Magic/More magic? Although SSL_read is normally
1440 * used to read application data, it will also
1441 * continue the TLS handshake. Removing this call will
1442 * cause the handshake to fail.
1443 *
1444 * We don't ever expect to actually *receive* application
1445 * data here.
1446 *
1447 * The reason why we call SSL_read instead of SSL_accept,
1448 * or SSL_connect, as it allows this function
1449 * to be used, irrespective or whether we're acting
1450 * as a client or a server.
1451 *
1452 * If acting as a client SSL_set_connect_state must have
1453 * been called before this function.
1454 *
1455 * If acting as a server SSL_set_accept_state must have
1456 * been called before this function.
1457 */
1458 tls_session->can_pause = true;
1459 tls_session->last_ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1460 sizeof(tls_session->clean_out.data) - tls_session->clean_out.used);
1461 tls_session->can_pause = false;
1462 if (tls_session->last_ret > 0) {
1463 tls_session->clean_out.used += tls_session->last_ret;
1464
1465 /*
1466 * Round successful, and we don't need to do any
1467 * further processing.
1468 */
1469 tls_session->result = FR_TLS_RESULT_SUCCESS;
1470 finish:
1471 /*
1472 * Was bound by caller
1473 */
1474 fr_tls_session_request_unbind(tls_session->ssl);
1476 }
1477
1478 /*
1479 * Bug in OpenSSL 3.0 - Normal handshaking behaviour
1480 * results in spurious "BIO_R_UNSUPPORTED_METHOD"
1481 * errors.
1482 *
1483 * SSL_get_error apparently returns SSL_ERROR_SSL if
1484 * there are any errors in the stack. This masks
1485 * SSL_ERROR_WANT_ASYNC and causes the handshake to
1486 * fail.
1487 *
1488 * Note: We may want some version of this code
1489 * included for all OpenSSL versions.
1490 *
1491 * It would call ERR_GET_FATAL() on each of the errors
1492 * in the stack to drain non-fatal errors and prevent
1493 * the other (more useful) return codes of
1494 * SSL_get_error from being masked. I guess we'll see
1495 * if this occurs in other scenarios.
1496 */
1497 if (SSL_get_error(tls_session->ssl, tls_session->last_ret) == SSL_ERROR_SSL) {
1498 unsigned long ssl_err;
1499
1500 /*
1501 * Some weird OpenSSL thing marking ERR_GET_REASON
1502 * as "unused". Unclear why this is done as it's
1503 * not deprecated.
1504 */
1506DIAG_OFF(used-but-marked-unused)
1507 while ((ssl_err = ERR_peek_error()) && (ERR_GET_REASON(ssl_err) == BIO_R_UNSUPPORTED_METHOD)) {
1508 (void) ERR_get_error();
1509 }
1510DIAG_ON(used-but-marked-unused)
1512 }
1513
1514 /*
1515 * Deal with asynchronous requests from OpenSSL.
1516 * These aren't actually errors, they're the
1517 * result of one of our callbacks indicating that
1518 * it'd like to perform the operation
1519 * asynchronously.
1520 */
1521 switch (err = SSL_get_error(tls_session->ssl, tls_session->last_ret)) {
1522 case SSL_ERROR_WANT_ASYNC: /* Certification validation or cache loads */
1523 {
1524 unlang_action_t ua;
1525
1526 RDEBUG3("Performing async action for libssl");
1527
1528 /*
1529 * Call this function again once we're done
1530 * asynchronously satisfying the load request.
1531 */
1532 if (unlikely(unlang_function_repeat_set(request, tls_session_async_handshake_cont) < 0)) {
1533 error:
1534 tls_session->result = FR_TLS_RESULT_ERROR;
1535 goto finish;
1536 }
1537
1538 /*
1539 * First service any pending cache actions
1540 */
1541 ua = fr_tls_cache_pending_push(request, tls_session);
1542 switch (ua) {
1543 case UNLANG_ACTION_FAIL:
1544 IGNORE(unlang_function_clear(request), int);
1545 goto error;
1546
1548 return ua;
1549
1550 default:
1551 break;
1552 }
1553
1554 /*
1555 * Next service any pending certificate
1556 * validation actions.
1557 */
1558 ua = fr_tls_verify_cert_pending_push(request, tls_session);
1559 switch (ua) {
1560 case UNLANG_ACTION_FAIL:
1561 IGNORE(unlang_function_clear(request), int);
1562 goto error;
1563
1564 default:
1565 return ua;
1566 }
1567 }
1568
1569 case SSL_ERROR_WANT_ASYNC_JOB:
1570 RERROR("No async jobs available in pool, increase thread.openssl_async_pool_max");
1571 goto error;
1572
1573 default:
1574 /*
1575 * Returns 0 if we can continue processing the handshake
1576 * Returns -1 if we encountered a fatal error.
1577 */
1578 if (fr_tls_log_io_error(request,
1579 err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
1580 return tls_session_async_handshake_done_round(request, uctx);
1581 }
1582}
1583
1584/** Ingest data for another handshake round
1585 *
1586 * Advance the TLS handshake by feeding OpenSSL data from dirty_in,
1587 * and reading data from OpenSSL into dirty_out.
1588 *
1589 * Calls #tls_session_async_handshake_read to perform the actual ingestion.
1590 * #tls_session_async_handshake_read is split out because we may need to call
1591 * it multiple times, once after every async action.
1592 *
1593 * @param[in] request The current request.
1594 * @param[in] uctx #fr_tls_session_t to continue.
1595 * @return
1596 * - UNLANG_ACTION_CALCULATE_RESULT - We're done with this round.
1597 * - UNLANG_ACTION_PUSHED_CHILD - Need to perform more asynchronous actions.
1598 */
1599static unlang_action_t tls_session_async_handshake(request_t *request, void *uctx)
1600{
1601 fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1602 int ret;
1603
1604 RDEBUG3("entered state %s", __FUNCTION__);
1605
1606 tls_session->result = FR_TLS_RESULT_IN_PROGRESS;
1607
1608 fr_tls_session_request_bind(tls_session->ssl, request); /* May be unbound in this function or asynchronously */
1609
1610 /*
1611 * This is a logic error. fr_tls_session_async_handshake
1612 * must not be called if the handshake is
1613 * complete fr_tls_session_recv must be
1614 * called instead.
1615 */
1616 if (SSL_is_init_finished(tls_session->ssl)) {
1617 REDEBUG("Attempted to continue TLS handshake, but handshake has completed");
1618 error:
1619 tls_session->result = FR_TLS_RESULT_ERROR;
1620 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1622 }
1623
1624 if (tls_session->invalid) {
1625 REDEBUG("Preventing invalid session from continuing");
1626 goto error;
1627 }
1628
1629 /*
1630 * Feed dirty data into OpenSSL, so that is can either
1631 * process it as Application data (decrypting it)
1632 * or continue the TLS handshake.
1633 */
1634 if (tls_session->dirty_in.used) {
1635 ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
1636 if (ret != (int)tls_session->dirty_in.used) {
1637 REDEBUG("Failed writing %zu bytes to TLS BIO: %d", tls_session->dirty_in.used, ret);
1638 record_init(&tls_session->dirty_in);
1639 goto error;
1640 }
1641 record_init(&tls_session->dirty_in);
1642 }
1643
1644 return tls_session_async_handshake_cont(request, uctx); /* Must unbind request, possibly asynchronously */
1645}
1646
1647/** Push a handshake call onto the stack
1648 *
1649 * We push the handshake frame (as opposed to having the caller do it),
1650 * so that we guarantee there's a frame that the handshake function can
1651 * manipulate to manage its own state.
1652 *
1653 * The result of processing this handshake round can be found in
1654 * tls_session->result.
1655 *
1656 * @param[in] request The current request.
1657 * @param[in] tls_session to continue handshaking.
1658 * @return
1659 * - UNLANG_ACTION_PUSHED_CHILD on success.
1660 * - UNLANG_ACTION_FAIL on failure.
1661 */
1662unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
1663{
1664 return unlang_function_push(request,
1665 tls_session_async_handshake,
1666 NULL,
1667 tls_session_async_handshake_signal,
1670 tls_session);
1671}
1672
1673/** Free a TLS session and any associated OpenSSL data
1674 *
1675 * @param session to free.
1676 * @return 0.
1677 */
1678static int _fr_tls_session_free(fr_tls_session_t *session)
1679{
1680 if (session->ssl) {
1681 /*
1682 * The OpenSSL docs state:
1683 *
1684 * SSL_shutdown() can be modified to only set the
1685 * connection to "shutdown" state but not actually
1686 * send the "close notify" alert messages, see
1687 * SSL_CTX_set_quiet_shutdown(3). When "quiet shutdown"
1688 * is enabled, SSL_shutdown() will always succeed and
1689 * return 1.
1690 *
1691 * This is only partially correct. This call does mean
1692 * we don't notify the other party, but the SSL_shutdown
1693 * call can still fail if the handshake hasn't begun, leaving
1694 * spurious errors on the thread local error stack.
1695 */
1696 SSL_set_quiet_shutdown(session->ssl, 1);
1697
1698 /*
1699 * Don't leave spurious errors raised by SSL_shutdown on
1700 * the error stack.
1701 */
1702 if (SSL_shutdown(session->ssl) != 1) ERR_clear_error();
1703
1704 SSL_free(session->ssl);
1705 session->ssl = NULL;
1706 }
1707
1708 return 0;
1709}
1710
1711static void session_init(fr_tls_session_t *session)
1712{
1713 session->ssl = NULL;
1714 session->into_ssl = session->from_ssl = NULL;
1715 record_init(&session->clean_in);
1716 record_init(&session->clean_out);
1717 record_init(&session->dirty_in);
1718 record_init(&session->dirty_out);
1719
1720 memset(&session->info, 0, sizeof(session->info));
1721
1722 session->mtu = 0;
1723 session->opaque = NULL;
1724}
1725
1726/** Create a new client TLS session
1727 *
1728 * Configures a new client TLS session, configuring options, setting callbacks etc...
1729 *
1730 * @param[in] ctx to alloc session data in. Should usually be NULL unless the lifetime of the
1731 * session is tied to another talloc'd object.
1732 * @param[in] ssl_ctx containing the base configuration for this session.
1733 * @return
1734 * - A new session on success.
1735 * - NULL on error.
1736 */
1737fr_tls_session_t *fr_tls_session_alloc_client(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx)
1738{
1739 int verify_mode;
1740 fr_tls_session_t *tls_session = NULL;
1741 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1742
1743 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1744 talloc_set_destructor(tls_session, _fr_tls_session_free);
1745 fr_pair_list_init(&tls_session->extra_pairs);
1746
1747 tls_session->ssl = SSL_new(ssl_ctx);
1748 if (!tls_session->ssl) {
1749 talloc_free(tls_session);
1750 return NULL;
1751 }
1752
1753 /*
1754 * Add the message callback to identify what type of
1755 * message/handshake is passed
1756 */
1757 SSL_set_msg_callback(tls_session->ssl, fr_tls_session_msg_cb);
1758 SSL_set_msg_callback_arg(tls_session->ssl, tls_session);
1759 SSL_set_info_callback(tls_session->ssl, fr_tls_session_info_cb);
1760
1761 /*
1762 * In Client mode we only accept.
1763 *
1764 * This sets up the SSL session to work correctly with
1765 * fr_tls_session_handshake.
1766 */
1767 SSL_set_connect_state(tls_session->ssl);
1768
1769 /*
1770 * Always verify the peer certificate.
1771 */
1772 DEBUG2("Requiring Server certificate");
1773 verify_mode = SSL_VERIFY_PEER;
1774 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1775
1776 /*
1777 * Callback should be fr_tls_verify_cert_cb but this
1778 * requires support around SSL_connect for dealing
1779 * with async.
1780 *
1781 * If the callback is NULL OpenSSL uses its own validation
1782 * function, and the flags modifies that function's
1783 * behaviour.
1784 */
1785 SSL_set_verify(tls_session->ssl, verify_mode, NULL);
1786 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1787 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1788
1789 tls_session->mtu = conf->fragment_size;
1790
1791 return tls_session;
1792}
1793
1794/** Create a new server TLS session
1795 *
1796 * Configures a new server TLS session, configuring options, setting callbacks etc...
1797 *
1798 * @param[in] ctx to alloc session data in. Should usually be NULL
1799 * unless the lifetime of the session is tied to another
1800 * talloc'd object.
1801 * @param[in] ssl_ctx containing the base configuration for this session.
1802 * @param[in] request The current #request_t.
1803 * @param[in] dynamic_mtu If greater than 100, overrides the MTU configured for the SSL_CTX.
1804 * @param[in] client_cert Whether to require a client_cert.
1805 * @return
1806 * - A new session on success.
1807 * - NULL on error.
1808 */
1809fr_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)
1810{
1811 fr_tls_session_t *tls_session = NULL;
1812 SSL *ssl = NULL;
1813 int verify_mode = 0;
1814 fr_pair_t *vp;
1815 fr_tls_conf_t *conf = fr_tls_ctx_conf(ssl_ctx);
1816
1817 RDEBUG2("Initiating new TLS session");
1818
1819 MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1820
1821 ssl = SSL_new(ssl_ctx);
1822 if (ssl == NULL) {
1823 talloc_free(tls_session);
1824 fr_tls_log(request, "Error creating new TLS session");
1825 return NULL;
1826 }
1827 fr_pair_list_init(&tls_session->extra_pairs);
1828
1829 session_init(tls_session);
1830 tls_session->ctx = ssl_ctx;
1831 tls_session->ssl = ssl;
1832 talloc_set_destructor(tls_session, _fr_tls_session_free);
1833
1834 fr_tls_session_request_bind(tls_session->ssl, request); /* Is unbound in this function */
1835
1836 /*
1837 * Initialize callbacks
1838 */
1839 tls_session->record_init = record_init;
1840 tls_session->record_close = record_close;
1841 tls_session->record_from_buff = record_from_buff;
1842 tls_session->record_to_buff = record_to_buff;
1843
1844 /*
1845 * Create & hook the BIOs to handle the dirty side of the
1846 * SSL. This is *very important* as we want to handle
1847 * the transmission part. Now the only IO interface
1848 * that SSL is aware of, is our defined BIO buffers.
1849 *
1850 * This means that all SSL IO is done to/from memory,
1851 * and we can update those BIOs from the packets we've
1852 * received.
1853 */
1854 MEM(tls_session->into_ssl = BIO_new(BIO_s_mem()));
1855 MEM(tls_session->from_ssl = BIO_new(BIO_s_mem()));
1856 SSL_set_bio(tls_session->ssl, tls_session->into_ssl, tls_session->from_ssl);
1857
1858 /*
1859 * Add the message callback to identify what type of
1860 * message/handshake is passed
1861 */
1862 SSL_set_msg_callback(ssl, fr_tls_session_msg_cb);
1863 SSL_set_msg_callback_arg(ssl, tls_session);
1864 SSL_set_info_callback(ssl, fr_tls_session_info_cb);
1865
1866 /*
1867 * This sets the context sessions can be resumed in.
1868 * This is to prevent sessions being created by one application
1869 * and used by another. In our case it prevents sessions being
1870 * reused between modules, or TLS server components such as
1871 * RADSEC.
1872 *
1873 * A context must always be set when doing session resumption
1874 * otherwise session resumption will fail.
1875 *
1876 * As the context ID must be <= 32, we digest the context
1877 * data with sha256.
1878 *
1879 * This seems to only be used for stateful session resumption
1880 * not session-tickets
1881 */
1882 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1883 char *context_id;
1884 EVP_MD_CTX *md_ctx;
1885 uint8_t digest[SHA256_DIGEST_LENGTH];
1886
1887 static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
1888 "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");
1889 fr_assert(conf->cache.id_name);
1890
1891 if (tmpl_aexpand(tls_session, &context_id, request, conf->cache.id_name, NULL, NULL) < 0) {
1892 RPEDEBUG("Failed expanding session ID");
1893 error:
1894 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1895 talloc_free(tls_session);
1896 return NULL;
1897 }
1898
1899 MEM(md_ctx = EVP_MD_CTX_create());
1900 EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
1901 EVP_DigestUpdate(md_ctx, context_id, talloc_array_length(context_id) - 1);
1902 EVP_DigestFinal_ex(md_ctx, digest, NULL);
1903 EVP_MD_CTX_destroy(md_ctx);
1904 talloc_free(context_id);
1905
1906 if (!fr_cond_assert(SSL_set_session_id_context(tls_session->ssl,
1907 digest, sizeof(digest)) == 1)) goto error;
1908 }
1909
1910 /*
1911 * Add the session certificate to the session.
1912 */
1913 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_cert_file);
1914 if (vp) {
1915 RDEBUG2("Loading TLS session certificate \"%pV\"", &vp->data);
1916
1917 if (SSL_use_certificate_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1918 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1919 vp->vp_strvalue);
1920 goto error;
1921 }
1922
1923 if (SSL_use_PrivateKey_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1924 fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1925 vp->vp_strvalue);
1926 goto error;
1927 }
1928
1929 if (SSL_check_private_key(tls_session->ssl) != 1) {
1930 fr_tls_log(request, "Failed validating TLS session certificate \"%s\"",
1931 vp->vp_strvalue);
1932 goto error;
1933 }
1934 /*
1935 * Better to perform explicit checks, than rely
1936 * on OpenSSL's opaque error messages.
1937 */
1938 } else {
1939 if (!conf->chains || !conf->chains[0]->private_key_file) {
1940 ERROR("TLS Server requires a private key file");
1941 goto error;
1942 }
1943
1944 if (!conf->chains || !conf->chains[0]->certificate_file) {
1945 ERROR("TLS Server requires a certificate file");
1946 goto error;
1947 }
1948 }
1949
1950 /** Dynamic toggle for allowing disallowing client certs
1951 *
1952 * This is mainly used for testing in environments where we can't
1953 * get test credentials for the host.
1954 */
1955 vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_require_client_cert);
1956 if (vp) client_cert = vp->vp_bool;
1957
1958 /*
1959 * In Server mode we only accept.
1960 *
1961 * This sets up the SSL session to work correctly with
1962 * fr_tls_session_handshake.
1963 */
1964 SSL_set_accept_state(tls_session->ssl);
1965
1966 /*
1967 * Verify the peer certificate, if asked.
1968 */
1969 if (client_cert) {
1970 RDEBUG2("Setting verify mode to require certificate from client");
1971 verify_mode = SSL_VERIFY_PEER;
1972 verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1973 verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1974 }
1975 tls_session->verify_client_cert = client_cert;
1976
1977 SSL_set_verify(tls_session->ssl, verify_mode, fr_tls_verify_cert_cb);
1978 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1979 SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1980
1981 if (conf->client_hello_parse) {
1982 SSL_CTX_set_client_hello_cb(ssl_ctx, fr_tls_session_client_hello_cb, NULL);
1983 }
1984
1985 tls_session->mtu = conf->fragment_size;
1986 if (dynamic_mtu > 100 && dynamic_mtu < tls_session->mtu) {
1987 RDEBUG2("Setting fragment_len to %zu from dynamic_mtu", dynamic_mtu);
1988 tls_session->mtu = dynamic_mtu;
1989 }
1990
1991 if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1992 tls_session->allow_session_resumption = true; /* otherwise it's false */
1993 fr_tls_cache_session_alloc(tls_session);
1994 }
1995
1996 fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1997
1998 return tls_session;
1999}
2000
2001static unlang_action_t tls_new_session_result(request_t *request, UNUSED void *uctx)
2002{
2003 request_t *parent = request->parent;
2004
2006
2007 /*
2008 * Copy control attributes back to the parent.
2009 */
2010 if (fr_pair_list_copy(parent->control_ctx, &parent->control_pairs, &request->control_pairs) < 0) return UNLANG_ACTION_FAIL;
2011
2013}
2014
2015unlang_action_t fr_tls_new_session_push(request_t *request, fr_tls_conf_t const *tls_conf)
2016{
2017 request_t *child;
2018 fr_pair_t *vp;
2019
2020 MEM(child = unlang_subrequest_alloc(request, dict_tls));
2021
2023 vp->vp_uint32 = enum_tls_packet_type_new_session->vb_uint32;
2024
2025 if (unlang_subrequest_child_push(NULL, child, request, true, UNLANG_SUB_FRAME) < 0) {
2026 talloc_free(child);
2027 return UNLANG_ACTION_FAIL;
2028 }
2029
2030 if (unlang_function_push(child,
2031 NULL,
2032 tls_new_session_result,
2033 NULL, 0,
2034 UNLANG_SUB_FRAME, NULL) < 0) {
2035 talloc_free(child);
2036 return UNLANG_ACTION_FAIL;
2037 }
2038
2039 if (unlang_call_push(NULL, child, tls_conf->virtual_server, UNLANG_SUB_FRAME) < 0) {
2040 talloc_free(child);
2041 return UNLANG_ACTION_FAIL;
2042 }
2043
2045}
2046#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:578
int const char int line
Definition acutest.h:704
#define fr_base16_decode(_err, _out, _in, _no_trailing)
Definition base16.h:95
#define IGNORE(_expr, _type)
Definition build.h:511
#define DIAG_UNKNOWN_PRAGMAS
Definition build.h:460
#define DIAG_ON(_x)
Definition build.h:462
#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:461
unlang_action_t unlang_call_push(unlang_result_t *p_result, 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:524
#define fr_cond_assert(_x)
Calls panic_action ifndef NDEBUG, else logs error and evaluates to value of _x.
Definition debug.h:131
#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:884
static fr_slen_t in
Definition dict.h:884
int unlang_function_clear(request_t *request)
Clear pending repeat function calls, and remove the signal handler.
Definition function.c:279
#define unlang_function_repeat_set(_request, _repeat)
Set a new repeat function for an existing function frame.
Definition function.h:108
#define unlang_function_push(_request, _func, _repeat, _signal, _sigmask, _top_frame, _uctx)
Push a generic function onto the unlang stack.
Definition function.h:179
talloc_free(hp)
#define UNLANG_SUB_FRAME
Definition interpret.h:37
static fr_dict_t const * dict_tls
Definition base.c:79
#define REXDENT()
Exdent (unindent) R* messages by one level.
Definition log.h:455
#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:540
#define RWDEBUG(fmt,...)
Definition log.h:373
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
Definition log.h:347
#define RDEBUG3(fmt,...)
Definition log.h:355
#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:718
#define RERROR(fmt,...)
Definition log.h:310
#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:554
#define RPEDEBUG(fmt,...)
Definition log.h:388
#define RHEXDUMP3(_data, _len, _fmt,...)
Definition log.h:717
#define RDEBUG4(fmt,...)
Definition log.h:356
#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:348
#define HEXDUMP4(_data, _len, _fmt,...)
Definition log.h:736
#define RPWDEBUG2(fmt,...)
Definition log.h:379
#define REDEBUG4(fmt,...)
Definition log.h:386
#define RINDENT()
Indent R* messages by one level.
Definition log.h:442
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
@ 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:2327
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:2646
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:2600
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:704
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
#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:1064
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:36
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:305
int unlang_subrequest_child_push(unlang_result_t *p_result, request_t *child, 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:429
static fr_slen_t parent
Definition pair.h:858
static fr_slen_t data
Definition value.h:1334
static size_t char fr_sbuff_t size_t inlen
Definition value.h:1024
static size_t char ** out
Definition value.h:1024