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