Coverage Report

Created: 2026-07-12 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ntpsec/ntpd/nts_server.c
Line
Count
Source
1
/*
2
 * nts_server.c - Network Time Security (NTS) server side support
3
 * Copyright the NTPsec project contributors
4
 * SPDX-License-Identifier: BSD-2-Clause
5
 *
6
 * Section references are to
7
 * https://tools.ietf.org/html/rfc8915
8
 *
9
 */
10
#include "config.h"
11
12
#include <signal.h>
13
#include <pthread.h>
14
#include <unistd.h>
15
#include <sys/socket.h>
16
#include <sys/time.h>
17
#include <sys/resource.h>
18
19
#include <openssl/ssl.h>
20
#include <openssl/err.h>
21
#include <openssl/x509.h>
22
23
#include "ntp.h"
24
#include "ntpd.h"
25
#include "ntp_stdlib.h"
26
#include "nts.h"
27
#include "nts2.h"
28
#include "timespecops.h"
29
30
/* Beware: bind and accept take type sockaddr, but that's not big
31
 *         enough for an IPv6 address.
32
 */
33
34
35
static bool create_listener4(int port);
36
static bool create_listener6(int port);
37
static void* nts_ke_listener(void*);
38
static void nts_ke_request(SSL *ssl,
39
  char *errbuf, int errlng, const char **errtxt);
40
static void nts_ke_accept_fail(char* hostname,
41
    double wall, double usr, double sys, int code);
42
43
static void nts_lock_certlock(void);
44
static void nts_unlock_certlock(void);
45
46
47
static SSL_CTX *server_ctx = NULL;
48
static int listener4_sock = -1;
49
static int listener6_sock = -1;
50
51
static void nts_ke_setup_send(struct BufCtl_t *buf, int aead,
52
       uint8_t *c2s, uint8_t *s2c, int keylen);
53
54
/* We need a lock to protect reloading our certificate.
55
 * This seems like overkill, but it doesn't happen often. */
56
pthread_mutex_t certificate_lock = PTHREAD_MUTEX_INITIALIZER;
57
58
static int alpn_select_cb(SSL *ssl,
59
        const unsigned char **out,
60
        unsigned char *outlen,
61
        const unsigned char *in,
62
        unsigned int inlen,
63
        void *arg)
64
0
{
65
0
  static const unsigned char alpn[] = {
66
0
            'n', 't', 's', 'k', 'e', '/', '1' };
67
0
  unsigned i, len;
68
69
0
  UNUSED_ARG(ssl);
70
0
  UNUSED_ARG(arg);
71
72
0
  for (i = 0; i < inlen; i += len+1) {
73
0
    len = in[i]; // first byte is the length
74
#if 0
75
    char foo[256];
76
    strlcpy(foo, (const char*)in+i+1, len);
77
    msyslog(LOG_DEBUG, "DEBUG: alpn_select_cb:  %u, %u, %s", inlen-i, len, foo);
78
#endif
79
0
    if (len+1 > inlen-i)
80
      /* bogus arg: length overlaps end of in buffer */
81
0
      return SSL_TLSEXT_ERR_ALERT_FATAL;
82
0
    if (len == sizeof(alpn) && !memcmp(in+i+1, alpn, len)) {
83
0
      *out = in+i+1;
84
0
      *outlen = len;
85
0
      return SSL_TLSEXT_ERR_OK;
86
0
    }
87
0
  }
88
89
0
  return SSL_TLSEXT_ERR_NOACK;
90
0
}
91
92
0
bool nts_server_init(void) {
93
0
  bool ok = true;
94
95
0
  msyslog(LOG_INFO, "NTSs: starting NTS-KE server listening on port %d",
96
0
    NTS_KE_PORT);
97
98
0
  server_ctx = SSL_CTX_new(TLS_server_method());
99
0
  if (NULL == server_ctx) {
100
    /* Happens if no ciphers */
101
0
    msyslog(LOG_INFO, "NTSs: NULL server_ctx");
102
0
    nts_log_ssl_error();
103
0
    return false;
104
0
  }
105
106
0
  SSL_CTX_set_alpn_select_cb(server_ctx, alpn_select_cb, NULL);
107
0
  SSL_CTX_set_session_cache_mode(server_ctx, SSL_SESS_CACHE_OFF);
108
0
  SSL_CTX_set_timeout(server_ctx, NTS_KE_TIMEOUT);  /* session lifetime */
109
110
0
  ok &= nts_load_versions(server_ctx);
111
0
  ok &= nts_load_ciphers(server_ctx);
112
0
  ok &= nts_load_ecdhcurves(server_ctx);
113
0
  ok &= nts_set_cipher_order(server_ctx);
114
115
0
  if (!ok) {
116
0
    msyslog(LOG_ERR, "NTSs: Disabling NTS-KE server");
117
0
    SSL_CTX_free(server_ctx);
118
0
    server_ctx = NULL;
119
0
    return false;
120
0
  };
121
122
0
  msyslog(LOG_INFO, "NTSs: OpenSSL security level is %d",
123
0
    SSL_CTX_get_security_level(server_ctx));
124
125
0
  msyslog(LOG_INFO, "NTSs: starting NTS-KE server listening on port %d",
126
0
    NTS_KE_PORT);
127
0
  ok &= create_listener4(NTS_KE_PORT);
128
0
  ok &= create_listener6(NTS_KE_PORT);
129
130
0
  return ok;
131
0
}
132
133
0
bool nts_server_init2(void) {
134
0
  pthread_t worker;
135
0
  sigset_t block_mask, saved_sig_mask;
136
0
  int rc;
137
0
  char errbuf[100];
138
139
0
  if (!nts_load_certificate(server_ctx)) {
140
0
    return false;
141
0
  }
142
143
0
  sigfillset(&block_mask);
144
0
  pthread_sigmask(SIG_BLOCK, &block_mask, &saved_sig_mask);
145
0
  if (listener4_sock != -1) {
146
0
    rc = pthread_create(&worker, NULL, nts_ke_listener, &listener4_sock);
147
0
    if (rc) {
148
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
149
0
      msyslog(LOG_ERR, "NTSs: nts_start_server4: error from pthread_create: %s", errbuf);
150
0
    }
151
0
  }
152
0
  if (listener6_sock != -1) {
153
0
    rc = pthread_create(&worker, NULL, nts_ke_listener, &listener6_sock);
154
0
    if (rc) {
155
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
156
0
      msyslog(LOG_ERR, "NTSs: nts_start_server6: error from pthread_create: %s", errbuf);
157
0
    }
158
0
  }
159
0
  pthread_sigmask(SIG_SETMASK, &saved_sig_mask, NULL);
160
161
0
  return true;
162
0
}
163
164
/* called every hour */
165
0
void nts_cert_timer(void) {
166
0
  check_cert_file();
167
0
}
168
169
/* call hourly and by SIGHUP */
170
0
void check_cert_file(void) {
171
0
  if (NULL == server_ctx)
172
0
    return;
173
0
  nts_lock_certlock();
174
0
  nts_reload_certificate(server_ctx);
175
0
  nts_unlock_certlock();
176
0
}
177
178
0
void nts_lock_certlock(void) {
179
0
  int err = pthread_mutex_lock(&certificate_lock);
180
0
  if (0 != err) {
181
0
    msyslog(LOG_ERR, "ERR: Can't lock certificate_lock: %d", err);
182
0
    exit(2);
183
0
  }
184
0
}
185
186
0
void nts_unlock_certlock(void) {
187
0
  int err = pthread_mutex_unlock(&certificate_lock);
188
0
  if (0 != err) {
189
0
    msyslog(LOG_ERR, "ERR: Can't unlock certificate_lock: %d", err);
190
0
    exit(2);
191
0
  }
192
0
}
193
194
/* lfptod goes to long double */
195
0
static inline double lfptox(l_fp r) {
196
/* l_fp to double */
197
0
        return ldexp((double)((int64_t)r), -32);
198
0
}
199
200
201
0
void* nts_ke_listener(void* arg) {
202
0
  struct timeval timeout = {.tv_sec = NTS_KE_TIMEOUT, .tv_usec = 0};
203
0
  int sock = *(int*)arg;
204
0
  char errbuf[100];
205
0
  char addrbuf[100];
206
0
  char usingbuf[100];
207
0
  struct timespec start, finish;    /* wall clock */
208
0
  l_fp wall, usr, sys;
209
0
  const char *errtxt; /* not NULL if error */
210
0
#ifdef RUSAGE_THREAD
211
  /* Not in NetBSD 10.1, 2026-Apr-05 */
212
0
  struct timespec start_u, finish_u;  /* CPU user */
213
0
  struct timespec start_s, finish_s;  /* CPU system */
214
0
  struct rusage usage;
215
0
#endif
216
217
#ifdef HAVE_SECCOMP_H
218
        setup_SIGSYS_trap();   /* enable trap for this thread */
219
#endif
220
221
0
#ifdef RUSAGE_THREAD
222
  /* NB: start_u and start_s are from near the end of the previous cycle.
223
   * Thus usage timing includes the TCP accept and
224
   * writing the previous msyslog message.
225
   */
226
0
  getrusage(RUSAGE_THREAD, &usage);
227
0
  start_u = tval_to_tspec(usage.ru_utime);
228
0
  start_s = tval_to_tspec(usage.ru_stime);
229
#else
230
  usr = 0;
231
  sys = 0;
232
#endif
233
234
0
  while(1) {
235
0
    NTSKE_Status status = NTSKE_SSL_Failed;
236
0
    sockaddr_u addr;
237
0
    socklen_t len = sizeof(addr);
238
0
    SSL *ssl;
239
0
    int client, err;
240
241
0
    sleep(1);     /* FIXME: log clutter/DoS */
242
0
    errtxt = NULL;
243
0
    client = accept(sock, &addr.sa, &len);
244
0
    if (client < 0) {
245
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
246
0
      msyslog(LOG_ERR, "NTSs: TCP accept failed: %s", errbuf);
247
0
      if (EBADF == errno)
248
0
        return NULL;
249
0
      continue;
250
0
    }
251
0
    clock_gettime(CLOCK_MONOTONIC, &start);
252
0
    sockporttoa_r(&addr, addrbuf, sizeof(addrbuf));
253
254
/* This is disabled in order to reduce clutter in the log file.
255
 * The client's address is now included in the final message.
256
 * That works fine in the normal successful case.  There is one line
257
 * per connection.
258
 * The failed cases are more complicated.
259
 * The common fail case is bad guys probing which fails in SSL_accept.
260
 * That branch has its own error handling.  Again, the common cases
261
 * have one line per connection and include the client address.
262
 * Uncommon cases will include two (or more) lines.
263
 * There are many possible error messages after SSL_accept works.
264
 * In practice, they don't happen, at least not often enough to notice.
265
 * They currently get logged without the client's address.  Then they
266
 * fall into the normal (non-error) path which does include the address.
267
 * Enabling this might make strange cases easier to understand.
268
 */
269
/*    msyslog(LOG_INFO, "NTSs: TCP accept-ed from %s", addrbuf); */
270
271
0
    err = setsockopt(client, SOL_SOCKET, SO_RCVTIMEO,
272
0
      &timeout, sizeof(timeout));
273
0
    if (0 > err) {
274
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
275
0
      msyslog(LOG_ERR, "NTSs: can't set recv timeout: %s", errbuf);
276
0
      close(client);
277
0
      ntske_cnt.serves_bad++;
278
0
      continue;
279
0
    }
280
0
    err = setsockopt(client, SOL_SOCKET, SO_SNDTIMEO,
281
0
      &timeout, sizeof(timeout));
282
0
    if (0 > err) {
283
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
284
0
      msyslog(LOG_ERR, "NTSs: can't set send timeout: %s", errbuf);
285
0
      close(client);
286
0
      ntske_cnt.serves_bad++;
287
0
      continue;
288
0
    }
289
290
    /* WARN: For high volume servers, this should go in a new thread. */
291
0
    nts_lock_certlock();
292
0
    ssl = SSL_new(server_ctx);
293
0
    nts_unlock_certlock();
294
0
    SSL_set_fd(ssl, client);
295
296
0
    err = SSL_accept(ssl);
297
0
    if (0 >= err) {
298
0
      int code = SSL_get_error(ssl, err);
299
0
      SSL_free(ssl);
300
0
      close(client);
301
0
      clock_gettime(CLOCK_MONOTONIC, &finish);
302
0
      wall = tspec_intv_to_lfp(sub_tspec(finish, start));
303
0
#ifdef RUSAGE_THREAD
304
0
      getrusage(RUSAGE_THREAD, &usage);
305
0
      finish_u = tval_to_tspec(usage.ru_utime);
306
0
      finish_s = tval_to_tspec(usage.ru_stime);
307
0
      usr = tspec_intv_to_lfp(sub_tspec(finish_u, start_u));
308
0
      sys = tspec_intv_to_lfp(sub_tspec(finish_s, start_s));
309
0
      start_u = finish_u;
310
0
      start_s = finish_s;
311
0
#endif
312
0
      nts_ke_accept_fail(addrbuf,
313
0
        lfptox(wall), lfptox(usr), lfptox(sys), code);
314
0
      continue;
315
0
    }
316
317
    /* Save info for final message. */
318
0
    snprintf(usingbuf, sizeof(usingbuf), "%s:%s(%d)",
319
0
      SSL_get_version(ssl),
320
0
      SSL_get_cipher_name(ssl),
321
0
      SSL_get_cipher_bits(ssl, NULL));
322
323
0
    status = NTSKE_Failed;
324
0
    nts_ke_request(ssl, errbuf, sizeof(errbuf), &errtxt);
325
0
    if (NULL==errtxt) status = NTSKE_OK;
326
327
0
    SSL_shutdown(ssl);
328
0
    SSL_free(ssl);
329
0
    close(client);
330
331
0
    clock_gettime(CLOCK_MONOTONIC, &finish);
332
0
    wall = tspec_intv_to_lfp(sub_tspec(finish, start));
333
0
#ifdef RUSAGE_THREAD
334
0
    getrusage(RUSAGE_THREAD, &usage);
335
0
    finish_u = tval_to_tspec(usage.ru_utime);
336
0
    finish_s = tval_to_tspec(usage.ru_stime);
337
0
    usr = tspec_intv_to_lfp(sub_tspec(finish_u, start_u));
338
0
    sys = tspec_intv_to_lfp(sub_tspec(finish_s, start_s));
339
0
    start_u = finish_u;
340
0
    start_s = finish_s;
341
0
#endif
342
0
    record_ntske_log(status, addrbuf, usingbuf,
343
0
      lfptox(wall), lfptox(usr), lfptox(sys),
344
0
      errtxt);
345
0
  }
346
347
0
  return NULL;
348
0
}
349
350
/* Analyze failure from SSL_accept
351
 * print single error message for common cases.
352
 * Similar code in nts.c, nts_ssl_read() and nts_ssl_write()
353
 */
354
void nts_ke_accept_fail(char* hostname,
355
0
    double wall, double usr, double sys, int code) {
356
0
  unsigned long err = ERR_peek_error();
357
0
  char errbuf[100];
358
0
  char buff[200];
359
0
  const char *msg = NULL;
360
0
  const char *errmsg = NULL;
361
0
  if (0 == err) {
362
0
    switch (code) {
363
0
      case SSL_ERROR_WANT_READ:
364
0
        msg = "Timeout";
365
0
        break;
366
0
      case SSL_ERROR_SYSCALL:
367
0
        if (ECONNRESET==errno) {
368
0
          msg = "Connection reset";
369
0
          break;
370
0
        }
371
        /* fall through */
372
0
      default:
373
0
        ntp_strerror_r(errno, errbuf, sizeof(errbuf));
374
0
        snprintf(buff, sizeof(buff), "code %d, errno=>%d, %s",
375
0
    code, errno, errbuf);
376
0
        msg = buff;
377
0
        break;
378
0
    }
379
0
  } else {
380
0
    if (code==SSL_ERROR_SSL) {
381
0
      msg = ERR_reason_error_string(err);
382
0
      err = 0;
383
0
    } else {
384
      // Maybe we need to handle other codes
385
0
      ntp_strerror_r(errno, errbuf, sizeof(errbuf));
386
0
      snprintf(buff, sizeof(buff), "code %d, errno=>%d, %s, %lx=>%s",
387
0
        code, errno, errbuf, err, ERR_reason_error_string(err));
388
0
      err = 0;
389
0
      msg = buff;
390
0
    }
391
0
  }
392
0
  record_ntske_log(NTSKE_SSL_Failed, hostname, msg,
393
0
    wall, usr, sys, errmsg);
394
0
}
395
396
397
void nts_ke_request(SSL *ssl,
398
0
  char *errbuf, int errlng, const char **errtxt) {
399
  /* RFC 4: servers must accept 1024
400
   * Our cookies can be 104, 136, or 168 for AES_SIV_CMAC_xxx
401
   * 8*168 fits comfortably into 2K.
402
   */
403
0
  uint8_t buff[2048];
404
0
  uint8_t c2s[NTS_MAX_KEYLEN], s2c[NTS_MAX_KEYLEN];
405
0
  int aead = NO_AEAD, keylen;
406
0
  struct BufCtl_t buf;
407
0
  int bytes_read, bytes_written;
408
0
  int used;
409
410
0
  bytes_read = nts_ssl_read(ssl, buff, sizeof(buff), errtxt);
411
0
  if (0 >= bytes_read)
412
0
    return;
413
414
0
  buf.next = buff;
415
0
  buf.left = bytes_read;
416
0
  if (!nts_ke_process_receive(&buf, &aead, errbuf, errlng, errtxt)) {
417
0
    return;
418
0
  }
419
420
0
  if ((NO_AEAD == aead) && (NULL != ntsconfig.aead))
421
0
    aead = nts_string_to_aead(ntsconfig.aead);
422
0
  if (NO_AEAD == aead)
423
0
    aead = AEAD_AES_SIV_CMAC_256;    /* default */
424
425
0
  keylen = nts_get_key_length(aead);
426
0
  if (!nts_make_keys(ssl, aead, c2s, s2c, keylen)) {
427
0
    *errtxt = "Can't make keys";
428
0
    return;
429
0
  }
430
431
0
  buf.next = buff;
432
0
  buf.left = sizeof(buff);
433
0
  nts_ke_setup_send(&buf, aead, c2s, s2c, keylen);
434
435
0
  used = sizeof(buff)-buf.left;
436
0
  bytes_written = nts_ssl_write(ssl, buff, used, errtxt);
437
0
  if (bytes_written != used)
438
0
    return;
439
440
/* FIXME: Need counters for AEAD */
441
442
0
  return;
443
0
}
444
445
0
bool create_listener4(int port) {
446
0
  int sock = -1;
447
0
  sockaddr_u addr;
448
0
  int on = 1;
449
0
  int err;
450
0
  char errbuf[100];
451
452
0
  addr.sa4.sin_family = AF_INET;
453
0
  addr.sa4.sin_port = htons(port);
454
0
  addr.sa4.sin_addr.s_addr= htonl(INADDR_ANY);
455
0
  sock = socket(AF_INET, SOCK_STREAM, 0);
456
0
  if (sock < 0) {
457
0
    if (EAFNOSUPPORT == errno) {
458
0
      msyslog(LOG_ERR, "NTSs: No IPv4 support, disabling NTS-KE listener");
459
0
      return true;
460
0
    }
461
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
462
0
    msyslog(LOG_ERR, "NTSs: Can't create socket4: %s", errbuf);
463
0
    return false;
464
0
  }
465
0
  err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
466
0
  if (0 > err) {
467
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
468
0
    msyslog(LOG_ERR, "NTSs: can't setsockopt4: %s", errbuf);
469
0
    close(sock);
470
0
    return false;
471
0
  }
472
0
  err = bind(sock, &addr.sa, sizeof(addr.sa4));
473
0
  if (0 > err) {
474
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
475
0
    msyslog(LOG_ERR, "NTSs: can't bind4: %s", errbuf);
476
0
    close(sock);
477
0
    return false;
478
0
  }
479
0
  if (listen(sock, 6) < 0) {
480
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
481
0
    msyslog(LOG_ERR, "NTSs: can't listen4: %s", errbuf);
482
0
    close(sock);
483
0
    return false;
484
0
  }
485
0
  msyslog(LOG_INFO, "NTSs: listen4 worked");
486
487
0
  listener4_sock = sock;
488
0
  return true;
489
0
}
490
491
0
bool create_listener6(int port) {
492
0
  int sock = -1;
493
0
  sockaddr_u addr;
494
0
  int on = 1;
495
0
  int err;
496
0
  char errbuf[100];
497
498
0
  addr.sa6.sin6_family = AF_INET6;
499
0
  addr.sa6.sin6_port = htons(port);
500
0
  addr.sa6.sin6_addr = in6addr_any;
501
0
  sock = socket(AF_INET6, SOCK_STREAM, 0);
502
0
  if (sock < 0) {
503
0
    if (EAFNOSUPPORT == errno) {
504
0
      msyslog(LOG_ERR, "NTSs: No IPv6 support, disabling NTS-KE listener");
505
0
      return true;
506
0
    }
507
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
508
0
    msyslog(LOG_ERR, "NTSs: Can't create socket6: %s", errbuf);
509
0
    return false;
510
0
  }
511
  /* Hack to keep IPV6 from listening on IPV4 too */
512
0
  err = setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on));
513
0
  if (0 > err) {
514
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
515
0
    msyslog(LOG_ERR, "NTSs: can't setsockopt6only: %s", errbuf);
516
0
    close(sock);
517
0
    return false;
518
0
  }
519
0
  err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
520
0
  if (0 > err) {
521
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
522
0
    msyslog(LOG_ERR, "NTSs: can't setsockopt6: %s", errbuf);
523
0
    close(sock);
524
0
    return false;
525
0
  }
526
0
  err = bind(sock, &addr.sa, sizeof(addr.sa6));
527
0
  if (0 > err) {
528
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
529
0
    msyslog(LOG_ERR, "NTSs: can't bind6: %s", errbuf);
530
0
    close(sock);
531
0
    return false;
532
0
  }
533
0
  if (listen(sock, 6) < 0) {
534
0
    ntp_strerror_r(errno, errbuf, sizeof(errbuf));
535
0
    msyslog(LOG_ERR, "NTSs: can't listen6: %s", errbuf);
536
0
    close(sock);
537
0
    return false;
538
0
  }
539
0
  msyslog(LOG_INFO, "NTSs: listen6 worked");
540
541
0
  listener6_sock = sock;
542
0
  return true;
543
0
}
544
545
bool nts_ke_process_receive(struct BufCtl_t *buf, int *aead,
546
0
  char *errbuf, int errlng, const char **errtxt) {
547
0
  while (buf->left >= NTS_KE_HDR_LNG) {
548
0
    uint16_t type, data;
549
0
    int length;
550
0
    bool critical = false;
551
0
    type = ke_next_record(buf, &length);
552
0
                if (length > buf->left) {
553
0
      snprintf(errbuf, errlng,
554
0
        "Chunk too big: 0x%x, %d, %d",
555
0
                                type, buf->left, length);
556
0
      *errtxt = errbuf;
557
0
                        return false;
558
0
                }
559
0
    if (NTS_CRITICAL & type) {
560
0
      critical = true;
561
0
      type &= ~NTS_CRITICAL;
562
0
    }
563
0
    if (0) // Handy for debugging but very verbose
564
0
      msyslog(LOG_INFO, "NTSs: Record: T=%d, L=%d, C=%d", type, length, critical);
565
0
    switch (type) {
566
0
        case nts_error:
567
0
      if (sizeof(data) != length) {
568
0
        snprintf(errbuf, errlng,
569
0
          "Wrong length on error: %d", length);
570
0
        *errtxt = errbuf;
571
0
        return false;
572
0
      }
573
0
      data = next_uint16(buf);
574
0
      snprintf(errbuf, errlng,
575
0
        "Received error: %d", data);
576
0
      *errtxt = errbuf;
577
0
      return false;
578
0
        case nts_next_protocol_negotiation:
579
0
      if (sizeof(data) != length) {
580
0
        snprintf(errbuf, errlng,
581
0
          "NPN-Wrong length: %d", length);
582
0
        *errtxt = errbuf;
583
0
        return false;
584
0
      }
585
0
      data = next_uint16(buf);
586
0
      if (data != nts_protocol_NTP) {
587
0
        snprintf(errbuf, errlng,
588
0
          "NPN-Bad data: %d", data);
589
0
        *errtxt = errbuf;
590
0
        return false;
591
0
      }
592
0
      break;
593
0
        case nts_algorithm_negotiation:
594
0
      if (length % sizeof(uint16_t) > 0) {
595
0
        snprintf(errbuf, errlng,
596
0
          "AN-Wrong length: %d", length);
597
0
        *errtxt = errbuf;
598
0
        return false;
599
0
      }
600
0
      for (int i=0; i<length; i+=sizeof(uint16_t)) {
601
0
        data = next_uint16(buf);
602
0
        if (0 == nts_get_key_length(data)) {
603
0
          if (0)  /* for debugging */
604
0
            msyslog(LOG_ERR, "NTSs: AN-Unsupported AEAN type: %d", data);
605
0
          continue;     /* ignore types we don't support */
606
0
        }
607
0
        if (*aead != NO_AEAD)
608
0
          continue;     /* already got one */
609
0
        *aead = data;   /* take this one */
610
0
      }
611
0
      break;
612
0
        case nts_end_of_message:
613
0
      if ((0 != length) || !critical) {
614
0
        snprintf(errbuf, errlng,
615
0
          "EOM-Wrong length or not Critical: %d, %d",
616
0
          length, critical);
617
0
        *errtxt = errbuf;
618
0
        return false;
619
0
      }
620
0
      if (0 != buf->left) {
621
0
        snprintf(errbuf, errlng,
622
0
          "EOM not at end: %d", buf->left);
623
0
        *errtxt = errbuf;
624
0
        return false;
625
0
      }
626
0
      return true;
627
0
        default:
628
0
      if (critical) {
629
        // This only logs the first one from a connection
630
0
        snprintf(errbuf, errlng,
631
0
        "Received strange type: T=%d, C=%d, L=%d",
632
0
        type, critical, length);
633
        // There is an error code for this
634
0
        return false;
635
0
      }
636
      // It might be interesting to log non-critical
637
      // but that needs rate limiting
638
0
      buf->next += length;
639
0
      buf->left -= length;
640
0
      break;
641
0
    } /* case */
642
0
  }   /* while */
643
644
  /* If we get here, we ran off the end without finding an EOM.
645
   * nts_ssl_read() should have complained, so this check
646
   * should never happen.
647
   */
648
0
  if (buf->left > 0) {
649
0
    *errtxt = "*** Leftovers";
650
0
    return false;
651
0
  }
652
653
0
  *errtxt = "*** Missing EOM";
654
0
  return false;
655
656
0
}
657
658
void nts_ke_setup_send(struct BufCtl_t *buf, int aead,
659
0
       uint8_t *c2s, uint8_t *s2c, int keylen) {
660
661
  /* 4.1.2 Next Protocol */
662
0
  ke_append_record_uint16(buf,
663
0
        NTS_CRITICAL+nts_next_protocol_negotiation, nts_protocol_NTP);
664
  /* 4.1.5 AEAD Algorithm List */
665
0
  ke_append_record_uint16(buf, nts_algorithm_negotiation, aead);
666
667
0
  if (extra_port)
668
0
          ke_append_record_uint16(buf, nts_port_negotiation, extra_port);
669
670
671
0
  for (int i=0; i<NTS_MAX_COOKIES; i++) {
672
0
    uint8_t cookie[NTS_MAX_COOKIELEN];
673
0
    int cookielen = nts_make_cookie(cookie, aead, c2s, s2c, keylen);
674
0
    ke_append_record_bytes(buf, nts_new_cookie, cookie, cookielen);
675
0
  }
676
677
  /* 4.1.1: End, Critical */
678
0
  ke_append_record_null(buf, NTS_CRITICAL+nts_end_of_message);
679
0
}
680
681
/* end */