Coverage Report

Created: 2026-03-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/lib/tls/session.c
Line
Count
Source
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
0
#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
53
static 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
71
static 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
84
static 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
137
static 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
 */
187
inline static void record_init(fr_tls_record_t *record)
188
0
{
189
0
  record->used = 0;
190
0
}
191
192
/** Destroy a record buffer
193
 *
194
 * @param record buffer to destroy clear.
195
 */
196
inline static void record_close(fr_tls_record_t *record)
197
0
{
198
0
  record->used = 0;
199
0
}
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
 */
208
inline static unsigned int record_from_buff(fr_tls_record_t *record, void const *in, unsigned int inlen)
209
0
{
210
0
  unsigned int added = FR_TLS_MAX_RECORD_SIZE - record->used;
211
212
0
  if (added > inlen) added = inlen;
213
0
  if (added == 0) return 0;
214
215
0
  memcpy(record->data + record->used, in, added);
216
0
  record->used += added;
217
218
0
  return added;
219
0
}
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
 */
228
inline static unsigned int record_to_buff(fr_tls_record_t *record, void *out, unsigned int outlen)
229
0
{
230
0
  unsigned int taken = record->used;
231
232
0
  if (taken > outlen) taken = outlen;
233
0
  if (taken == 0) return 0;
234
0
  if (out) memcpy(out, record->data, taken);
235
236
0
  record->used -= taken;
237
238
  /*
239
   *  This is pretty bad...
240
   */
241
0
  if (record->used > 0) memmove(record->data, record->data + taken, record->used);
242
243
0
  return taken;
244
0
}
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
 */
258
int fr_tls_session_password_cb(char *buf, int size, int rwflag UNUSED, void *u)
259
0
{
260
0
  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
0
  if (!u) {
268
0
    ERROR("Private key encrypted but no private_key_password configured");
269
0
    return 0;
270
0
  }
271
272
0
  len = strlcpy(buf, (char *)u, size);
273
0
  if (len > (size_t)size) {
274
0
    ERROR("Password too long.  Maximum length is %i bytes", size - 1);
275
0
    return 0;
276
0
  }
277
278
0
  return len;
279
0
}
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
 */
289
static bool session_psk_identity_is_safe(const char *identity)
290
0
{
291
0
  char c;
292
293
0
  if (!identity) return true;
294
295
0
  while ((c = *(identity++)) != '\0') {
296
0
    if (isalpha((uint8_t) c) || isdigit((uint8_t) c) || isspace((uint8_t) c) ||
297
0
        (c == '@') || (c == '-') || (c == '_') || (c == '.')) {
298
0
      continue;
299
0
    }
300
301
0
    return false;
302
0
  }
303
304
0
  return true;
305
0
}
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
 */
317
unsigned 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
0
{
321
0
  unsigned int psk_len;
322
0
  fr_tls_conf_t *conf;
323
324
0
  conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
325
0
  if (!conf) return 0;
326
327
0
  psk_len = strlen(conf->psk_password);
328
0
  if (psk_len > (2 * max_psk_len)) return 0;
329
330
0
  strlcpy(identity, conf->psk_identity, max_identity_len);
331
332
0
  return fr_base16_decode(NULL,
333
0
        &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
334
0
        &FR_SBUFF_IN(conf->psk_password, (size_t)psk_len), false);
335
0
}
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
 */
347
unsigned int fr_tls_session_psk_server_cb(SSL *ssl, const char *identity,
348
            unsigned char *psk, unsigned int max_psk_len)
349
0
{
350
0
  size_t    psk_len = 0;
351
0
  fr_tls_conf_t *conf;
352
0
  request_t *request;
353
354
0
  conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
355
0
  if (!conf) return 0;
356
357
0
  request = fr_tls_session_request(ssl);
358
0
  if (request && conf->psk_query) {
359
0
    size_t hex_len;
360
0
    fr_pair_t *vp;
361
0
    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
0
    if (!session_psk_identity_is_safe(identity)) {
367
0
      RWDEBUG("Invalid characters in PSK identity %s", identity);
368
0
      return 0;
369
0
    }
370
371
0
    MEM(pair_update_request(&vp, attr_tls_psk_identity) >= 0);
372
0
    if (fr_pair_value_from_str(vp, identity, strlen(identity), NULL, true) < 0) {
373
0
      RPWDEBUG2("Failed parsing TLS PSK Identity");
374
0
      talloc_free(vp);
375
0
      return 0;
376
0
    }
377
378
0
    hex_len = xlat_eval(buffer, sizeof(buffer), request, conf->psk_query, NULL, NULL);
379
0
    if (!hex_len) {
380
0
      RWDEBUG("PSK expansion returned an empty string.");
381
0
      return 0;
382
0
    }
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
0
    if (hex_len > (2 * max_psk_len)) {
390
0
      RWDEBUG("Returned PSK is too long (%u > %u)", (unsigned int) hex_len, 2 * max_psk_len);
391
0
      return 0;
392
0
    }
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
0
    return fr_base16_decode(NULL,
400
0
          &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
401
0
          &FR_SBUFF_IN(buffer, hex_len), false);
402
0
  }
403
404
0
  if (!conf->psk_identity) {
405
0
    DEBUG("No static PSK identity set.  Rejecting the user");
406
0
    return 0;
407
0
  }
408
409
  /*
410
   *  No request_t, or no dynamic query.  Just look for a
411
   *  static identity.
412
   */
413
0
  if (strcmp(identity, conf->psk_identity) != 0) {
414
0
    ERROR("Supplied PSK identity %s does not match configuration.  Rejecting.",
415
0
          identity);
416
0
    return 0;
417
0
  }
418
419
0
  psk_len = strlen(conf->psk_password);
420
0
  if (psk_len > (2 * max_psk_len)) return 0;
421
422
0
  return fr_base16_decode(NULL,
423
0
        &FR_DBUFF_TMP((uint8_t *)psk, (size_t)max_psk_len),
424
0
        &FR_SBUFF_IN(conf->psk_password, psk_len), false);
425
0
}
426
#endif /* PSK_MAX_IDENTITY_LEN */
427
428
DIAG_OFF(DIAG_UNKNOWN_PRAGMAS)
429
DIAG_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
 */
440
void fr_tls_session_info_cb(SSL const *ssl, int where, int ret)
441
0
{
442
0
  char const  *role, *state;
443
0
  request_t *request = SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_REQUEST);
444
445
0
  if ((where & ~SSL_ST_MASK) & SSL_ST_CONNECT) {
446
0
    role = "Client ";
447
0
  } else if (((where & ~SSL_ST_MASK)) & SSL_ST_ACCEPT) {
448
0
    role = "Server ";
449
0
  } else {
450
0
    role = "";
451
0
  }
452
453
0
  state = SSL_state_string_long(ssl);
454
0
  state = state ? state : "<INVALID>";
455
456
0
  if ((where & SSL_CB_LOOP) || (where & SSL_CB_HANDSHAKE_START) || (where & SSL_CB_HANDSHAKE_DONE)) {
457
0
    if (ROPTIONAL_ENABLED(RDEBUG_ENABLED3, DEBUG_ENABLED3)) {
458
0
      char const *abbrv = SSL_state_string(ssl);
459
0
      size_t len;
460
461
      /*
462
       *  Trim crappy OpenSSL state strings...
463
       */
464
0
      len = strlen(abbrv);
465
0
      if ((len > 1) && (abbrv[len - 1] == ' ')) len--;
466
467
0
      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)");
494
          if (ROPTIONAL_ENABLED(RDEBUG_ENABLED4, DEBUG_ENABLED4)) {
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
           */
508
          if (ROPTIONAL_ENABLED(RDEBUG_ENABLED3, DEBUG_ENABLED3)) {
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
0
    } else {
522
0
      ROPTIONAL(RDEBUG2, DEBUG2, "Handshake state - %s%s (%u)", role, state, SSL_get_state(ssl));
523
0
    }
524
0
    return;
525
0
  }
526
527
0
  if (where & SSL_CB_ALERT) {
528
0
    if ((ret & 0xff) == SSL_AD_CLOSE_NOTIFY) return;
529
530
    /*
531
     *  We got an alert...
532
     */
533
0
    if (where & SSL_CB_READ) {
534
0
      fr_pair_t *vp;
535
536
0
      ROPTIONAL(REDEBUG, ERROR, "Client sent %s TLS alert (%i) - %s", SSL_alert_type_string_long(ret),
537
0
                ret & 0xff, SSL_alert_desc_string_long(ret));
538
539
      /*
540
       *  Offer helpful advice... Should be expanded.
541
       */
542
0
      switch (ret & 0xff) {
543
0
      case TLS1_AD_UNKNOWN_CA:
544
0
        REDEBUG("Verify the client has a copy of the server's Certificate "
545
0
          "Authority (CA) installed, and trusts that CA");
546
0
        break;
547
548
0
      default:
549
0
        break;
550
0
      }
551
552
0
      if (request) {
553
0
        MEM(pair_update_request(&vp, attr_tls_client_error_code) >= 0);
554
0
        vp->vp_uint8 = ret & 0xff;
555
0
        RDEBUG2("TLS-Client-Error-Code := %pV", &vp->data);
556
0
      }
557
    /*
558
     *  We're sending the client an alert.
559
     */
560
0
    } else {
561
0
      ROPTIONAL(REDEBUG, ERROR, "Sending client %s TLS alert (%i) - %s",
562
0
          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
0
      switch (ret & 0xff) {
568
0
      case TLS1_AD_PROTOCOL_VERSION:
569
0
        ROPTIONAL(REDEBUG, ERROR, "Client requested a TLS protocol version that is not "
570
0
            "enabled or not supported. Upgrade FreeRADIUS + OpenSSL to their latest "
571
0
            "versions and/or adjust 'tls_max_version'/'tls_min_version' if you want "
572
0
            "authentication to succeed");
573
0
        break;
574
575
0
      default:
576
0
        break;
577
0
      }
578
0
    }
579
0
    return;
580
0
  }
581
582
0
  if (where & SSL_CB_EXIT) {
583
0
    if (ret == 0) {
584
0
      ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
585
0
      return;
586
0
    }
587
588
0
    if (ret < 0) {
589
0
      if (SSL_want_read(ssl)) {
590
0
        RDEBUG2("Need more data from client"); /* State same as previous call, don't print */
591
0
        return;
592
0
      }
593
0
      ROPTIONAL(REDEBUG, ERROR, "Handshake exit state %s%s", role, state);
594
0
    }
595
0
  }
596
0
}
597
DIAG_ON(used-but-marked-unused)
598
DIAG_ON(DIAG_UNKNOWN_PRAGMAS)
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
 */
605
static void session_msg_log(request_t *request, fr_tls_session_t *tls_session, uint8_t const *data, size_t data_len)
606
0
{
607
0
  char const  *version, *content_type;
608
0
  char const  *str_details1 = NULL;
609
0
  char const  *str_details2 = NULL;
610
0
  char    unknown_version[32];
611
0
  char    unknown_content_type[32];
612
0
  char    unknown_alert_level[32];
613
0
  char    unknown_alert_description[32];
614
0
  char    unknown_handshake_type[32];
615
616
  /*
617
   *  Don't print this out in the normal course of
618
   *  operations.
619
   */
620
0
  if (!ROPTIONAL_ENABLED(RDEBUG_ENABLED2, DEBUG_ENABLED2)) return;
621
622
0
  if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
623
0
      !tls_version_str[tls_session->info.version]) {
624
0
    snprintf(unknown_version, sizeof(unknown_version), "unknown_tls_version_0x%04x",
625
0
       (unsigned int) tls_session->info.version);
626
0
    version = unknown_version;
627
0
  } else {
628
0
    version = tls_version_str[tls_session->info.version];
629
0
  }
630
631
  /*
632
   *  TLS 1.0, 1.1, 1.2 content types are the same as SSLv3
633
   */
634
0
  if (((size_t)tls_session->info.content_type >= NUM_ELEMENTS(tls_content_type_str)) ||
635
0
      !tls_content_type_str[tls_session->info.content_type]) {
636
0
    snprintf(unknown_content_type, sizeof(unknown_content_type),
637
0
       "unknown_content_type_0x%04x", (unsigned int) tls_session->info.content_type);
638
0
    content_type = unknown_content_type;
639
0
  } else {
640
0
    content_type = tls_content_type_str[tls_session->info.content_type];
641
0
  }
642
643
0
  if (tls_session->info.content_type == SSL3_RT_ALERT) {
644
0
    if (tls_session->info.record_len == 2) {
645
0
      switch (tls_session->info.alert_level) {
646
0
      case SSL3_AL_WARNING:
647
0
        str_details1 = "warning";
648
0
        break;
649
0
      case SSL3_AL_FATAL:
650
0
        str_details1 = "fatal";
651
0
        break;
652
653
0
      default:
654
0
        snprintf(unknown_alert_level, sizeof(unknown_alert_level),
655
0
           "unknown_alert_level_0x%04x", tls_session->info.alert_level);
656
0
        str_details1 = unknown_alert_level;
657
0
        break;
658
0
      }
659
660
0
      if (((size_t)tls_session->info.alert_description >= NUM_ELEMENTS(tls_alert_description_str)) ||
661
0
          !tls_alert_description_str[tls_session->info.alert_description]) {
662
0
        snprintf(unknown_alert_description, sizeof(unknown_alert_description),
663
0
           "unknown_alert_0x%04x", tls_session->info.alert_description);
664
0
        str_details2 = unknown_alert_description;
665
0
      } else {
666
0
        str_details2 = tls_alert_description_str[tls_session->info.alert_description];
667
0
      }
668
0
    } else {
669
0
      str_details1 = "unknown_alert_level";
670
0
      str_details2 = "unknown_alert";
671
0
    }
672
0
  }
673
674
0
  if ((size_t)tls_session->info.content_type == SSL3_RT_HANDSHAKE) {
675
0
    if (tls_session->info.record_len > 0) {
676
      /*
677
       *  Range guard not needed due to size of array
678
       *  and underlying type.
679
       */
680
0
      if (!tls_handshake_type_str[tls_session->info.handshake_type]) {
681
0
        snprintf(unknown_handshake_type, sizeof(unknown_handshake_type),
682
0
           "unknown_handshake_type_0x%02x", tls_session->info.handshake_type);
683
0
        str_details1 = unknown_handshake_type;
684
0
      } else {
685
0
        str_details1 = tls_handshake_type_str[tls_session->info.handshake_type];
686
0
      }
687
0
    }
688
0
  }
689
690
0
  snprintf(tls_session->info.info_description, sizeof(tls_session->info.info_description),
691
0
     "%s %s, %s[length %lu]%s%s%s%s",
692
0
     tls_session->info.origin ? ">>> send" : "<<< recv",
693
0
     version,
694
0
     content_type,
695
0
     (unsigned long)tls_session->info.record_len,
696
0
     str_details1 ? ", " : "",
697
0
     str_details1 ? str_details1 : "",
698
0
     str_details2 ? ", " : "",
699
0
     str_details2 ? str_details2 : "");
700
701
  /*
702
   *  Print out information about the record and print the
703
   *  data at higher debug levels.
704
   */
705
0
  if (ROPTIONAL_ENABLED(RDEBUG_ENABLED4, DEBUG_ENABLED4)) {
706
0
    ROPTIONAL(RHEXDUMP4, HEXDUMP4, data, data_len, "%s", tls_session->info.info_description);
707
0
  } else {
708
0
    ROPTIONAL(RDEBUG2, DEBUG2, "%s", tls_session->info.info_description);
709
0
  }
710
0
}
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
 */
741
void 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
0
{
745
0
  uint8_t const   *buf = inbuf;
746
0
  fr_tls_session_t  *tls_session = talloc_get_type_abort(arg, fr_tls_session_t);
747
0
  request_t   *request = fr_tls_session_request(tls_session->ssl);
748
749
  /*
750
   *  Mostly to check for memory corruption...
751
   */
752
0
  if (!fr_cond_assert(tls_session->ssl == ssl)) {
753
0
    ROPTIONAL(REDEBUG, ERROR, "fr_tls_session_t and ssl arg do not match in fr_tls_session_msg_cb");
754
0
    tls_session->invalid = true;
755
0
    return;
756
0
  }
757
758
  /*
759
   *  As per https://tools.ietf.org/html/rfc7568
760
   *
761
   *  We explicitly disable SSLv2/v3, hence the asserts.
762
   */
763
0
#ifdef SSL2_VERSION
764
0
  if (!fr_cond_assert(msg_version != SSL2_VERSION)) {
765
0
    ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv2) in handshake");
766
0
    tls_session->invalid = true;
767
0
    return;
768
0
  }
769
0
#endif
770
771
0
#ifdef SSL3_VERSION
772
0
  if (!fr_cond_assert(msg_version != SSL3_VERSION)) {
773
0
    ROPTIONAL(REDEBUG, ERROR, "Invalid version (SSLv3) in handshake");
774
0
    tls_session->invalid = true;
775
0
    return;
776
0
  }
777
0
#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
0
  if ((msg_version == 0) && (content_type > UINT8_MAX)) {
785
0
    ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with pseudo content type %i, version %i",
786
0
              content_type, msg_version);
787
0
    return;
788
0
  }
789
790
0
  if ((write_p != 0) && (write_p != 1)) {
791
0
    ROPTIONAL(REDEBUG4, DEBUG4, "Ignoring fr_tls_session_msg_cb call with invalid write_p %d", write_p);
792
0
    return;
793
0
  }
794
795
  /*
796
   *  0 - received (from peer)
797
   *  1 - sending (to peer)
798
   */
799
0
  tls_session->info.origin = write_p;
800
0
  tls_session->info.content_type = content_type;
801
0
  tls_session->info.record_len = len;
802
0
  tls_session->info.version = msg_version;
803
0
  tls_session->info.initialized = true;
804
805
0
  switch (content_type) {
806
0
  case SSL3_RT_ALERT:
807
0
    if (len < 2) {
808
0
    invalid_alert:
809
0
      ROPTIONAL(REDEBUG, ERROR, "Invalid TLS Alert.  Closing connection");
810
0
      tls_session->invalid = true;
811
0
      return;
812
0
    }
813
814
0
    tls_session->info.alert_level = buf[0];
815
0
    tls_session->info.alert_description = buf[1];
816
0
    tls_session->info.handshake_type = 0x00;
817
0
    break;
818
819
0
  case SSL3_RT_HANDSHAKE:
820
0
    if (!len) goto invalid_alert;
821
822
0
    tls_session->info.handshake_type = buf[0];
823
0
    tls_session->info.alert_level = 0x00;
824
0
    tls_session->info.alert_description = 0x00;
825
0
    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
0
  default:
844
0
    break;
845
0
  }
846
847
0
  session_msg_log(request, tls_session, (uint8_t const *)inbuf, len);
848
849
0
#ifndef OPENSSL_NO_SSL_TRACE
850
0
  if (ROPTIONAL_ENABLED(RDEBUG_ENABLED3, DEBUG_ENABLED3)) {
851
0
    SSL_trace(tls_session->info.origin,
852
0
        tls_session->info.version,
853
0
        tls_session->info.content_type,
854
0
        inbuf, len,
855
0
        ssl,
856
0
        request ?
857
0
          fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3) :
858
0
        fr_tls_global_log_bio(L_DBG, L_DBG_LVL_3));
859
0
  }
860
0
#endif
861
0
}
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
 */
879
void fr_tls_session_keylog_cb(const SSL *ssl, const char *line)
880
0
{
881
0
  int fd;
882
0
  size_t len;
883
0
  const char *filename;
884
0
  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
0
  filename = getenv("SSLKEYLOGFILE");
893
0
  if (!filename) {
894
0
    fr_tls_conf_t *conf;
895
896
0
    conf = (fr_tls_conf_t *)SSL_get_ex_data(ssl, FR_TLS_EX_INDEX_CONF);
897
0
    if (!conf || !conf->keylog_file || !*conf->keylog_file) return;
898
899
0
    filename = conf->keylog_file;
900
0
  }
901
902
  /*
903
   *  We write all of the data at once.  This is *generally*
904
   *  atomic on most systems.
905
   */
906
0
  len = strlen(line);
907
0
  if ((len + 1) > sizeof(buffer)) {
908
0
    DEBUG("SSLKEYLOGFILE buffer not large enough, max %lu, required %lu", sizeof(buffer), len + 1);
909
0
    return;
910
0
  }
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
0
  memcpy(buffer, line, len);
918
0
  buffer[len] = '\n';
919
920
0
  fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
921
0
  if (fd < 0) {
922
0
    DEBUG("Failed to open file %s: %s", filename, strerror(errno));
923
0
    return;
924
0
  }
925
926
  /*
927
   *  This should work in most situations.
928
   */
929
0
  if (write(fd, buffer, len + 1) < 0) {
930
0
    DEBUG("Failed to write to file %s: %s", filename, strerror(errno));
931
0
  }
932
933
0
  close(fd);
934
0
}
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
 */
949
int fr_tls_session_recv(request_t *request, fr_tls_session_t *tls_session)
950
0
{
951
0
  int ret;
952
953
0
  fr_tls_session_request_bind(tls_session->ssl, request);
954
955
0
  if (!SSL_is_init_finished(tls_session->ssl)) {
956
0
    REDEBUG("Attempted to read application data before handshake completed");
957
0
  error:
958
0
    ret = -1;
959
0
    goto finish;
960
0
  }
961
962
  /*
963
   *  Decrypt the complete record.
964
   */
965
0
  if (tls_session->dirty_in.used) {
966
0
    ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
967
0
    if (ret != (int) tls_session->dirty_in.used) {
968
0
      REDEBUG("Failed writing %zu bytes to SSL BIO: %d", tls_session->dirty_in.used, ret);
969
0
      record_init(&tls_session->dirty_in);
970
0
      goto error;
971
0
    }
972
973
0
    record_init(&tls_session->dirty_in);
974
0
  }
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
0
  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
0
  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
0
  ret = SSL_read(tls_session->ssl, tls_session->clean_out.data, sizeof(tls_session->clean_out.data));
995
0
  if (ret < 0) {
996
0
    int code;
997
998
0
    code = SSL_get_error(tls_session->ssl, ret);
999
0
    switch (code) {
1000
0
    case SSL_ERROR_WANT_READ:
1001
0
      RWDEBUG("Peer indicated record was complete, but OpenSSL returned SSL_WANT_READ. "
1002
0
        "Attempting to continue");
1003
0
      ret = 1;
1004
0
      goto finish;
1005
1006
0
    case SSL_ERROR_WANT_WRITE:
1007
0
      REDEBUG("Error in fragmentation logic: SSL_WANT_WRITE");
1008
0
      goto error;
1009
1010
0
    case SSL_ERROR_NONE:
1011
0
      RDEBUG2("No application data received.  Assuming handshake is continuing...");
1012
0
      ret = 0;
1013
0
      break;
1014
1015
0
    default:
1016
0
      REDEBUG("Error in fragmentation logic");
1017
0
      fr_tls_log_io_error(request, code, "SSL_read (%s)", __FUNCTION__);
1018
0
      goto error;
1019
0
    }
1020
0
  }
1021
1022
  /*
1023
   *  Passed all checks, successfully decrypted data
1024
   */
1025
0
  tls_session->clean_out.used = ret;
1026
0
  ret = 0;
1027
1028
0
  if (RDEBUG_ENABLED3) {
1029
0
    RHEXDUMP3(tls_session->clean_out.data, tls_session->clean_out.used,
1030
0
       "Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1031
0
  } else {
1032
0
    RDEBUG2("Decrypted TLS application data (%zu bytes)", tls_session->clean_out.used);
1033
0
  }
1034
0
finish:
1035
0
  fr_tls_session_request_unbind(tls_session->ssl);
1036
1037
0
  return ret;
1038
0
}
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
 */
1053
int fr_tls_session_send(request_t *request, fr_tls_session_t *tls_session)
1054
0
{
1055
0
  int ret = 0;
1056
1057
0
  fr_tls_session_request_bind(tls_session->ssl, request);
1058
1059
0
  if (!SSL_is_init_finished(tls_session->ssl)) {
1060
0
    REDEBUG("Attempted to write application data before handshake completed");
1061
0
    ret = -1;
1062
0
    goto finish;
1063
0
  }
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
0
  if (tls_session->clean_in.used > 0) {
1075
    /*
1076
     *  Ensure spurious errors aren't printed
1077
     */
1078
0
    ERR_clear_error();
1079
1080
0
    if (RDEBUG_ENABLED3) {
1081
0
      RHEXDUMP3(tls_session->clean_in.data, tls_session->clean_in.used,
1082
0
         "TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1083
0
    } else {
1084
0
      RDEBUG2("TLS application data to encrypt (%zu bytes)", tls_session->clean_in.used);
1085
0
    }
1086
1087
0
    ret = SSL_write(tls_session->ssl, tls_session->clean_in.data, tls_session->clean_in.used);
1088
0
    if (ret < 0) goto log_io_error;
1089
0
    record_to_buff(&tls_session->clean_in, NULL, ret);
1090
1091
    /* Get the dirty data from Bio to send it */
1092
0
    ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1093
0
             sizeof(tls_session->dirty_out.data));
1094
0
    if (ret < 0) {
1095
0
    log_io_error:
1096
0
      ret = fr_tls_log_io_error(request, SSL_get_error(tls_session->ssl, ret),
1097
0
              "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
0
    } else {
1104
0
      tls_session->dirty_out.used = ret;
1105
0
      ret = 0;
1106
0
    }
1107
0
  }
1108
1109
0
finish:
1110
0
  fr_tls_session_request_unbind(tls_session->ssl);
1111
1112
0
  return ret;
1113
0
}
1114
1115
/** Instruct fr_tls_session_async_handshake to create a synthesised TLS alert record and send it to the peer
1116
 *
1117
 */
1118
int fr_tls_session_alert(UNUSED request_t *request, fr_tls_session_t *session, uint8_t level, uint8_t description)
1119
0
{
1120
0
  if (session->alerts_sent > 3) return -1;   /* Some kind of state machine brokenness */
1121
1122
  /*
1123
   *  Ignore less severe alerts
1124
   */
1125
0
  if (session->pending_alert && (level < session->pending_alert_level)) return 0;
1126
1127
0
  session->pending_alert = true;
1128
0
  session->pending_alert_level = level;
1129
0
  session->pending_alert_description = description;
1130
1131
0
  return 0;
1132
0
}
1133
1134
static void fr_tls_session_alert_send(request_t *request, fr_tls_session_t *session)
1135
0
{
1136
  /*
1137
   *  Update our internal view of the session
1138
   */
1139
0
  session->info.origin = TLS_INFO_ORIGIN_RECORD_SENT;
1140
0
  session->info.content_type = SSL3_RT_ALERT;
1141
0
  session->info.alert_level = session->pending_alert_level;
1142
0
  session->info.alert_description = session->pending_alert_description;
1143
1144
0
  session->dirty_out.data[0] = session->info.content_type;
1145
0
  session->dirty_out.data[1] = 3;
1146
0
  session->dirty_out.data[2] = 1;
1147
0
  session->dirty_out.data[3] = 0;
1148
0
  session->dirty_out.data[4] = 2;
1149
0
  session->dirty_out.data[5] = session->pending_alert_level;
1150
0
  session->dirty_out.data[6] = session->pending_alert_description;
1151
1152
0
  session->dirty_out.used = 7;
1153
1154
0
  session->pending_alert = false;
1155
0
  session->alerts_sent++;
1156
1157
0
  SSL_clear(session->ssl);  /* Reset the SSL *, to allow the client to restart the session */
1158
1159
0
  session_msg_log(request, session, session->dirty_out.data, session->dirty_out.used);
1160
0
}
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
 */
1166
static unlang_action_t tls_establish_session_result(UNUSED request_t *request, UNUSED void *uctx)
1167
0
{
1168
0
  return UNLANG_ACTION_CALCULATE_RESULT;
1169
0
}
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
 */
1180
static inline CC_HINT(always_inline)
1181
unlang_action_t tls_establish_session_push(request_t *request, fr_tls_conf_t *conf, fr_tls_session_t *tls_session)
1182
0
{
1183
0
  request_t *child;
1184
0
  fr_pair_t *vp;
1185
0
  unlang_action_t ua;
1186
0
  uint8_t const *session_id;
1187
0
  unsigned int  len;
1188
1189
0
  MEM(child = unlang_subrequest_alloc(request, dict_tls));
1190
0
  request = child;
1191
1192
  /*
1193
   *  Setup the child request for reporting session
1194
   */
1195
0
  MEM(pair_prepend_request(&vp, attr_tls_packet_type) >= 0);
1196
0
  vp->vp_uint32 = enum_tls_packet_type_establish_session->vb_uint32;
1197
1198
0
  session_id = SSL_SESSION_get_id(tls_session->session, &len);
1199
0
  if (session_id && (len > 0)) {
1200
0
    MEM(pair_append_request(&vp, attr_tls_session_id) >= 0);
1201
0
    fr_pair_value_memdup(vp, session_id, len, false);
1202
0
  }
1203
1204
  /*
1205
   *  Allocate a child, and set it up to call
1206
   *      the TLS virtual server.
1207
   */
1208
0
  ua = fr_tls_call_push(child, tls_establish_session_result, conf, tls_session, false);
1209
0
  if (ua < 0) {
1210
0
    talloc_free(child);
1211
0
    return UNLANG_ACTION_FAIL;
1212
0
  }
1213
1214
0
  return ua;
1215
0
}
1216
1217
/** Finish off a handshake round, possibly adding attributes to the request
1218
 *
1219
 */
1220
static unlang_action_t tls_session_async_handshake_done_round(request_t *request, void *uctx)
1221
0
{
1222
0
  fr_tls_session_t  *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1223
0
  int     ret;
1224
1225
0
  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
0
  if (SSL_is_init_finished(tls_session->ssl)) {
1237
0
    SSL_CIPHER const  *cipher;
1238
0
    fr_pair_t   *vp;
1239
0
    char const    *version;
1240
1241
0
    char cipher_desc[256], cipher_desc_clean[256];
1242
0
    char *p = cipher_desc, *q = cipher_desc_clean;
1243
1244
0
    cipher = SSL_get_current_cipher(tls_session->ssl);
1245
0
    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
0
    while (*p != '\0') {
1252
0
      if (isspace((uint8_t) *p)) {
1253
0
        *q++ = *p;
1254
0
        fr_skip_whitespace(p);
1255
0
        continue;
1256
0
      }
1257
0
      *q++ = *p++;
1258
0
    }
1259
0
    *q = '\0';
1260
1261
0
    RDEBUG2("Cipher suite: %s", cipher_desc_clean);
1262
1263
0
    RDEBUG2("Adding TLS session information to request");
1264
0
    RINDENT();
1265
0
    MEM(pair_update_session_state(&vp, attr_tls_session_cipher_suite) >= 0);
1266
0
    fr_pair_value_strdup(vp,  SSL_CIPHER_get_name(cipher), false);
1267
0
    RDEBUG2("session-state.%pP", vp);
1268
1269
0
    if (((size_t)tls_session->info.version >= NUM_ELEMENTS(tls_version_str)) ||
1270
0
        !tls_version_str[tls_session->info.version]) {
1271
0
      version = "UNKNOWN";
1272
0
    } else {
1273
0
      version = tls_version_str[tls_session->info.version];
1274
0
    }
1275
1276
0
    MEM(pair_update_session_state(&vp, attr_tls_session_version) >= 0);
1277
0
    fr_pair_value_strdup(vp, version, false);
1278
0
    RDEBUG2("session-state.%pP", vp);
1279
0
    REXDENT();
1280
1281
    /*
1282
     *  Cache the SSL_SESSION pointer.
1283
     *
1284
     *  Which contains all the data we need for session resumption.
1285
     */
1286
0
    if (!tls_session->session) {
1287
0
      tls_session->session = SSL_get_session(tls_session->ssl);
1288
0
      if (!tls_session->session) {
1289
0
        REDEBUG("Failed getting TLS session");
1290
0
      error:
1291
0
        tls_session->result = FR_TLS_RESULT_ERROR;
1292
0
        fr_tls_session_request_unbind(tls_session->ssl);
1293
0
        return UNLANG_ACTION_CALCULATE_RESULT;
1294
0
      }
1295
0
    }
1296
1297
0
    if (RDEBUG_ENABLED3) {
1298
0
      if (SSL_SESSION_print(fr_tls_request_log_bio(request, L_DBG, L_DBG_LVL_3),
1299
0
                tls_session->session) != 1) {
1300
0
        RDEBUG3("Failed retrieving session data");
1301
0
      }
1302
0
    }
1303
1304
    /*
1305
     *  Session was resumed, add attribute to mark it as such.
1306
     */
1307
0
    if (SSL_session_reused(tls_session->ssl)) {
1308
      /*
1309
       *  Mark the request as resumed.
1310
       */
1311
0
      MEM(pair_update_request(&vp, attr_session_resumed) >= 0);
1312
0
      vp->vp_bool = true;
1313
0
    }
1314
0
  }
1315
1316
  /*
1317
   *  Get data to pack and send back to the TLS peer.
1318
   */
1319
0
  ret = BIO_ctrl_pending(tls_session->from_ssl);
1320
0
  if (ret > 0) {
1321
0
    ret = BIO_read(tls_session->from_ssl, tls_session->dirty_out.data,
1322
0
             sizeof(tls_session->dirty_out.data));
1323
0
    if (ret > 0) {
1324
0
      tls_session->dirty_out.used = ret;
1325
0
    } else if (BIO_should_retry(tls_session->from_ssl)) {
1326
0
      record_init(&tls_session->dirty_in);
1327
0
      RDEBUG2("Asking for more data in tunnel");
1328
1329
0
    } else {
1330
0
      fr_tls_log(NULL, NULL);
1331
0
      record_init(&tls_session->dirty_in);
1332
0
      goto error;
1333
0
    }
1334
0
  } else {
1335
    /* Its clean application data, do whatever we want */
1336
0
    record_init(&tls_session->clean_out);
1337
0
  }
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
0
  if (tls_session->pending_alert) fr_tls_session_alert_send(request, tls_session);
1348
1349
  /* We are done with dirty_in, reinitialize it */
1350
0
  record_init(&tls_session->dirty_in);
1351
1352
0
  tls_session->result = FR_TLS_RESULT_SUCCESS;
1353
0
  fr_tls_session_request_unbind(tls_session->ssl);
1354
0
  if (SSL_is_init_finished(tls_session->ssl)) {
1355
0
    fr_tls_conf_t *conf = fr_tls_session_conf(tls_session->ssl);
1356
0
    if (conf->establish_session) return tls_establish_session_push(request, conf, tls_session);
1357
0
  }
1358
0
  return UNLANG_ACTION_CALCULATE_RESULT;
1359
0
}
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
 */
1369
static void tls_session_async_handshake_signal(UNUSED request_t *request, UNUSED fr_signal_t action, void *uctx)
1370
0
{
1371
0
  fr_tls_session_t  *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1372
0
  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
0
  for (ret = tls_session->last_ret;
1393
0
       SSL_get_error(tls_session->ssl, ret) == SSL_ERROR_WANT_ASYNC;
1394
0
       ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1395
0
                sizeof(tls_session->clean_out.data) - tls_session->clean_out.used));
1396
1397
  /*
1398
   *  Unbind the cancelled request from the SSL *
1399
   */
1400
0
  fr_tls_session_request_unbind(tls_session->ssl);
1401
0
}
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
 */
1413
static unlang_action_t tls_session_async_handshake_cont(request_t *request, void *uctx)
1414
0
{
1415
0
  fr_tls_session_t  *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1416
0
  int     err;
1417
1418
0
  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
0
  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
0
  tls_session->can_pause = true;
1460
0
  tls_session->last_ret = SSL_read(tls_session->ssl, tls_session->clean_out.data + tls_session->clean_out.used,
1461
0
           sizeof(tls_session->clean_out.data) - tls_session->clean_out.used);
1462
0
  tls_session->can_pause = false;
1463
0
  if (tls_session->last_ret > 0) {
1464
0
    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
0
    tls_session->result = FR_TLS_RESULT_SUCCESS;
1471
0
  finish:
1472
    /*
1473
     *  Was bound by caller
1474
     */
1475
0
    fr_tls_session_request_unbind(tls_session->ssl);
1476
0
    return UNLANG_ACTION_CALCULATE_RESULT;
1477
0
  }
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
0
  if (SSL_get_error(tls_session->ssl, tls_session->last_ret) == SSL_ERROR_SSL) {
1499
0
    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
     */
1506
0
DIAG_OFF(DIAG_UNKNOWN_PRAGMAS)
1507
0
DIAG_OFF(used-but-marked-unused)
1508
0
    while ((ssl_err = ERR_peek_error()) && (ERR_GET_REASON(ssl_err) == BIO_R_UNSUPPORTED_METHOD)) {
1509
0
      (void) ERR_get_error();
1510
0
    }
1511
0
DIAG_ON(used-but-marked-unused)
1512
0
DIAG_ON(DIAG_UNKNOWN_PRAGMAS)
1513
0
  }
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
0
  switch (err = SSL_get_error(tls_session->ssl, tls_session->last_ret)) {
1523
0
  case SSL_ERROR_WANT_ASYNC: /* Certification validation or cache loads */
1524
0
  {
1525
0
    unlang_action_t ua;
1526
1527
0
    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
0
    if (unlikely(unlang_function_repeat_set(request, tls_session_async_handshake_cont) < 0)) {
1534
0
    error:
1535
0
      tls_session->result = FR_TLS_RESULT_ERROR;
1536
0
      goto finish;
1537
0
    }
1538
1539
    /*
1540
     *  First service any pending cache actions
1541
     */
1542
0
    ua = fr_tls_cache_pending_push(request, tls_session);
1543
0
    switch (ua) {
1544
0
    case UNLANG_ACTION_FAIL:
1545
0
      IGNORE(unlang_function_clear(request), int);
1546
0
      goto error;
1547
1548
0
    case UNLANG_ACTION_PUSHED_CHILD:
1549
0
      return ua;
1550
1551
0
    default:
1552
0
      break;
1553
0
    }
1554
1555
    /*
1556
     *  Next service any pending certificate
1557
     *  validation actions.
1558
     */
1559
0
    ua = fr_tls_verify_cert_pending_push(request, tls_session);
1560
0
    switch (ua) {
1561
0
    case UNLANG_ACTION_FAIL:
1562
0
      IGNORE(unlang_function_clear(request), int);
1563
0
      goto error;
1564
1565
0
    default:
1566
0
      return ua;
1567
0
    }
1568
0
  }
1569
1570
0
  case SSL_ERROR_WANT_ASYNC_JOB:
1571
0
    RERROR("No async jobs available in pool, increase thread.openssl_async_pool_max");
1572
0
    goto error;
1573
1574
0
  default:
1575
    /*
1576
     *  Returns 0 if we can continue processing the handshake
1577
     *  Returns -1 if we encountered a fatal error.
1578
     */
1579
0
    if (fr_tls_log_io_error(request,
1580
0
          err, "SSL_read (%s)", __FUNCTION__) < 0) goto error;
1581
0
    return tls_session_async_handshake_done_round(request, uctx);
1582
0
  }
1583
0
}
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
 */
1600
static unlang_action_t tls_session_async_handshake(request_t *request, void *uctx)
1601
0
{
1602
0
  fr_tls_session_t *tls_session = talloc_get_type_abort(uctx, fr_tls_session_t);
1603
0
  int ret;
1604
1605
0
  RDEBUG3("entered state %s", __FUNCTION__);
1606
1607
0
  tls_session->result = FR_TLS_RESULT_IN_PROGRESS;
1608
1609
0
  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
0
  if (SSL_is_init_finished(tls_session->ssl)) {
1618
0
    REDEBUG("Attempted to continue TLS handshake, but handshake has completed");
1619
0
  error:
1620
0
    tls_session->result = FR_TLS_RESULT_ERROR;
1621
0
    fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1622
0
    return UNLANG_ACTION_CALCULATE_RESULT;
1623
0
  }
1624
1625
0
  if (tls_session->invalid) {
1626
0
    REDEBUG("Preventing invalid session from continuing");
1627
0
    goto error;
1628
0
  }
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
0
  if (tls_session->dirty_in.used) {
1636
0
    ret = BIO_write(tls_session->into_ssl, tls_session->dirty_in.data, tls_session->dirty_in.used);
1637
0
    if (ret != (int)tls_session->dirty_in.used) {
1638
0
      REDEBUG("Failed writing %zu bytes to TLS BIO: %d", tls_session->dirty_in.used, ret);
1639
0
      record_init(&tls_session->dirty_in);
1640
0
      goto error;
1641
0
    }
1642
0
    record_init(&tls_session->dirty_in);
1643
0
  }
1644
1645
0
  return tls_session_async_handshake_cont(request, uctx); /* Must unbind request, possibly asynchronously */
1646
0
}
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
 */
1663
unlang_action_t fr_tls_session_async_handshake_push(request_t *request, fr_tls_session_t *tls_session)
1664
0
{
1665
0
  return unlang_function_push(request,
1666
0
            tls_session_async_handshake,
1667
0
            NULL,
1668
0
            tls_session_async_handshake_signal,
1669
0
            ~FR_SIGNAL_CANCEL,
1670
0
            UNLANG_SUB_FRAME,
1671
0
            tls_session);
1672
0
}
1673
1674
/** Free a TLS session and any associated OpenSSL data
1675
 *
1676
 * @param session to free.
1677
 * @return 0.
1678
 */
1679
static int _fr_tls_session_free(fr_tls_session_t *session)
1680
0
{
1681
0
  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
0
    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
0
    if (SSL_shutdown(session->ssl) != 1) ERR_clear_error();
1704
1705
0
    SSL_free(session->ssl);
1706
0
    session->ssl = NULL;
1707
0
  }
1708
1709
0
  return 0;
1710
0
}
1711
1712
static void session_init(fr_tls_session_t *session)
1713
0
{
1714
0
  session->ssl = NULL;
1715
0
  session->into_ssl = session->from_ssl = NULL;
1716
0
  record_init(&session->clean_in);
1717
0
  record_init(&session->clean_out);
1718
0
  record_init(&session->dirty_in);
1719
0
  record_init(&session->dirty_out);
1720
1721
0
  memset(&session->info, 0, sizeof(session->info));
1722
1723
0
  session->mtu = 0;
1724
0
  session->opaque = NULL;
1725
0
}
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
 */
1738
fr_tls_session_t *fr_tls_session_alloc_client(TALLOC_CTX *ctx, SSL_CTX *ssl_ctx)
1739
0
{
1740
0
  int     verify_mode;
1741
0
  fr_tls_session_t  *tls_session = NULL;
1742
0
  fr_tls_conf_t   *conf = fr_tls_ctx_conf(ssl_ctx);
1743
1744
0
  MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1745
0
  talloc_set_destructor(tls_session, _fr_tls_session_free);
1746
0
  fr_pair_list_init(&tls_session->extra_pairs);
1747
1748
0
  tls_session->ssl = SSL_new(ssl_ctx);
1749
0
  if (!tls_session->ssl) {
1750
0
    talloc_free(tls_session);
1751
0
    return NULL;
1752
0
  }
1753
1754
  /*
1755
   *  Add the message callback to identify what type of
1756
   *  message/handshake is passed
1757
   */
1758
0
  SSL_set_msg_callback(tls_session->ssl, fr_tls_session_msg_cb);
1759
0
  SSL_set_msg_callback_arg(tls_session->ssl, tls_session);
1760
0
  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
0
  SSL_set_connect_state(tls_session->ssl);
1769
1770
  /*
1771
   *  Always verify the peer certificate.
1772
   */
1773
0
  DEBUG2("Requiring Server certificate");
1774
0
  verify_mode = SSL_VERIFY_PEER;
1775
0
  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
0
  SSL_set_verify(tls_session->ssl, verify_mode, NULL);
1787
0
  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1788
0
  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1789
1790
0
  tls_session->mtu = conf->fragment_size;
1791
1792
0
  return tls_session;
1793
0
}
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
 */
1810
fr_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
0
{
1812
0
  fr_tls_session_t  *tls_session = NULL;
1813
0
  SSL     *ssl = NULL;
1814
0
  int     verify_mode = 0;
1815
0
  fr_pair_t   *vp;
1816
0
  fr_tls_conf_t   *conf = fr_tls_ctx_conf(ssl_ctx);
1817
1818
0
  RDEBUG2("Initiating new TLS session");
1819
1820
0
  MEM(tls_session = talloc_zero(ctx, fr_tls_session_t));
1821
1822
0
  ssl = SSL_new(ssl_ctx);
1823
0
  if (ssl == NULL) {
1824
0
    talloc_free(tls_session);
1825
0
    fr_tls_log(request, "Error creating new TLS session");
1826
0
    return NULL;
1827
0
  }
1828
0
  fr_pair_list_init(&tls_session->extra_pairs);
1829
1830
0
  session_init(tls_session);
1831
0
  tls_session->ctx = ssl_ctx;
1832
0
  tls_session->ssl = ssl;
1833
0
  talloc_set_destructor(tls_session, _fr_tls_session_free);
1834
1835
0
  fr_tls_session_request_bind(tls_session->ssl, request);  /* Is unbound in this function */
1836
1837
  /*
1838
   *  Initialize callbacks
1839
   */
1840
0
  tls_session->record_init = record_init;
1841
0
  tls_session->record_close = record_close;
1842
0
  tls_session->record_from_buff = record_from_buff;
1843
0
  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
0
  MEM(tls_session->into_ssl = BIO_new(BIO_s_mem()));
1856
0
  MEM(tls_session->from_ssl = BIO_new(BIO_s_mem()));
1857
0
  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
0
  SSL_set_msg_callback(ssl, fr_tls_session_msg_cb);
1864
0
  SSL_set_msg_callback_arg(ssl, tls_session);
1865
0
  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
0
  if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1884
0
    char    *context_id;
1885
0
    EVP_MD_CTX  *md_ctx;
1886
0
    uint8_t   digest[SHA256_DIGEST_LENGTH];
1887
1888
0
    static_assert(sizeof(digest) <= SSL_MAX_SSL_SESSION_ID_LENGTH,
1889
0
            "SSL_MAX_SSL_SESSION_ID_LENGTH must be >= SHA256_DIGEST_LENGTH");
1890
0
    fr_assert(conf->cache.id_name);
1891
1892
0
    if (tmpl_aexpand(tls_session, &context_id, request, conf->cache.id_name, NULL, NULL) < 0) {
1893
0
      RPEDEBUG("Failed expanding session ID");
1894
0
    error:
1895
0
      fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1896
0
      talloc_free(tls_session);
1897
0
      return NULL;
1898
0
    }
1899
1900
0
    MEM(md_ctx = EVP_MD_CTX_create());
1901
0
    EVP_DigestInit_ex(md_ctx, EVP_sha256(), NULL);
1902
0
    EVP_DigestUpdate(md_ctx, context_id, talloc_strlen(context_id));
1903
0
    EVP_DigestFinal_ex(md_ctx, digest, NULL);
1904
0
    EVP_MD_CTX_destroy(md_ctx);
1905
0
    talloc_free(context_id);
1906
1907
0
    if (!fr_cond_assert(SSL_set_session_id_context(tls_session->ssl,
1908
0
                     digest, sizeof(digest)) == 1)) goto error;
1909
0
  }
1910
1911
  /*
1912
   *  Add the session certificate to the session.
1913
   */
1914
0
  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_cert_file);
1915
0
  if (vp) {
1916
0
    RDEBUG2("Loading TLS session certificate \"%pV\"", &vp->data);
1917
1918
0
    if (SSL_use_certificate_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1919
0
      fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1920
0
              vp->vp_strvalue);
1921
0
      goto error;
1922
0
    }
1923
1924
0
    if (SSL_use_PrivateKey_file(tls_session->ssl, vp->vp_strvalue, SSL_FILETYPE_PEM) != 1) {
1925
0
      fr_tls_log(request, "Failed loading TLS session certificate \"%s\"",
1926
0
              vp->vp_strvalue);
1927
0
      goto error;
1928
0
    }
1929
1930
0
    if (SSL_check_private_key(tls_session->ssl) != 1) {
1931
0
      fr_tls_log(request, "Failed validating TLS session certificate \"%s\"",
1932
0
              vp->vp_strvalue);
1933
0
      goto error;
1934
0
    }
1935
  /*
1936
   *  Better to perform explicit checks, than rely
1937
   *  on OpenSSL's opaque error messages.
1938
   */
1939
0
  } else {
1940
0
    if (!conf->chains || !conf->chains[0]->private_key_file) {
1941
0
      ERROR("TLS Server requires a private key file");
1942
0
      goto error;
1943
0
    }
1944
1945
0
    if (!conf->chains || !conf->chains[0]->certificate_file) {
1946
0
      ERROR("TLS Server requires a certificate file");
1947
0
      goto error;
1948
0
    }
1949
0
  }
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
0
  vp = fr_pair_find_by_da(&request->control_pairs, NULL, attr_tls_session_require_client_cert);
1957
0
  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
0
  SSL_set_accept_state(tls_session->ssl);
1966
1967
  /*
1968
   *  Verify the peer certificate, if asked.
1969
   */
1970
0
  if (client_cert) {
1971
0
    RDEBUG2("Setting verify mode to require certificate from client");
1972
0
    verify_mode = SSL_VERIFY_PEER;
1973
0
    verify_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
1974
0
    verify_mode |= SSL_VERIFY_CLIENT_ONCE;
1975
0
  }
1976
0
  tls_session->verify_client_cert = client_cert;
1977
1978
0
  SSL_set_verify(tls_session->ssl, verify_mode, fr_tls_verify_cert_cb);
1979
0
  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_CONF, (void *)conf);
1980
0
  SSL_set_ex_data(tls_session->ssl, FR_TLS_EX_INDEX_TLS_SESSION, (void *)tls_session);
1981
1982
0
  if (conf->client_hello_parse) {
1983
0
    SSL_CTX_set_client_hello_cb(ssl_ctx, fr_tls_session_client_hello_cb, NULL);
1984
0
  }
1985
1986
0
  tls_session->mtu = conf->fragment_size;
1987
0
  if (dynamic_mtu > 100 && dynamic_mtu < tls_session->mtu) {
1988
0
    RDEBUG2("Setting fragment_len to %zu from dynamic_mtu", dynamic_mtu);
1989
0
    tls_session->mtu = dynamic_mtu;
1990
0
  }
1991
1992
0
  if (conf->cache.mode != FR_TLS_CACHE_DISABLED) {
1993
0
    tls_session->allow_session_resumption = true; /* otherwise it's false */
1994
0
    fr_tls_cache_session_alloc(tls_session);
1995
0
  }
1996
1997
0
  fr_tls_session_request_unbind(tls_session->ssl); /* Was bound in this function */
1998
1999
0
  return tls_session;
2000
0
}
2001
2002
static unlang_action_t tls_new_session_result(request_t *request, UNUSED void *uctx)
2003
0
{
2004
0
  request_t *parent = request->parent;
2005
2006
0
  fr_assert(parent);
2007
2008
  /*
2009
   *  Copy control attributes back to the parent.
2010
   */
2011
0
  if (fr_pair_list_copy(parent->control_ctx, &parent->control_pairs, &request->control_pairs) < 0) return UNLANG_ACTION_FAIL;
2012
2013
0
  return UNLANG_ACTION_CALCULATE_RESULT;
2014
0
}
2015
2016
unlang_action_t fr_tls_new_session_push(request_t *request, fr_tls_conf_t const *tls_conf)
2017
0
{
2018
0
  request_t *child;
2019
0
  fr_pair_t *vp;
2020
2021
0
  MEM(child = unlang_subrequest_alloc(request, dict_tls));
2022
2023
0
  MEM(pair_prepend_request(&vp, attr_tls_packet_type) >= 0);
2024
0
  vp->vp_uint32 = enum_tls_packet_type_new_session->vb_uint32;
2025
2026
0
  if (unlang_subrequest_child_push(NULL, child, request, true, UNLANG_SUB_FRAME) < 0) {
2027
0
    talloc_free(child);
2028
0
    return UNLANG_ACTION_FAIL;
2029
0
  }
2030
2031
0
  if (unlang_function_push(child,
2032
0
         NULL,
2033
0
         tls_new_session_result,
2034
0
         NULL, 0,
2035
0
         UNLANG_SUB_FRAME, NULL) < 0) {
2036
0
    talloc_free(child);
2037
0
    return UNLANG_ACTION_FAIL;
2038
0
  }
2039
2040
0
  if (unlang_call_push(NULL, child, tls_conf->virtual_server, UNLANG_SUB_FRAME) < 0) {
2041
0
    talloc_free(child);
2042
0
    return UNLANG_ACTION_FAIL;
2043
0
  }
2044
2045
0
  return UNLANG_ACTION_PUSHED_CHILD;
2046
0
}
2047
#endif /* WITH_TLS */