Coverage Report

Created: 2026-04-12 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcoap/src/coap_openssl.c
Line
Count
Source
1
/*
2
 * coap_openssl.c -- Datagram Transport Layer Support for libcoap with openssl
3
 *
4
 * Copyright (C) 2017      Jean-Claude Michelou <jcm@spinetix.com>
5
 * Copyright (C) 2018-2026 Jon Shallow <supjps-libcoap@jpshallow.com>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * This file is part of the CoAP library libcoap. Please see README for terms
10
 * of use.
11
 */
12
13
/**
14
 * @file coap_openssl.c
15
 * @brief OpenSSL specific interface functions.
16
 */
17
18
#include "coap3/coap_libcoap_build.h"
19
20
#if COAP_WITH_LIBOPENSSL
21
22
/*
23
 * OpenSSL 1.1.0 has support for making decisions during receipt of
24
 * the Client Hello - the call back function is set up using
25
 * SSL_CTX_set_tlsext_servername_callback() which is called later in the
26
 * Client Hello processing - but called every Client Hello.
27
 * Certificates and Preshared Keys have to be set up in the SSL CTX before
28
 * SSL_accept() is called, making the code messy to decide whether this is a
29
 * PKI or PSK incoming request to handle things accordingly if both are
30
 * defined.  SNI has to create a new SSL CTX to handle different server names
31
 * with different crtificates.
32
 *
33
 * OpenSSL 1.1.1 introduces a new function SSL_CTX_set_client_hello_cb().
34
 * The call back is invoked early on in the Client Hello processing giving
35
 * the ability to easily use different Preshared Keys, Certificates etc.
36
 * Certificates do not have to be set up in the SSL CTX before SSL_accept is
37
 * called.
38
 * Later in the Client Hello code, the callback for
39
 * SSL_CTX_set_tlsext_servername_callback() is still called, but only if SNI
40
 * is being used by the client, so cannot be used for doing things the
41
 * OpenSSL 1.1.0 way.
42
 *
43
 * OpenSSL 1.1.1 supports TLS1.3.
44
 *
45
 * There is also support for OpenSSL 3.
46
 *
47
 * Consequently, this code has to have compile time options to include /
48
 * exclude code based on whether compiled against 1.1.0 or 1.1.1, as well as
49
 * have additional run time checks.
50
 *
51
 * It is possible to override the Ciphers, define the Algorithms or Groups,
52
 * and/or define the PKCS11 engine id to to use for the SSL negotiations at
53
 * compile time. This is done by the adding of the appropriate -D option to
54
 * the CPPFLAGS parameter that is used on the ./configure command line.
55
 * E.g.  ./configure CPPFLAGS="-DXX='\"YY\"' -DUU='\"VV\"'"
56
 * The parameter value is case-sensitive.
57
 *
58
 * The ciphers can be overridden with (example)
59
 *  -DCOAP_OPENSSL_CIPHERS='\"ECDHE-ECDSA-AES256-GCM-SHA384\"'
60
 *
61
 * The Algorithms can be defined by (example)
62
 *  -DCOAP_OPENSSL_SIGALGS='\"ed25519\"'
63
 *
64
 * The Groups (OpenSSL 1.1.1 or later) can be defined by (example)
65
 *  -DCOAP_OPENSSL_GROUPS='\"X25519\"'
66
 *
67
 * The PKCSLL engine ID can be defined by (example)
68
 + -DCOAP_OPENSSL_PKCS11_ENGINE_ID='\"pkcs11\"'
69
 *
70
 * The PSK security level can be defined by (example)
71
 + -DCOAP_OPENSSL_PSK_SECURITY_LEVEL=0
72
 *
73
 */
74
#include <openssl/ssl.h>
75
#include <openssl/engine.h>
76
#include <openssl/err.h>
77
#include <openssl/rand.h>
78
#include <openssl/hmac.h>
79
#include <openssl/x509v3.h>
80
81
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
82
#ifdef __GNUC__
83
/* Ignore OpenSSL 3.0 deprecated warnings for now */
84
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
85
#endif
86
#if defined(_WIN32)
87
#if !defined(__MINGW32__)
88
#pragma warning(disable : 4996)
89
#endif /* ! __MINGW32__ */
90
#endif /* _WIN32 */
91
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
92
93
#ifdef COAP_EPOLL_SUPPORT
94
# include <sys/epoll.h>
95
#endif /* COAP_EPOLL_SUPPORT */
96
97
#if OPENSSL_VERSION_NUMBER < 0x10100000L
98
#error Must be compiled against OpenSSL 1.1.0 or later
99
#endif
100
101
#ifdef _WIN32
102
#define strcasecmp _stricmp
103
#define strncasecmp _strnicmp
104
#endif
105
106
/* RFC6091/RFC7250 */
107
#ifndef TLSEXT_TYPE_client_certificate_type
108
0
#define TLSEXT_TYPE_client_certificate_type 19
109
#endif
110
#ifndef TLSEXT_TYPE_server_certificate_type
111
#define TLSEXT_TYPE_server_certificate_type 20
112
#endif
113
114
#ifndef COAP_OPENSSL_CIPHERS
115
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
116
0
#define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL"
117
#else /* OPENSSL_VERSION_NUMBER < 0x10101000L */
118
#define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL"
119
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
120
#endif /*COAP_OPENSSL_CIPHERS */
121
122
#ifndef COAP_OPENSSL_PSK_CIPHERS
123
0
#define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL"
124
#endif /*COAP_OPENSSL_PSK_CIPHERS */
125
126
#ifndef COAP_OPENSSL_PKCS11_ENGINE_ID
127
0
#define COAP_OPENSSL_PKCS11_ENGINE_ID "pkcs11"
128
#endif /* COAP_OPENSSL_PKCS11_ENGINE_ID */
129
130
/* This structure encapsulates the OpenSSL context object. */
131
typedef struct coap_dtls_context_t {
132
  SSL_CTX *ctx;
133
  SSL *ssl;        /* OpenSSL object for listening to connection requests */
134
  HMAC_CTX *cookie_hmac;
135
  BIO_METHOD *meth;
136
  BIO_ADDR *bio_addr;
137
} coap_dtls_context_t;
138
139
typedef struct coap_tls_context_t {
140
  SSL_CTX *ctx;
141
  BIO_METHOD *meth;
142
} coap_tls_context_t;
143
144
0
#define IS_PSK 0x1
145
0
#define IS_PKI 0x2
146
147
typedef struct sni_entry {
148
  char *sni;
149
#if OPENSSL_VERSION_NUMBER < 0x10101000L
150
  SSL_CTX *ctx;
151
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
152
  coap_dtls_key_t pki_key;
153
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
154
} sni_entry;
155
156
typedef struct psk_sni_entry {
157
  char *sni;
158
#if OPENSSL_VERSION_NUMBER < 0x10101000L
159
  SSL_CTX *ctx;
160
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
161
  coap_dtls_spsk_info_t psk_info;
162
} psk_sni_entry;
163
164
typedef struct coap_openssl_context_t {
165
  coap_dtls_context_t dtls;
166
#if !COAP_DISABLE_TCP
167
  coap_tls_context_t tls;
168
#endif /* !COAP_DISABLE_TCP */
169
  coap_dtls_pki_t setup_data;
170
  int psk_pki_enabled;
171
  size_t sni_count;
172
  sni_entry *sni_entry_list;
173
#if OPENSSL_VERSION_NUMBER < 0x10101000L
174
  size_t psk_sni_count;
175
  psk_sni_entry *psk_sni_entry_list;
176
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
177
} coap_openssl_context_t;
178
179
#if COAP_SERVER_SUPPORT
180
#if OPENSSL_VERSION_NUMBER < 0x10101000L
181
static int psk_tls_server_name_call_back(SSL *ssl, int *sd, void *arg);
182
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
183
static int psk_tls_client_hello_call_back(SSL *ssl, int *al, void *arg);
184
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
185
#endif /* COAP_SERVER_SUPPORT */
186
187
int
188
1
coap_dtls_is_supported(void) {
189
1
  if (SSLeay() < 0x10100000L) {
190
0
    coap_log_warn("OpenSSL version 1.1.0 or later is required\n");
191
0
    return 0;
192
0
  }
193
1
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
194
  /*
195
   * For 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
196
   * which is not in 1.1.0 instead of SSL_CTX_set_tlsext_servername_callback()
197
   *
198
   * However, there could be a runtime undefined external reference error
199
   * as SSL_CTX_set_client_hello_cb() is not there in 1.1.0.
200
   */
201
1
  if (SSLeay() < 0x10101000L) {
202
0
    coap_log_warn("OpenSSL version 1.1.1 or later is required\n");
203
0
    return 0;
204
0
  }
205
1
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
206
1
  return 1;
207
1
}
208
209
int
210
2
coap_tls_is_supported(void) {
211
2
#if !COAP_DISABLE_TCP
212
2
  if (SSLeay() < 0x10100000L) {
213
0
    coap_log_warn("OpenSSL version 1.1.0 or later is required\n");
214
0
    return 0;
215
0
  }
216
2
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
217
2
  if (SSLeay() < 0x10101000L) {
218
0
    coap_log_warn("OpenSSL version 1.1.1 or later is required\n");
219
0
    return 0;
220
0
  }
221
2
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
222
2
  return 1;
223
#else /* COAP_DISABLE_TCP */
224
  return 0;
225
#endif /* COAP_DISABLE_TCP */
226
2
}
227
228
/*
229
 * return 0 failed
230
 *        1 passed
231
 */
232
int
233
0
coap_dtls_psk_is_supported(void) {
234
0
  return 1;
235
0
}
236
237
/*
238
 * return 0 failed
239
 *        1 passed
240
 */
241
int
242
0
coap_dtls_pki_is_supported(void) {
243
0
  return 1;
244
0
}
245
246
/*
247
 * return 0 failed
248
 *        1 passed
249
 */
250
int
251
0
coap_dtls_pkcs11_is_supported(void) {
252
0
  return 1;
253
0
}
254
255
/*
256
 * return 0 failed
257
 *        1 passed
258
 */
259
int
260
0
coap_dtls_rpk_is_supported(void) {
261
0
  return 0;
262
0
}
263
264
/*
265
 * return 0 failed
266
 *        1 passed
267
 */
268
int
269
0
coap_dtls_cid_is_supported(void) {
270
0
  return 0;
271
0
}
272
273
#if COAP_CLIENT_SUPPORT
274
int
275
0
coap_dtls_set_cid_tuple_change(coap_context_t *c_context, uint8_t every) {
276
0
  (void)c_context;
277
0
  (void)every;
278
0
  return 0;
279
0
}
280
#endif /* COAP_CLIENT_SUPPORT */
281
282
coap_tls_version_t *
283
0
coap_get_tls_library_version(void) {
284
0
  static coap_tls_version_t version;
285
0
  version.version = SSLeay();
286
0
  version.built_version = OPENSSL_VERSION_NUMBER;
287
0
  version.type = COAP_TLS_LIBRARY_OPENSSL;
288
0
  return &version;
289
0
}
290
291
static ENGINE *pkcs11_engine = NULL;
292
static ENGINE *defined_engine = NULL;
293
294
void
295
0
coap_dtls_startup(void) {
296
0
  SSL_load_error_strings();
297
0
  SSL_library_init();
298
0
  ENGINE_load_dynamic();
299
0
}
300
301
void
302
0
coap_dtls_shutdown(void) {
303
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
304
0
  if (pkcs11_engine) {
305
    /* Release the functional reference from ENGINE_init() */
306
0
    ENGINE_finish(pkcs11_engine);
307
0
    pkcs11_engine = NULL;
308
0
  }
309
0
  if (defined_engine) {
310
    /* Release the functional reference from ENGINE_init() */
311
0
    ENGINE_finish(defined_engine);
312
0
    defined_engine = NULL;
313
0
  }
314
#else /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
315
  pkcs11_engine = NULL;
316
  defined_engine = NULL;
317
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
318
0
  ERR_free_strings();
319
0
  coap_dtls_set_log_level(COAP_LOG_EMERG);
320
0
}
321
322
void
323
0
coap_dtls_thread_shutdown(void) {
324
0
}
325
326
void *
327
coap_dtls_get_tls(const coap_session_t *c_session,
328
0
                  coap_tls_library_t *tls_lib) {
329
0
  if (tls_lib)
330
0
    *tls_lib = COAP_TLS_LIBRARY_OPENSSL;
331
0
  if (c_session) {
332
0
    return c_session->tls;
333
0
  }
334
0
  return NULL;
335
0
}
336
337
static int
338
get_split_conf_entry(const uint8_t **start, size_t size, const char *get_keyword,
339
0
                     coap_str_const_t **p1, coap_str_const_t **p2) {
340
0
  const uint8_t *begin = *start;
341
0
  const uint8_t *end;
342
0
  const uint8_t *kend;
343
0
  const uint8_t *split;
344
345
0
  *p1 = NULL;
346
0
  *p2 = NULL;
347
348
0
retry:
349
0
  kend = end = memchr(begin, '\n', size);
350
0
  if (end == NULL)
351
0
    return 0;
352
353
  /* Track beginning of next line */
354
0
  *start = end + 1;
355
0
  if (end > begin && end[-1] == '\r')
356
0
    end--;
357
358
0
  if (begin[0] == '#' || (end - begin) == 0) {
359
    /* Skip comment / blank line */
360
0
    size -= kend - begin + 1;
361
0
    begin = *start;
362
0
    goto retry;
363
0
  }
364
365
  /* Get in the keyword */
366
0
  split = memchr(begin, ':', end - begin);
367
0
  if (split == NULL)
368
0
    goto bad_entry;
369
370
0
  if ((size_t)(split - begin) != strlen(get_keyword)) {
371
0
    size -= kend - begin + 1;
372
0
    begin = *start;
373
0
    goto retry;
374
0
  }
375
0
  if (memcmp(begin, get_keyword, split - begin)) {
376
0
    size -= kend - begin + 1;
377
0
    begin = *start;
378
0
    goto retry;
379
0
  }
380
  /* Found entry we are looking for */
381
0
  begin = split + 1;
382
383
  /* parameter 1 is mandatory */
384
0
  if ((end - begin) == 0)
385
0
    goto bad_entry;
386
  /* Get in paramater #1 */
387
0
  split = memchr(begin, ':', end - begin);
388
0
  if (split == NULL) {
389
    /* Single entry - no parameter #2 */
390
0
    *p1 = coap_new_str_const(begin, end - begin);
391
0
    if (!(*p1)) {
392
0
      goto bad_entry;
393
0
    }
394
0
  } else {
395
0
    *p1 = coap_new_str_const(begin, split - begin);
396
0
    if (!(*p1)) {
397
0
      goto bad_entry;
398
0
    }
399
0
    if ((end - split) > 0) {
400
0
      *p2 = coap_new_str_const(split + 1, end - split - 1);
401
0
      if (!(*p2)) {
402
0
        goto bad_entry;
403
0
      }
404
0
    }
405
0
  }
406
407
0
  return 1;
408
409
0
bad_entry:
410
0
  coap_delete_str_const(*p1);
411
0
  coap_delete_str_const(*p2);
412
0
  return 0;
413
0
}
414
415
/*
416
 * Formating of OpenSSL Engine configuration is:-
417
 * (Must be in this order)
418
 *
419
 * engine:XXX
420
 * pre-cmd:XXX:YYY
421
 *   ....
422
 * pre-cmd:XXX:YYY
423
 * post-cmd:XXX:YYY
424
 *   ....
425
 * post-cmd:XXX:YYY
426
 * enable-methods:unsigned-int
427
 *   OR'd set of ENGINE_METHOD_* or ENGINE_METHOD_ALL
428
 *
429
 * pre-cmd and post-cmd are optional
430
 * YYY does not have to be defined for some pre-cmd or post-cmd
431
 */
432
int
433
0
coap_tls_engine_configure(coap_str_const_t *conf_mem) {
434
0
  const uint8_t *start;
435
0
  const uint8_t *end;
436
0
  coap_str_const_t *p1 = NULL;
437
0
  coap_str_const_t *p2 = NULL;
438
0
  coap_str_const_t *engine_id = NULL;
439
0
  unsigned int defaults = 0;
440
0
  int done_engine_id = 0;
441
0
  int done_engine_init = 0;
442
443
0
  if (!conf_mem)
444
0
    return 0;
445
446
0
  start = conf_mem->s;
447
0
  end = start + conf_mem->length;
448
449
0
  if (defined_engine) {
450
0
    coap_log_warn("coap_tls_engine_configure: Freeing off previous engine definition\n");
451
0
    ENGINE_finish(defined_engine);
452
0
    defined_engine = NULL;
453
0
  }
454
455
  /* Set up engine */
456
0
  if (!get_split_conf_entry(&start, end - start, "engine", &engine_id, &p2)) {
457
0
    coap_log_warn("coap_tls_engine_configure: engine not defined\n");
458
0
    return 0;
459
0
  }
460
0
  defined_engine = ENGINE_by_id((const char *)engine_id->s);
461
0
  if (!defined_engine) {
462
0
    coap_log_warn("coap_tls_engine_configure: engine '%s' not known\n", engine_id->s);
463
0
    goto fail_cleanup;
464
0
  } else {
465
0
    done_engine_id = 1;
466
0
    coap_dtls_log(COAP_LOG_DEBUG, "coap_tls_engine_configure: engine '%s' started\n", engine_id->s);
467
0
  }
468
0
  coap_delete_str_const(p2);
469
470
0
  start = conf_mem->s;
471
  /* process all the pre-cmd defined */
472
0
  while (get_split_conf_entry(&start, end - start, "pre-cmd", &p1, &p2)) {
473
0
    if (!ENGINE_ctrl_cmd_string(defined_engine, (const char *)p1->s, p2 ? (const char *)p2->s : NULL,
474
0
                                0)) {
475
0
      coap_log_warn("coap_tls_engine_configure: engine %s pre-cmd '%s:%s' failed\n",
476
0
                    (const char *)engine_id->s,
477
0
                    (const char *)p1->s, p2 ? (const char *)p2->s : "(NULL)");
478
0
      goto fail_cleanup;
479
0
    } else {
480
0
      coap_dtls_log(COAP_LOG_DEBUG, "coap_tls_engine_configure: engine '%s' pre-cmd '%s:%s' success\n",
481
0
                    engine_id->s, p1->s, p2 ? (const char *)p2->s : "(NULL)");
482
0
    }
483
0
    coap_delete_str_const(p1);
484
0
    coap_delete_str_const(p2);
485
0
  }
486
487
0
  p1 = NULL;
488
0
  p2 = NULL;
489
  /* Start up the engine */
490
0
  if (!ENGINE_init(defined_engine)) {
491
0
    coap_log_warn("coap_tls_engine_configure: %s failed initialization\n", (const char *)engine_id->s);
492
0
    goto fail_cleanup;
493
0
  } else {
494
0
    done_engine_init = 1;
495
0
    coap_dtls_log(COAP_LOG_DEBUG, "coap_tls_engine_configure: %s initialized\n",
496
0
                  (const char *)engine_id->s);
497
0
  }
498
499
0
  start = conf_mem->s;
500
  /* process all the post-cmd defined */
501
0
  while (get_split_conf_entry(&start, end - start, "post-cmd", &p1, &p2)) {
502
0
    if (!ENGINE_ctrl_cmd_string(defined_engine, (const char *)p1->s, p2 ? (const char *)p2->s : NULL,
503
0
                                0)) {
504
0
      coap_log_warn("coap_tls_engine_configure: %s post-cmd '%s:%s' failed\n", (const char *)engine_id->s,
505
0
                    (const char *)p1->s, p2 ? (const char *)p2->s : "(NULL)");
506
0
      goto fail_cleanup;
507
0
    } else {
508
0
      coap_dtls_log(COAP_LOG_DEBUG, "coap_tls_engine_configure: %s post-cmd '%s:%s' success\n",
509
0
                    (const char *)engine_id->s,
510
0
                    (const char *)p1->s, p2 ? (const char *)p2->s : "(NULL)");
511
0
    }
512
0
    coap_delete_str_const(p1);
513
0
    coap_delete_str_const(p2);
514
0
  }
515
516
0
  start = conf_mem->s;
517
  /* See what we should be setting as the methods */
518
0
  if (!get_split_conf_entry(&start, end - start, "enable-methods", &p1, &p2)) {
519
0
    coap_log_warn("coap_tls_engine_configure: enable-methods not found\n");
520
0
    goto fail_cleanup;
521
0
  }
522
0
  defaults = strtoul((const char *)p1->s, NULL, 0);
523
0
  if (!ENGINE_set_default(defined_engine, defaults)) {
524
0
    coap_log_warn("coap_tls_engine_configure: enable-methods 0x%x invalid\n", defaults);
525
0
    goto fail_cleanup;
526
0
  } else {
527
0
    coap_dtls_log(COAP_LOG_DEBUG, "coap_tls_engine_configure: enable-methods 0x%x successful\n",
528
0
                  defaults);
529
0
  }
530
0
  coap_delete_str_const(engine_id);
531
0
  coap_delete_str_const(p1);
532
0
  coap_delete_str_const(p2);
533
  /* Success */
534
535
0
  return 1;
536
537
0
fail_cleanup:
538
0
  if (done_engine_id)
539
0
    ENGINE_free(defined_engine);
540
0
  if (done_engine_init)
541
0
    ENGINE_finish(defined_engine);
542
0
  defined_engine = NULL;
543
0
  coap_delete_str_const(engine_id);
544
0
  coap_delete_str_const(p1);
545
0
  coap_delete_str_const(p2);
546
0
  return 0;
547
0
}
548
549
int
550
0
coap_tls_engine_remove(void) {
551
0
  if (defined_engine) {
552
0
    ENGINE_finish(defined_engine);
553
0
    defined_engine = NULL;
554
0
    return 1;
555
0
  }
556
0
  return 0;
557
0
}
558
559
/*
560
 * Logging levels use the standard CoAP logging levels
561
 */
562
static coap_log_t dtls_log_level = COAP_LOG_EMERG;
563
564
void
565
0
coap_dtls_set_log_level(coap_log_t level) {
566
0
  dtls_log_level = level;
567
0
}
568
569
coap_log_t
570
0
coap_dtls_get_log_level(void) {
571
0
  return dtls_log_level;
572
0
}
573
574
typedef struct coap_ssl_data {
575
  coap_session_t *session;
576
  const void *pdu;
577
  unsigned pdu_len;
578
  unsigned peekmode;
579
  coap_tick_t timeout;
580
} coap_ssl_data;
581
582
static int
583
0
coap_dgram_create(BIO *a) {
584
0
  coap_ssl_data *data = NULL;
585
0
  data = malloc(sizeof(coap_ssl_data));
586
0
  if (data == NULL)
587
0
    return 0;
588
0
  BIO_set_init(a, 1);
589
0
  BIO_set_data(a, data);
590
0
  memset(data, 0x00, sizeof(coap_ssl_data));
591
0
  return 1;
592
0
}
593
594
static int
595
0
coap_dgram_destroy(BIO *a) {
596
0
  coap_ssl_data *data;
597
0
  if (a == NULL)
598
0
    return 0;
599
0
  data = (coap_ssl_data *)BIO_get_data(a);
600
0
  BIO_set_data(a, NULL);
601
0
  if (data != NULL)
602
0
    free(data);
603
0
  return 1;
604
0
}
605
606
static int
607
0
coap_dgram_read(BIO *a, char *out, int outl) {
608
0
  int ret = 0;
609
0
  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
610
611
0
  if (out != NULL) {
612
0
    if (data != NULL && data->pdu_len > 0) {
613
0
      if (outl < (int)data->pdu_len) {
614
0
        memcpy(out, data->pdu, outl);
615
0
        ret = outl;
616
0
      } else {
617
0
        memcpy(out, data->pdu, data->pdu_len);
618
0
        ret = (int)data->pdu_len;
619
0
      }
620
0
      if (!data->peekmode) {
621
0
        data->pdu_len = 0;
622
0
        data->pdu = NULL;
623
0
      }
624
0
    } else {
625
0
      ret = -1;
626
0
    }
627
0
    BIO_clear_retry_flags(a);
628
0
    if (ret < 0)
629
0
      BIO_set_retry_read(a);
630
0
  }
631
0
  return ret;
632
0
}
633
634
static int
635
0
coap_dgram_write(BIO *a, const char *in, int inl) {
636
0
  int ret = 0;
637
0
  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
638
639
0
  if (data && data->session) {
640
0
    if (!coap_netif_available(data->session)
641
0
#if COAP_SERVER_SUPPORT
642
0
        && data->session->endpoint == NULL
643
0
#endif /* COAP_SERVER_SUPPORT */
644
0
       ) {
645
      /* socket was closed on client due to error */
646
0
      BIO_clear_retry_flags(a);
647
0
      errno = ECONNRESET;
648
0
      return -1;
649
0
    }
650
0
    ret = (int)data->session->sock.lfunc[COAP_LAYER_TLS].l_write(data->session,
651
0
          (const uint8_t *)in,
652
0
          inl);
653
0
    BIO_clear_retry_flags(a);
654
0
    if (ret <= 0) {
655
0
      if (ret < 0 && (errno == ENOTCONN || errno == ECONNREFUSED))
656
0
        data->session->dtls_event = COAP_EVENT_DTLS_ERROR;
657
0
      BIO_set_retry_write(a);
658
0
    }
659
0
  } else {
660
0
    BIO_clear_retry_flags(a);
661
0
    ret = -1;
662
0
  }
663
0
  return ret;
664
0
}
665
666
static int
667
0
coap_dgram_puts(BIO *a, const char *pstr) {
668
0
  return coap_dgram_write(a, pstr, (int)strlen(pstr));
669
0
}
670
671
static long
672
0
coap_dgram_ctrl(BIO *a, int cmd, long num, void *ptr) {
673
0
  long ret = 1;
674
0
  coap_ssl_data *data = BIO_get_data(a);
675
676
0
  (void)ptr;
677
678
0
  switch (cmd) {
679
0
  case BIO_CTRL_GET_CLOSE:
680
0
    ret = BIO_get_shutdown(a);
681
0
    break;
682
0
  case BIO_CTRL_SET_CLOSE:
683
0
    BIO_set_shutdown(a, (int)num);
684
0
    break;
685
0
  case BIO_CTRL_DGRAM_SET_PEEK_MODE:
686
0
    if (data)
687
0
      data->peekmode = (unsigned)num;
688
0
    else
689
0
      ret = 0;
690
0
    break;
691
0
  case BIO_CTRL_DGRAM_CONNECT:
692
0
  case BIO_C_SET_FD:
693
0
  case BIO_C_GET_FD:
694
0
  case BIO_CTRL_DGRAM_SET_DONT_FRAG:
695
0
  case BIO_CTRL_DGRAM_GET_MTU:
696
0
  case BIO_CTRL_DGRAM_SET_MTU:
697
0
  case BIO_CTRL_DGRAM_QUERY_MTU:
698
0
  case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
699
0
    ret = -1;
700
0
    break;
701
0
  case BIO_CTRL_DUP:
702
0
  case BIO_CTRL_FLUSH:
703
0
  case BIO_CTRL_DGRAM_MTU_DISCOVER:
704
0
  case BIO_CTRL_DGRAM_SET_CONNECTED:
705
0
    break;
706
0
  case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
707
0
    if (data)
708
0
      data->timeout = coap_ticks_from_rt_us((uint64_t)((struct timeval *)ptr)->tv_sec * 1000000 +
709
0
                                            ((struct timeval *)ptr)->tv_usec);
710
0
    else
711
0
      ret = 0;
712
0
    break;
713
0
  case BIO_CTRL_RESET:
714
0
  case BIO_C_FILE_SEEK:
715
0
  case BIO_C_FILE_TELL:
716
0
  case BIO_CTRL_INFO:
717
0
  case BIO_CTRL_PENDING:
718
0
  case BIO_CTRL_WPENDING:
719
0
  case BIO_CTRL_DGRAM_GET_PEER:
720
0
  case BIO_CTRL_DGRAM_SET_PEER:
721
0
  case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
722
0
  case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
723
0
  case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
724
0
  case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
725
0
  case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
726
0
  case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
727
0
  case BIO_CTRL_DGRAM_MTU_EXCEEDED:
728
0
  case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
729
0
  default:
730
0
    ret = 0;
731
0
    break;
732
0
  }
733
0
  return ret;
734
0
}
735
736
static int
737
coap_dtls_generate_cookie(SSL *ssl,
738
                          unsigned char *cookie,
739
0
                          unsigned int *cookie_len) {
740
0
  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
741
0
  coap_dtls_context_t *dtls = ctx ? (coap_dtls_context_t *)SSL_CTX_get_app_data(ctx) : NULL;
742
0
  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
743
744
0
  if (dtls && data) {
745
0
    int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
746
0
    r &= HMAC_Update(dtls->cookie_hmac,
747
0
                     (const uint8_t *)&data->session->addr_info.local.addr,
748
0
                     (size_t)data->session->addr_info.local.size);
749
0
    r &= HMAC_Update(dtls->cookie_hmac,
750
0
                     (const uint8_t *)&data->session->addr_info.remote.addr,
751
0
                     (size_t)data->session->addr_info.remote.size);
752
0
    r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
753
0
    return r;
754
0
  }
755
0
  return 0;
756
0
}
757
758
static int
759
coap_dtls_verify_cookie(SSL *ssl,
760
                        const uint8_t *cookie,
761
0
                        unsigned int cookie_len) {
762
0
  uint8_t hmac[32];
763
0
  unsigned len = 32;
764
0
  if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
765
0
      cookie_len == len && memcmp(cookie, hmac, len) == 0)
766
0
    return 1;
767
0
  else
768
0
    return 0;
769
0
}
770
771
#if COAP_CLIENT_SUPPORT
772
static unsigned int
773
coap_dtls_psk_client_callback(SSL *ssl,
774
                              const char *hint,
775
                              char *identity,
776
                              unsigned int max_identity_len,
777
                              unsigned char *psk,
778
0
                              unsigned int max_psk_len) {
779
0
  coap_session_t *c_session;
780
0
  coap_openssl_context_t *o_context;
781
0
  coap_dtls_cpsk_t *setup_data;
782
0
  coap_bin_const_t temp;
783
0
  const coap_dtls_cpsk_info_t *cpsk_info;
784
0
  const coap_bin_const_t *psk_key;
785
0
  const coap_bin_const_t *psk_identity;
786
787
0
  c_session = (coap_session_t *)SSL_get_app_data(ssl);
788
0
  if (c_session == NULL || c_session->context == NULL)
789
0
    return 0;
790
0
  o_context = (coap_openssl_context_t *)c_session->context->dtls_context;
791
0
  if (o_context == NULL)
792
0
    return 0;
793
0
  setup_data = &c_session->cpsk_setup_data;
794
795
0
  temp.s = hint ? (const uint8_t *)hint : (const uint8_t *)"";
796
0
  temp.length = strlen((const char *)temp.s);
797
0
  coap_session_refresh_psk_hint(c_session, &temp);
798
799
0
  coap_log_debug("got psk_identity_hint: '%.*s'\n", (int)temp.length,
800
0
                 (const char *)temp.s);
801
802
0
  if (setup_data->validate_ih_call_back) {
803
0
    coap_str_const_t lhint;
804
805
0
    lhint.s = temp.s;
806
0
    lhint.length = temp.length;
807
0
    coap_lock_callback_ret(cpsk_info,
808
0
                           setup_data->validate_ih_call_back(&lhint,
809
0
                                                             c_session,
810
0
                                                             setup_data->ih_call_back_arg));
811
812
0
    if (cpsk_info == NULL)
813
0
      return 0;
814
815
0
    coap_session_refresh_psk_identity(c_session, &cpsk_info->identity);
816
0
    coap_session_refresh_psk_key(c_session, &cpsk_info->key);
817
0
    psk_identity = &cpsk_info->identity;
818
0
    psk_key = &cpsk_info->key;
819
0
  } else {
820
0
    psk_identity = coap_get_session_client_psk_identity(c_session);
821
0
    psk_key = coap_get_session_client_psk_key(c_session);
822
0
  }
823
824
0
  if (psk_identity == NULL || psk_key == NULL) {
825
0
    coap_log_warn("no PSK available\n");
826
0
    return 0;
827
0
  }
828
829
  /* identity has to be NULL terminated */
830
0
  if (!max_identity_len)
831
0
    return 0;
832
0
  max_identity_len--;
833
0
  if (psk_identity->length > max_identity_len) {
834
0
    coap_log_warn("psk_identity too large, truncated to %d bytes\n",
835
0
                  max_identity_len);
836
0
  } else {
837
    /* Reduce to match */
838
0
    max_identity_len = (unsigned int)psk_identity->length;
839
0
  }
840
0
  memcpy(identity, psk_identity->s, max_identity_len);
841
0
  identity[max_identity_len] = '\000';
842
843
0
  if (psk_key->length > max_psk_len) {
844
0
    coap_log_warn("psk_key too large, truncated to %d bytes\n",
845
0
                  max_psk_len);
846
0
  } else {
847
    /* Reduce to match */
848
0
    max_psk_len = (unsigned int)psk_key->length;
849
0
  }
850
0
  memcpy(psk, psk_key->s, max_psk_len);
851
0
  return max_psk_len;
852
0
}
853
#endif /* COAP_CLIENT_SUPPORT */
854
855
#if COAP_SERVER_SUPPORT
856
static unsigned int
857
coap_dtls_psk_server_callback(
858
    SSL *ssl,
859
    const char *identity,
860
    unsigned char *psk,
861
    unsigned int max_psk_len
862
0
) {
863
0
  coap_session_t *c_session;
864
0
  coap_dtls_spsk_t *setup_data;
865
0
  coap_bin_const_t lidentity;
866
0
  const coap_bin_const_t *psk_key;
867
868
0
  c_session = (coap_session_t *)SSL_get_app_data(ssl);
869
0
  if (c_session == NULL || c_session->context == NULL)
870
0
    return 0;
871
872
0
  setup_data = &c_session->context->spsk_setup_data;
873
874
  /* Track the Identity being used */
875
0
  lidentity.s = identity ? (const uint8_t *)identity : (const uint8_t *)"";
876
0
  lidentity.length = strlen((const char *)lidentity.s);
877
0
  coap_session_refresh_psk_identity(c_session, &lidentity);
878
879
0
  coap_log_debug("got psk_identity: '%.*s'\n",
880
0
                 (int)lidentity.length, (const char *)lidentity.s);
881
882
0
  if (setup_data->validate_id_call_back) {
883
0
    psk_key = setup_data->validate_id_call_back(&lidentity,
884
0
                                                c_session,
885
0
                                                setup_data->id_call_back_arg);
886
887
0
    coap_session_refresh_psk_key(c_session, psk_key);
888
0
  } else {
889
0
    psk_key = coap_get_session_server_psk_key(c_session);
890
0
  }
891
892
0
  if (psk_key == NULL)
893
0
    return 0;
894
895
0
  if (psk_key->length > max_psk_len) {
896
0
    coap_log_warn("psk_key too large, truncated to %d bytes\n",
897
0
                  max_psk_len);
898
0
  } else {
899
    /* Reduce to match */
900
0
    max_psk_len = (unsigned int)psk_key->length;
901
0
  }
902
0
  memcpy(psk, psk_key->s, max_psk_len);
903
0
  return max_psk_len;
904
0
}
905
#endif /* COAP_SERVER_SUPPORT */
906
907
static const char *
908
0
ssl_function_definition(unsigned long e) {
909
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
910
  (void)e;
911
  return "";
912
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
913
0
  static char buff[80];
914
915
0
  snprintf(buff, sizeof(buff), " at %s:%s",
916
0
           ERR_lib_error_string(e), ERR_func_error_string(e));
917
0
  return buff;
918
0
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
919
0
}
920
921
static void
922
0
coap_dtls_info_callback(const SSL *ssl, int where, int ret) {
923
0
  coap_session_t *session = (coap_session_t *)SSL_get_app_data(ssl);
924
0
  const char *pstr;
925
0
  int w = where &~SSL_ST_MASK;
926
927
0
  if (!session) {
928
0
    coap_dtls_log(COAP_LOG_WARN,
929
0
                  "coap_dtls_info_callback: session not determined, where 0x%0x and ret 0x%0x\n", where, ret);
930
0
    return;
931
0
  }
932
0
  if (w & SSL_ST_CONNECT)
933
0
    pstr = "SSL_connect";
934
0
  else if (w & SSL_ST_ACCEPT)
935
0
    pstr = "SSL_accept";
936
0
  else
937
0
    pstr = "undefined";
938
939
0
  if (where & SSL_CB_LOOP) {
940
0
    coap_dtls_log(COAP_LOG_DEBUG, "*  %s: %s:%s\n",
941
0
                  coap_session_str(session), pstr, SSL_state_string_long(ssl));
942
0
  } else if (where & SSL_CB_ALERT) {
943
0
    coap_log_t log_level = COAP_LOG_INFO;
944
0
    pstr = (where & SSL_CB_READ) ? "read" : "write";
945
0
    if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
946
0
      session->dtls_event = COAP_EVENT_DTLS_ERROR;
947
0
      if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
948
0
        log_level = COAP_LOG_WARN;
949
0
    }
950
    /* Need to let CoAP logging know why this session is dying */
951
0
    coap_log(log_level, "*  %s: SSL3 alert %s:%s:%s\n",
952
0
             coap_session_str(session),
953
0
             pstr,
954
0
             SSL_alert_type_string_long(ret),
955
0
             SSL_alert_desc_string_long(ret));
956
0
  } else if (where & SSL_CB_EXIT) {
957
0
    if (ret == 0) {
958
0
      if (dtls_log_level >= COAP_LOG_WARN) {
959
0
        unsigned long e;
960
0
        coap_dtls_log(COAP_LOG_WARN, "*  %s: %s:failed in %s\n",
961
0
                      coap_session_str(session), pstr, SSL_state_string_long(ssl));
962
0
        while ((e = ERR_get_error()))
963
0
          coap_dtls_log(COAP_LOG_WARN, "*  %s: %s%s\n",
964
0
                        coap_session_str(session), ERR_reason_error_string(e),
965
0
                        ssl_function_definition(e));
966
0
      }
967
0
    } else if (ret < 0) {
968
0
      if (dtls_log_level >= COAP_LOG_WARN) {
969
0
        int err = SSL_get_error(ssl, ret);
970
0
        if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE &&
971
0
            err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT &&
972
0
            err != SSL_ERROR_WANT_X509_LOOKUP) {
973
0
          long e;
974
0
          coap_dtls_log(COAP_LOG_WARN, "*  %s: %s:error in %s\n",
975
0
                        coap_session_str(session), pstr, SSL_state_string_long(ssl));
976
0
          while ((e = ERR_get_error()))
977
0
            coap_dtls_log(COAP_LOG_WARN, "*  %s: %s%s\n",
978
0
                          coap_session_str(session), ERR_reason_error_string(e),
979
0
                          ssl_function_definition(e));
980
0
        }
981
0
      }
982
0
    }
983
0
  }
984
985
0
  if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
986
0
    session->dtls_event = COAP_EVENT_DTLS_RENEGOTIATE;
987
0
}
988
989
#if !COAP_DISABLE_TCP
990
static int
991
0
coap_sock_create(BIO *a) {
992
0
  BIO_set_init(a, 1);
993
0
  return 1;
994
0
}
995
996
static int
997
0
coap_sock_destroy(BIO *a) {
998
0
  (void)a;
999
0
  return 1;
1000
0
}
1001
1002
/*
1003
 * strm
1004
 * return +ve data amount
1005
 *        0   no more
1006
 *        -1  error
1007
 */
1008
static int
1009
0
coap_sock_read(BIO *a, char *out, int outl) {
1010
0
  int ret = 0;
1011
0
  coap_session_t *session = (coap_session_t *)BIO_get_data(a);
1012
1013
0
  if (session && out != NULL) {
1014
0
    ret =(int)session->sock.lfunc[COAP_LAYER_TLS].l_read(session, (uint8_t *)out,
1015
0
                                                         outl);
1016
    /* Translate layer returns into what OpenSSL expects */
1017
0
    if (ret == 0) {
1018
0
      BIO_set_retry_read(a);
1019
0
      ret = -1;
1020
0
    } else {
1021
0
      BIO_clear_retry_flags(a);
1022
0
    }
1023
0
  }
1024
0
  return ret;
1025
0
}
1026
1027
/*
1028
 * strm
1029
 * return +ve data amount
1030
 *        0   no more
1031
 *        -1  error (error in errno)
1032
 */
1033
static int
1034
0
coap_sock_write(BIO *a, const char *in, int inl) {
1035
0
  int ret = 0;
1036
0
  coap_session_t *session = (coap_session_t *)BIO_get_data(a);
1037
1038
0
  if (!session) {
1039
0
    errno = ENOMEM;
1040
0
    return -1;
1041
0
  } else {
1042
0
    ret = (int)session->sock.lfunc[COAP_LAYER_TLS].l_write(session,
1043
0
                                                           (const uint8_t *)in,
1044
0
                                                           inl);
1045
0
  }
1046
  /* Translate layer what returns into what OpenSSL expects */
1047
0
  BIO_clear_retry_flags(a);
1048
0
  if (ret == 0) {
1049
0
    BIO_set_retry_read(a);
1050
0
    ret = -1;
1051
0
  } else {
1052
0
    BIO_clear_retry_flags(a);
1053
0
    if (ret == -1) {
1054
0
      if ((session->state == COAP_SESSION_STATE_CSM ||
1055
0
           session->state == COAP_SESSION_STATE_HANDSHAKE) &&
1056
0
          (errno == EPIPE || errno == ECONNRESET)) {
1057
        /*
1058
         * Need to handle a TCP timing window where an agent continues with
1059
         * the sending of the next handshake or a CSM.
1060
         * However, the peer does not like a certificate and so sends a
1061
         * fatal alert and closes the TCP session.
1062
         * The sending of the next handshake or CSM may get terminated because
1063
         * of the closed TCP session, but there is still an outstanding alert
1064
         * to be read in and reported on.
1065
         * In this case, pretend that sending the info was fine so that the
1066
         * alert can be read (which effectively is what happens with DTLS).
1067
         */
1068
0
        ret = inl;
1069
0
      }
1070
0
    }
1071
0
  }
1072
0
  return ret;
1073
0
}
1074
1075
static int
1076
0
coap_sock_puts(BIO *a, const char *pstr) {
1077
0
  return coap_sock_write(a, pstr, (int)strlen(pstr));
1078
0
}
1079
1080
static long
1081
0
coap_sock_ctrl(BIO *a, int cmd, long num, void *ptr) {
1082
0
  int r = 1;
1083
0
  (void)a;
1084
0
  (void)ptr;
1085
0
  (void)num;
1086
1087
0
  switch (cmd) {
1088
0
  case BIO_C_SET_FD:
1089
0
  case BIO_C_GET_FD:
1090
0
    r = -1;
1091
0
    break;
1092
0
  case BIO_CTRL_SET_CLOSE:
1093
0
  case BIO_CTRL_DUP:
1094
0
  case BIO_CTRL_FLUSH:
1095
0
    r = 1;
1096
0
    break;
1097
0
  default:
1098
0
  case BIO_CTRL_GET_CLOSE:
1099
0
    r = 0;
1100
0
    break;
1101
0
  }
1102
0
  return r;
1103
0
}
1104
#endif /* !COAP_DISABLE_TCP */
1105
1106
static void
1107
0
coap_set_user_prefs(SSL_CTX *ctx) {
1108
0
  SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1109
1110
#ifdef COAP_OPENSSL_SIGALGS
1111
  SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
1112
  SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
1113
#endif
1114
1115
#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS)
1116
  SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
1117
#endif
1118
0
}
1119
1120
#if COAP_DTLS_RETRANSMIT_MS != 1000
1121
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
1122
static unsigned int
1123
timer_cb(SSL *s, unsigned int timer_us) {
1124
  (void)s;
1125
  if (timer_us == 0)
1126
    return COAP_DTLS_RETRANSMIT_MS * 1000;
1127
  else
1128
    return 2 * timer_us;
1129
}
1130
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1131
#endif /* COAP_DTLS_RETRANSMIT_MS != 1000 */
1132
1133
void *
1134
0
coap_dtls_new_context(coap_context_t *coap_context) {
1135
0
  coap_openssl_context_t *context;
1136
0
  (void)coap_context;
1137
1138
0
  context = (coap_openssl_context_t *)coap_malloc_type(COAP_STRING, sizeof(coap_openssl_context_t));
1139
0
  if (context) {
1140
0
    uint8_t cookie_secret[32];
1141
1142
0
    memset(context, 0, sizeof(coap_openssl_context_t));
1143
1144
    /* Set up DTLS context */
1145
0
    context->dtls.ctx = SSL_CTX_new(DTLS_method());
1146
0
    if (!context->dtls.ctx)
1147
0
      goto error;
1148
0
    SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
1149
0
    SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
1150
0
    SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
1151
0
    coap_set_user_prefs(context->dtls.ctx);
1152
0
    memset(cookie_secret, 0, sizeof(cookie_secret));
1153
0
    if (!RAND_bytes(cookie_secret, (int)sizeof(cookie_secret))) {
1154
0
      coap_dtls_log(COAP_LOG_WARN,
1155
0
                    "Insufficient entropy for random cookie generation");
1156
0
      coap_prng_lkd(cookie_secret, sizeof(cookie_secret));
1157
0
    }
1158
0
    context->dtls.cookie_hmac = HMAC_CTX_new();
1159
0
    if (!context->dtls.cookie_hmac)
1160
0
      goto error;
1161
0
    if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (int)sizeof(cookie_secret),
1162
0
                      EVP_sha256(), NULL))
1163
0
      goto error;
1164
0
    SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
1165
0
    SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
1166
0
    SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
1167
0
    SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
1168
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1169
    SSL_CTX_set_options(context->dtls.ctx, SSL_OP_LEGACY_SERVER_CONNECT);
1170
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
1171
0
    context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM, "coapdgram");
1172
0
    if (!context->dtls.meth)
1173
0
      goto error;
1174
0
    context->dtls.bio_addr = BIO_ADDR_new();
1175
0
    if (!context->dtls.bio_addr)
1176
0
      goto error;
1177
0
    BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
1178
0
    BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
1179
0
    BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
1180
0
    BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
1181
0
    BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
1182
0
    BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
1183
1184
0
#if !COAP_DISABLE_TCP
1185
    /* Set up TLS context */
1186
0
    context->tls.ctx = SSL_CTX_new(TLS_method());
1187
0
    if (!context->tls.ctx)
1188
0
      goto error;
1189
0
    SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
1190
0
    SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
1191
0
    coap_set_user_prefs(context->tls.ctx);
1192
0
    SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
1193
0
    context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET, "coapsock");
1194
0
    if (!context->tls.meth)
1195
0
      goto error;
1196
0
    BIO_meth_set_write(context->tls.meth, coap_sock_write);
1197
0
    BIO_meth_set_read(context->tls.meth, coap_sock_read);
1198
0
    BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
1199
0
    BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
1200
0
    BIO_meth_set_create(context->tls.meth, coap_sock_create);
1201
0
    BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
1202
0
#endif /* !COAP_DISABLE_TCP */
1203
0
  }
1204
1205
0
  return context;
1206
1207
0
error:
1208
0
  coap_dtls_free_context(context);
1209
0
  return NULL;
1210
0
}
1211
1212
#if COAP_SERVER_SUPPORT
1213
int
1214
coap_dtls_context_set_spsk(coap_context_t *c_context,
1215
                           coap_dtls_spsk_t *setup_data
1216
0
                          ) {
1217
0
  coap_openssl_context_t *o_context =
1218
0
      ((coap_openssl_context_t *)c_context->dtls_context);
1219
0
  BIO *bio;
1220
1221
0
  if (!setup_data || !o_context)
1222
0
    return 0;
1223
1224
0
  SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
1225
0
                                  coap_dtls_psk_server_callback);
1226
0
#if !COAP_DISABLE_TCP
1227
0
  SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
1228
0
                                  coap_dtls_psk_server_callback);
1229
0
#endif /* !COAP_DISABLE_TCP */
1230
0
  if (setup_data->psk_info.hint.s) {
1231
0
    char hint[COAP_DTLS_HINT_LENGTH];
1232
0
    snprintf(hint, sizeof(hint), "%.*s", (int)setup_data->psk_info.hint.length,
1233
0
             setup_data->psk_info.hint.s);
1234
0
    SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
1235
0
#if !COAP_DISABLE_TCP
1236
0
    SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
1237
0
#endif /* !COAP_DISABLE_TCP */
1238
0
  }
1239
0
  if (setup_data->validate_sni_call_back) {
1240
#if OPENSSL_VERSION_NUMBER < 0x10101000L
1241
    SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
1242
                                      &c_context->spsk_setup_data);
1243
    SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
1244
                                           psk_tls_server_name_call_back);
1245
#if !COAP_DISABLE_TCP
1246
    SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
1247
                                      &c_context->spsk_setup_data);
1248
    SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
1249
                                           psk_tls_server_name_call_back);
1250
#endif /* !COAP_DISABLE_TCP */
1251
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1252
0
    SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
1253
0
                                psk_tls_client_hello_call_back,
1254
0
                                NULL);
1255
0
#if !COAP_DISABLE_TCP
1256
0
    SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
1257
0
                                psk_tls_client_hello_call_back,
1258
0
                                NULL);
1259
0
#endif /* !COAP_DISABLE_TCP */
1260
0
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
1261
0
  }
1262
1263
0
  if (!o_context->dtls.ssl) {
1264
    /* This is set up to handle new incoming sessions to a server */
1265
0
    o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
1266
0
    if (!o_context->dtls.ssl)
1267
0
      return 0;
1268
0
    bio = BIO_new(o_context->dtls.meth);
1269
0
    if (!bio) {
1270
0
      SSL_free(o_context->dtls.ssl);
1271
0
      o_context->dtls.ssl = NULL;
1272
0
      return 0;
1273
0
    }
1274
0
    SSL_set_bio(o_context->dtls.ssl, bio, bio);
1275
0
    SSL_set_app_data(o_context->dtls.ssl, NULL);
1276
0
    SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1277
0
    SSL_set_mtu(o_context->dtls.ssl, COAP_DEFAULT_MTU);
1278
0
  }
1279
0
  if (setup_data->ec_jpake) {
1280
0
    coap_log_warn("OpenSSL has no EC-JPAKE support\n");
1281
0
  }
1282
0
  o_context->psk_pki_enabled |= IS_PSK;
1283
0
  return 1;
1284
0
}
1285
#endif /* COAP_SERVER_SUPPORT */
1286
1287
#if COAP_CLIENT_SUPPORT
1288
int
1289
coap_dtls_context_set_cpsk(coap_context_t *c_context,
1290
                           coap_dtls_cpsk_t *setup_data
1291
0
                          ) {
1292
0
  coap_openssl_context_t *o_context =
1293
0
      ((coap_openssl_context_t *)c_context->dtls_context);
1294
0
  BIO *bio;
1295
1296
0
  if (!setup_data || !o_context)
1297
0
    return 0;
1298
1299
0
  if (!o_context->dtls.ssl) {
1300
    /* This is set up to handle new incoming sessions to a server */
1301
0
    o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
1302
0
    if (!o_context->dtls.ssl)
1303
0
      return 0;
1304
0
    bio = BIO_new(o_context->dtls.meth);
1305
0
    if (!bio) {
1306
0
      SSL_free(o_context->dtls.ssl);
1307
0
      o_context->dtls.ssl = NULL;
1308
0
      return 0;
1309
0
    }
1310
0
    SSL_set_bio(o_context->dtls.ssl, bio, bio);
1311
0
    SSL_set_app_data(o_context->dtls.ssl, NULL);
1312
0
    SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1313
0
    SSL_set_mtu(o_context->dtls.ssl, COAP_DEFAULT_MTU);
1314
0
  }
1315
0
  if (setup_data->ec_jpake) {
1316
0
    coap_log_warn("OpenSSL has no EC-JPAKE support\n");
1317
0
  }
1318
0
  if (setup_data->use_cid) {
1319
0
    coap_log_warn("OpenSSL has no Connection-ID support\n");
1320
0
  }
1321
0
  o_context->psk_pki_enabled |= IS_PSK;
1322
0
  return 1;
1323
0
}
1324
#endif /* COAP_CLIENT_SUPPORT */
1325
1326
static int
1327
map_key_type(int asn1_private_key_type
1328
0
            ) {
1329
0
  switch (asn1_private_key_type) {
1330
0
  case COAP_ASN1_PKEY_NONE:
1331
0
    return EVP_PKEY_NONE;
1332
0
  case COAP_ASN1_PKEY_RSA:
1333
0
    return EVP_PKEY_RSA;
1334
0
  case COAP_ASN1_PKEY_RSA2:
1335
0
    return EVP_PKEY_RSA2;
1336
0
  case COAP_ASN1_PKEY_DSA:
1337
0
    return EVP_PKEY_DSA;
1338
0
  case COAP_ASN1_PKEY_DSA1:
1339
0
    return EVP_PKEY_DSA1;
1340
0
  case COAP_ASN1_PKEY_DSA2:
1341
0
    return EVP_PKEY_DSA2;
1342
0
  case COAP_ASN1_PKEY_DSA3:
1343
0
    return EVP_PKEY_DSA3;
1344
0
  case COAP_ASN1_PKEY_DSA4:
1345
0
    return EVP_PKEY_DSA4;
1346
0
  case COAP_ASN1_PKEY_DH:
1347
0
    return EVP_PKEY_DH;
1348
0
  case COAP_ASN1_PKEY_DHX:
1349
0
    return EVP_PKEY_DHX;
1350
0
  case COAP_ASN1_PKEY_EC:
1351
0
    return EVP_PKEY_EC;
1352
0
  case COAP_ASN1_PKEY_HMAC:
1353
0
    return EVP_PKEY_HMAC;
1354
0
  case COAP_ASN1_PKEY_CMAC:
1355
0
    return EVP_PKEY_CMAC;
1356
0
  case COAP_ASN1_PKEY_TLS1_PRF:
1357
0
    return EVP_PKEY_TLS1_PRF;
1358
0
  case COAP_ASN1_PKEY_HKDF:
1359
0
    return EVP_PKEY_HKDF;
1360
0
  default:
1361
0
    coap_log_warn("*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
1362
0
                  asn1_private_key_type);
1363
0
    break;
1364
0
  }
1365
0
  return 0;
1366
0
}
1367
#if !COAP_DISABLE_TCP
1368
static uint8_t coap_alpn[] = { 4, 'c', 'o', 'a', 'p' };
1369
1370
#if COAP_SERVER_SUPPORT
1371
static int
1372
server_alpn_callback(SSL *ssl COAP_UNUSED,
1373
                     const unsigned char **out,
1374
                     unsigned char *outlen,
1375
                     const unsigned char *in,
1376
                     unsigned int inlen,
1377
                     void *arg COAP_UNUSED
1378
0
                    ) {
1379
0
  unsigned char *tout = NULL;
1380
0
  int ret;
1381
0
  if (inlen == 0)
1382
0
    return SSL_TLSEXT_ERR_NOACK;
1383
0
  ret = SSL_select_next_proto(&tout,
1384
0
                              outlen,
1385
0
                              coap_alpn,
1386
0
                              sizeof(coap_alpn),
1387
0
                              in,
1388
0
                              inlen);
1389
0
  *out = tout;
1390
0
  return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
1391
0
}
1392
#endif /* COAP_SERVER_SUPPORT */
1393
#endif /* !COAP_DISABLE_TCP */
1394
1395
static void
1396
0
add_ca_to_cert_store(X509_STORE *st, X509 *x509) {
1397
0
  long e;
1398
1399
  /* Flush out existing errors */
1400
0
  while (ERR_get_error() != 0) {
1401
0
  }
1402
1403
0
  if (!X509_STORE_add_cert(st, x509)) {
1404
0
    while ((e = ERR_get_error()) != 0) {
1405
0
      int r = ERR_GET_REASON(e);
1406
0
      if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1407
        /* Not already added */
1408
0
        coap_log_warn("***setup_pki: (D)TLS: %s%s\n",
1409
0
                      ERR_reason_error_string(e),
1410
0
                      ssl_function_definition(e));
1411
0
      }
1412
0
    }
1413
0
  }
1414
0
}
1415
1416
static X509 *
1417
0
missing_ENGINE_load_cert(ENGINE *engine, const char *cert_id) {
1418
0
  struct {
1419
0
    const char *cert_id;
1420
0
    X509 *cert;
1421
0
  } params;
1422
1423
0
  params.cert_id = cert_id;
1424
0
  params.cert = NULL;
1425
1426
  /* There is no ENGINE_load_cert() */
1427
0
  if (!ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &params, NULL, 1)) {
1428
0
    params.cert = NULL;
1429
0
  }
1430
0
  return params.cert;
1431
0
}
1432
1433
static int
1434
0
check_pkcs11_engine(void) {
1435
0
  static int already_tried = 0;
1436
1437
0
  if (already_tried)
1438
0
    return 0;
1439
1440
0
  if (!pkcs11_engine) {
1441
0
    pkcs11_engine = ENGINE_by_id(COAP_OPENSSL_PKCS11_ENGINE_ID);
1442
0
    if (!pkcs11_engine) {
1443
0
      coap_log_err("*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL %s engine\n",
1444
0
                   COAP_OPENSSL_PKCS11_ENGINE_ID);
1445
0
      already_tried = 1;
1446
0
      return 0;
1447
0
    }
1448
0
    if (!ENGINE_init(pkcs11_engine)) {
1449
      /* the engine couldn't initialise, release 'pkcs11_engine' */
1450
0
      ENGINE_free(pkcs11_engine);
1451
0
      pkcs11_engine = NULL;
1452
0
      coap_log_err("*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1453
0
      already_tried = 1;
1454
0
      return 0;
1455
0
    }
1456
    /*
1457
     * ENGINE_init() returned a functional reference, so free the structural
1458
     * reference from ENGINE_by_id().
1459
     */
1460
0
    ENGINE_free(pkcs11_engine);
1461
0
  }
1462
0
  return 1;
1463
0
}
1464
1465
#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT
1466
1467
static int
1468
install_engine_public_cert_ctx(ENGINE *engine, SSL_CTX *ctx,
1469
                               const char *public_cert) {
1470
  X509 *x509;
1471
1472
  x509 = missing_ENGINE_load_cert(engine, public_cert);
1473
  if (!x509) {
1474
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1475
                  "%s Certificate\n",
1476
                  public_cert,
1477
                  "Server");
1478
    return 0;
1479
  }
1480
  if (!SSL_CTX_use_certificate(ctx, x509)) {
1481
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1482
                  "%s Certificate\n",
1483
                  public_cert,
1484
                  "Server");
1485
    X509_free(x509);
1486
    return 0;
1487
  }
1488
  X509_free(x509);
1489
  return 1;
1490
}
1491
1492
static int
1493
install_engine_private_key_ctx(ENGINE *engine, SSL_CTX *ctx,
1494
                               const char *private_key) {
1495
  EVP_PKEY *pkey = ENGINE_load_private_key(engine,
1496
                                           private_key,
1497
                                           NULL, NULL);
1498
1499
  if (!pkey) {
1500
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1501
                  "%s Private Key\n",
1502
                  private_key,
1503
                  "Server");
1504
    return 0;
1505
  }
1506
  if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1507
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1508
                  "%s Private Key\n",
1509
                  private_key,
1510
                  "Server");
1511
    EVP_PKEY_free(pkey);
1512
    return 0;
1513
  }
1514
  EVP_PKEY_free(pkey);
1515
  return 1;
1516
}
1517
1518
static int
1519
install_engine_ca_ctx(ENGINE *engine, SSL_CTX *ctx, const char *ca) {
1520
  X509 *x509;
1521
  X509_STORE *st;
1522
1523
  x509 = missing_ENGINE_load_cert(engine,
1524
                                  ca);
1525
  if (!x509) {
1526
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1527
                  "%s CA Certificate\n",
1528
                  ca,
1529
                  "Server");
1530
    return 0;
1531
  }
1532
  if (!SSL_CTX_add_client_CA(ctx, x509)) {
1533
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1534
                  "%s CA Certificate\n",
1535
                  ca,
1536
                  "Server");
1537
    X509_free(x509);
1538
    return 0;
1539
  }
1540
  st = SSL_CTX_get_cert_store(ctx);
1541
  add_ca_to_cert_store(st, x509);
1542
  X509_free(x509);
1543
  return 1;
1544
}
1545
1546
static int
1547
load_in_cas_ctx(SSL_CTX *ctx,
1548
                const char *ca_file) {
1549
  STACK_OF(X509_NAME) *cert_names;
1550
  X509_STORE *st;
1551
  BIO *in;
1552
  X509 *x = NULL;
1553
  char *rw_var = NULL;
1554
  cert_names = SSL_load_client_CA_file(ca_file);
1555
  if (cert_names != NULL)
1556
    SSL_CTX_set_client_CA_list(ctx, cert_names);
1557
  else {
1558
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1559
                  "client CA File\n",
1560
                  ca_file);
1561
    return 0;
1562
  }
1563
1564
  /* Add CA to the trusted root CA store */
1565
  st = SSL_CTX_get_cert_store(ctx);
1566
  in = BIO_new(BIO_s_file());
1567
  if (!in)
1568
    return 0;
1569
  /* Need to do this to not get a compiler warning about const parameters */
1570
  memcpy(&rw_var, &ca_file, sizeof(rw_var));
1571
  if (!BIO_read_filename(in, rw_var)) {
1572
    BIO_free(in);
1573
    return 0;
1574
  }
1575
1576
  for (;;) {
1577
    if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
1578
      break;
1579
    add_ca_to_cert_store(st, x);
1580
    X509_free(x);
1581
  }
1582
  BIO_free(in);
1583
  return 1;
1584
}
1585
1586
static int
1587
setup_pki_server(SSL_CTX *ctx,
1588
                 const coap_dtls_pki_t *setup_data) {
1589
  coap_dtls_key_t key;
1590
1591
  /* Map over to the new define format to save code duplication */
1592
  coap_dtls_map_key_type_to_define(setup_data, &key);
1593
1594
  assert(key.key_type == COAP_PKI_KEY_DEFINE);
1595
1596
  /*
1597
   * Configure the Private Key
1598
   */
1599
  if (key.key.define.private_key.u_byte &&
1600
      key.key.define.private_key.u_byte[0]) {
1601
    switch (key.key.define.private_key_def) {
1602
    case COAP_PKI_KEY_DEF_PEM: /* define private key */
1603
      if (!(SSL_CTX_use_PrivateKey_file(ctx,
1604
                                        key.key.define.private_key.s_byte,
1605
                                        SSL_FILETYPE_PEM))) {
1606
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1607
                                      COAP_DEFINE_FAIL_BAD,
1608
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1609
      }
1610
      break;
1611
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define private key */
1612
      if (key.key.define.private_key_len) {
1613
        BIO *bp = BIO_new_mem_buf(key.key.define.private_key.u_byte,
1614
                                  (int)key.key.define.private_key_len);
1615
        EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1616
1617
        if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
1618
          if (bp)
1619
            BIO_free(bp);
1620
          if (pkey)
1621
            EVP_PKEY_free(pkey);
1622
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1623
                                        COAP_DEFINE_FAIL_BAD,
1624
                                        &key, COAP_DTLS_ROLE_SERVER, 0);
1625
        }
1626
        if (bp)
1627
          BIO_free(bp);
1628
        if (pkey)
1629
          EVP_PKEY_free(pkey);
1630
      } else {
1631
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1632
                                      COAP_DEFINE_FAIL_NONE,
1633
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1634
      }
1635
      break;
1636
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define private key */
1637
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1638
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1639
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1640
    case COAP_PKI_KEY_DEF_DER: /* define private key */
1641
      if (!(SSL_CTX_use_PrivateKey_file(ctx,
1642
                                        key.key.define.private_key.s_byte,
1643
                                        SSL_FILETYPE_ASN1))) {
1644
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1645
                                      COAP_DEFINE_FAIL_BAD,
1646
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1647
      }
1648
      break;
1649
    case COAP_PKI_KEY_DEF_DER_BUF: /* define private key */
1650
      if (key.key.define.private_key_len == 0 ||
1651
          !(SSL_CTX_use_PrivateKey_ASN1(map_key_type(key.key.define.private_key_type),
1652
                                        ctx,
1653
                                        key.key.define.private_key.u_byte,
1654
                                        (long)key.key.define.private_key_len))) {
1655
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1656
                                      COAP_DEFINE_FAIL_BAD,
1657
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1658
      }
1659
      break;
1660
    case COAP_PKI_KEY_DEF_PKCS11: /* define private key */
1661
      if (!check_pkcs11_engine()) {
1662
        return 0;
1663
      }
1664
      if (key.key.define.user_pin) {
1665
        /* If not set, pin-value may be held in pkcs11: URI */
1666
        if (ENGINE_ctrl_cmd_string(pkcs11_engine,
1667
                                   "PIN",
1668
                                   key.key.define.user_pin, 0) == 0) {
1669
          coap_log_warn("*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1670
                        key.key.define.user_pin);
1671
          return 0;
1672
        }
1673
      }
1674
      if (!install_engine_private_key_ctx(pkcs11_engine, ctx,
1675
                                          key.key.define.private_key.s_byte)) {
1676
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1677
                                      COAP_DEFINE_FAIL_BAD,
1678
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1679
      }
1680
      break;
1681
    case COAP_PKI_KEY_DEF_ENGINE: /* define private key */
1682
      if (!defined_engine ||
1683
          !install_engine_private_key_ctx(defined_engine, ctx,
1684
                                          key.key.define.private_key.s_byte)) {
1685
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1686
                                      COAP_DEFINE_FAIL_BAD,
1687
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1688
      }
1689
      break;
1690
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define private key */
1691
    default:
1692
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1693
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1694
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1695
    }
1696
  } else if (key.key.define.public_cert.u_byte && key.key.define.public_cert.u_byte[0]) {
1697
    return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
1698
                                  COAP_DEFINE_FAIL_NONE,
1699
                                  &key, COAP_DTLS_ROLE_SERVER, 0);
1700
  }
1701
1702
  /*
1703
   * Configure the Public Certificate / Key
1704
   * OpenSSL < 1.1.1 and Server
1705
   */
1706
  if (key.key.define.public_cert.u_byte &&
1707
      key.key.define.public_cert.u_byte[0]) {
1708
    switch (key.key.define.public_cert_def) {
1709
    case COAP_PKI_KEY_DEF_PEM: /* define public cert */
1710
      if (key.key.define.ca.u_byte &&
1711
          key.key.define.ca.u_byte[0]) {
1712
        if (!(SSL_CTX_use_certificate_file(ctx,
1713
                                           key.key.define.public_cert.s_byte,
1714
                                           SSL_FILETYPE_PEM))) {
1715
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1716
                                        COAP_DEFINE_FAIL_BAD,
1717
                                        &key, COAP_DTLS_ROLE_SERVER, 0);
1718
        }
1719
      } else {
1720
        if (!SSL_CTX_use_certificate_chain_file(ctx,
1721
                                                key.key.define.public_cert.s_byte)) {
1722
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1723
                                        COAP_DEFINE_FAIL_BAD,
1724
                                        &key, COAP_DTLS_ROLE_SERVER, 0);
1725
        }
1726
      }
1727
      break;
1728
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define public cert */
1729
      if (key.key.define.public_cert_len) {
1730
        BIO *bp = BIO_new_mem_buf(key.key.define.public_cert.u_byte,
1731
                                  (int)key.key.define.public_cert_len);
1732
        X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1733
1734
        if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
1735
          if (bp)
1736
            BIO_free(bp);
1737
          if (cert)
1738
            X509_free(cert);
1739
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1740
                                        COAP_DEFINE_FAIL_BAD,
1741
                                        &key, COAP_DTLS_ROLE_SERVER, 0);
1742
        }
1743
        if (bp)
1744
          BIO_free(bp);
1745
        if (cert)
1746
          X509_free(cert);
1747
      } else {
1748
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1749
                                      COAP_DEFINE_FAIL_BAD,
1750
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1751
      }
1752
      break;
1753
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define public cert */
1754
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1755
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1756
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1757
    case COAP_PKI_KEY_DEF_DER: /* define public cert */
1758
      if (!(SSL_CTX_use_certificate_file(ctx,
1759
                                         key.key.define.public_cert.s_byte,
1760
                                         SSL_FILETYPE_ASN1))) {
1761
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1762
                                      COAP_DEFINE_FAIL_BAD,
1763
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1764
      }
1765
      break;
1766
    case COAP_PKI_KEY_DEF_DER_BUF: /* define public cert */
1767
      if (key.key.define.public_cert_len == 0 ||
1768
          !(SSL_CTX_use_certificate_ASN1(ctx,
1769
                                         (int)key.key.define.public_cert_len,
1770
                                         key.key.define.public_cert.u_byte))) {
1771
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1772
                                      COAP_DEFINE_FAIL_BAD,
1773
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1774
      }
1775
      break;
1776
    case COAP_PKI_KEY_DEF_PKCS11: /* define public cert */
1777
      if (!check_pkcs11_engine()) {
1778
        return 0;
1779
      }
1780
      if (!install_engine_public_cert_ctx(pkcs11_engine, ctx,
1781
                                          key.key.define.public_cert.s_byte)) {
1782
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1783
                                      COAP_DEFINE_FAIL_BAD,
1784
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1785
      }
1786
      break;
1787
    case COAP_PKI_KEY_DEF_ENGINE: /* define public cert */
1788
      if (!defined_engine ||
1789
          !install_engine_public_cert_ctx(defined_engine, ctx,
1790
                                          key.key.define.public_cert.s_byte)) {
1791
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1792
                                      COAP_DEFINE_FAIL_BAD,
1793
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1794
      }
1795
      break;
1796
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define public cert */
1797
    default:
1798
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1799
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1800
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1801
    }
1802
  } else if (key.key.define.private_key.u_byte &&
1803
             key.key.define.private_key.u_byte[0]) {
1804
    return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
1805
                                  COAP_DEFINE_FAIL_NONE,
1806
                                  &key, COAP_DTLS_ROLE_SERVER, 0);
1807
  }
1808
1809
  /*
1810
   * Configure the CA
1811
   */
1812
  if (key.key.define.ca.u_byte &&
1813
      key.key.define.ca.u_byte[0]) {
1814
    switch (key.key.define.ca_def) {
1815
    case COAP_PKI_KEY_DEF_PEM:
1816
      if (!load_in_cas_ctx(ctx, key.key.define.ca.s_byte)) {
1817
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1818
                                      COAP_DEFINE_FAIL_BAD,
1819
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1820
      }
1821
      break;
1822
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define ca */
1823
      if (key.key.define.ca_len) {
1824
        BIO *bp = BIO_new_mem_buf(key.key.define.ca.s_byte,
1825
                                  (int)key.key.define.ca_len);
1826
        X509 *x;
1827
        X509_STORE *st = SSL_CTX_get_cert_store(ctx);
1828
1829
        if (bp) {
1830
          for (;;) {
1831
            if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
1832
              break;
1833
            add_ca_to_cert_store(st, x);
1834
            SSL_CTX_add_client_CA(ctx, x);
1835
            X509_free(x);
1836
          }
1837
          BIO_free(bp);
1838
        }
1839
      } else {
1840
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1841
                                      COAP_DEFINE_FAIL_BAD,
1842
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1843
      }
1844
      break;
1845
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define ca */
1846
      return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1847
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1848
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1849
    case COAP_PKI_KEY_DEF_DER: /* define ca */
1850
      if (!(SSL_CTX_use_certificate_file(ctx,
1851
                                         key.key.define.ca.s_byte,
1852
                                         SSL_FILETYPE_ASN1))) {
1853
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1854
                                      COAP_DEFINE_FAIL_BAD,
1855
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1856
      }
1857
      break;
1858
    case COAP_PKI_KEY_DEF_DER_BUF: /* define ca */
1859
      if (key.key.define.ca_len > 0) {
1860
        /* Need to use a temp variable as it gets incremented*/
1861
        const uint8_t *p = key.key.define.ca.u_byte;
1862
        X509 *x509 = d2i_X509(NULL, &p, (long)key.key.define.ca_len);
1863
        X509_STORE *st;
1864
1865
        if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1866
          X509_free(x509);
1867
          return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1868
                                        COAP_DEFINE_FAIL_BAD,
1869
                                        &key, COAP_DTLS_ROLE_SERVER, 0);
1870
        }
1871
1872
        /* Add CA to the trusted root CA store */
1873
        st = SSL_CTX_get_cert_store(ctx);
1874
        add_ca_to_cert_store(st, x509);
1875
        X509_free(x509);
1876
      }
1877
      break;
1878
    case COAP_PKI_KEY_DEF_PKCS11: /* define ca */
1879
      if (!check_pkcs11_engine()) {
1880
        return 0;
1881
      }
1882
      if (!install_engine_ca_ctx(pkcs11_engine, ctx,
1883
                                 key.key.define.ca.s_byte)) {
1884
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1885
                                      COAP_DEFINE_FAIL_BAD,
1886
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1887
      }
1888
      break;
1889
    case COAP_PKI_KEY_DEF_ENGINE: /* define ca */
1890
      if (!defined_engine ||
1891
          !install_engine_ca_ctx(defined_engine, ctx,
1892
                                 key.key.define.ca.s_byte)) {
1893
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1894
                                      COAP_DEFINE_FAIL_BAD,
1895
                                      &key, COAP_DTLS_ROLE_SERVER, 0);
1896
      }
1897
      break;
1898
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define ca */
1899
    default:
1900
      return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
1901
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
1902
                                    &key, COAP_DTLS_ROLE_SERVER, 0);
1903
    }
1904
  }
1905
1906
  return 1;
1907
}
1908
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
1909
1910
#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT
1911
1912
static int
1913
install_engine_public_cert(ENGINE *engine, SSL *ssl, const char *public_cert,
1914
0
                           coap_dtls_role_t role) {
1915
0
  X509 *x509;
1916
1917
0
  x509 = missing_ENGINE_load_cert(engine, public_cert);
1918
0
  if (!x509) {
1919
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1920
0
                  "%s Certificate\n",
1921
0
                  public_cert,
1922
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1923
0
    return 0;
1924
0
  }
1925
0
  if (!SSL_use_certificate(ssl, x509)) {
1926
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1927
0
                  "%s Certificate\n",
1928
0
                  public_cert,
1929
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1930
0
    X509_free(x509);
1931
0
    return 0;
1932
0
  }
1933
0
  X509_free(x509);
1934
0
  return 1;
1935
0
}
1936
1937
static int
1938
install_engine_private_key(ENGINE *engine, SSL *ssl, const char *private_key,
1939
0
                           coap_dtls_role_t role) {
1940
0
  EVP_PKEY *pkey = ENGINE_load_private_key(engine,
1941
0
                                           private_key,
1942
0
                                           NULL, NULL);
1943
1944
0
  if (!pkey) {
1945
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1946
0
                  "%s Private Key\n",
1947
0
                  private_key,
1948
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1949
0
    return 0;
1950
0
  }
1951
0
  if (!SSL_use_PrivateKey(ssl, pkey)) {
1952
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1953
0
                  "%s Private Key\n",
1954
0
                  private_key,
1955
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1956
0
    EVP_PKEY_free(pkey);
1957
0
    return 0;
1958
0
  }
1959
0
  EVP_PKEY_free(pkey);
1960
0
  return 1;
1961
0
}
1962
1963
static int
1964
install_engine_ca(ENGINE *engine, SSL *ssl, const char *ca,
1965
0
                  coap_dtls_role_t role) {
1966
0
  X509 *x509;
1967
0
  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1968
0
  X509_STORE *st;
1969
1970
0
  if (!ctx) {
1971
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1972
0
                  "%s CA Certificate (no ctx)\n",
1973
0
                  ca,
1974
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1975
0
    return 0;
1976
0
  }
1977
0
  x509 = missing_ENGINE_load_cert(engine,
1978
0
                                  ca);
1979
0
  if (!x509) {
1980
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to load "
1981
0
                  "%s CA Certificate\n",
1982
0
                  ca,
1983
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1984
0
    return 0;
1985
0
  }
1986
0
  if (!SSL_add_client_CA(ssl, x509)) {
1987
0
    coap_log_warn("*** setup_pki: (D)TLS: %s: Unable to configure "
1988
0
                  "%s CA Certificate\n",
1989
0
                  ca,
1990
0
                  role == COAP_DTLS_ROLE_SERVER ? "Server" : "Client");
1991
0
    X509_free(x509);
1992
0
    return 0;
1993
0
  }
1994
0
  st = SSL_CTX_get_cert_store(ctx);
1995
0
  add_ca_to_cert_store(st, x509);
1996
0
  X509_free(x509);
1997
0
  return 1;
1998
0
}
1999
2000
static int
2001
load_in_cas(SSL *ssl,
2002
0
            const char *ca_file, coap_dtls_role_t role) {
2003
0
  X509_STORE *st;
2004
0
  BIO *in;
2005
0
  X509 *x = NULL;
2006
0
  char *rw_var = NULL;
2007
0
  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
2008
2009
0
  if (role == COAP_DTLS_ROLE_SERVER) {
2010
0
    STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(ca_file);
2011
2012
0
    if (cert_names != NULL)
2013
0
      SSL_set_client_CA_list(ssl, cert_names);
2014
0
    else {
2015
0
      return 0;
2016
0
    }
2017
0
  }
2018
2019
0
  if (!ctx)
2020
0
    return 0;
2021
2022
  /* Add CA to the trusted root CA store */
2023
0
  in = BIO_new(BIO_s_file());
2024
0
  if (!in)
2025
0
    return 0;
2026
  /* Need to do this to not get a compiler warning about const parameters */
2027
0
  memcpy(&rw_var, &ca_file, sizeof(rw_var));
2028
0
  if (!BIO_read_filename(in, rw_var)) {
2029
0
    BIO_free(in);
2030
0
    return 0;
2031
0
  }
2032
0
  st = SSL_CTX_get_cert_store(ctx);
2033
0
  for (;;) {
2034
0
    if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
2035
0
      break;
2036
0
    add_ca_to_cert_store(st, x);
2037
0
    X509_free(x);
2038
0
  }
2039
0
  BIO_free(in);
2040
0
  return 1;
2041
0
}
2042
2043
static int
2044
setup_pki_ssl(SSL *ssl,
2045
0
              coap_dtls_pki_t *setup_data, coap_dtls_role_t role) {
2046
0
  coap_dtls_key_t key;
2047
2048
  /* Map over to the new define format to save code duplication */
2049
0
  coap_dtls_map_key_type_to_define(setup_data, &key);
2050
2051
0
  assert(key.key_type == COAP_PKI_KEY_DEFINE);
2052
2053
  /*
2054
   * Configure the Private Key
2055
   */
2056
0
  if (key.key.define.private_key.u_byte &&
2057
0
      key.key.define.private_key.u_byte[0]) {
2058
0
    switch (key.key.define.private_key_def) {
2059
0
    case COAP_PKI_KEY_DEF_PEM: /* define private key */
2060
0
      if (!(SSL_use_PrivateKey_file(ssl,
2061
0
                                    key.key.define.private_key.s_byte,
2062
0
                                    SSL_FILETYPE_PEM))) {
2063
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2064
0
                                      COAP_DEFINE_FAIL_BAD,
2065
0
                                      &key, role, 0);
2066
0
      }
2067
0
      break;
2068
0
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define private key */
2069
0
      if (key.key.define.private_key_len) {
2070
0
        BIO *bp = BIO_new_mem_buf(key.key.define.private_key.u_byte,
2071
0
                                  (int)key.key.define.private_key_len);
2072
0
        EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
2073
2074
0
        if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
2075
0
          if (bp)
2076
0
            BIO_free(bp);
2077
0
          if (pkey)
2078
0
            EVP_PKEY_free(pkey);
2079
0
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2080
0
                                        COAP_DEFINE_FAIL_BAD,
2081
0
                                        &key, role, 0);
2082
0
        }
2083
0
        if (bp)
2084
0
          BIO_free(bp);
2085
0
        if (pkey)
2086
0
          EVP_PKEY_free(pkey);
2087
0
      } else {
2088
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2089
0
                                      COAP_DEFINE_FAIL_NONE,
2090
0
                                      &key, role, 0);
2091
0
      }
2092
0
      break;
2093
0
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define private key */
2094
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2095
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2096
0
                                    &key, role, 0);
2097
0
    case COAP_PKI_KEY_DEF_DER: /* define private key */
2098
0
      if (!(SSL_use_PrivateKey_file(ssl,
2099
0
                                    key.key.define.private_key.s_byte,
2100
0
                                    SSL_FILETYPE_ASN1))) {
2101
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2102
0
                                      COAP_DEFINE_FAIL_BAD,
2103
0
                                      &key, role, 0);
2104
0
      }
2105
0
      break;
2106
0
    case COAP_PKI_KEY_DEF_DER_BUF: /* define private key */
2107
0
      if (key.key.define.private_key_len == 0 ||
2108
0
          !(SSL_use_PrivateKey_ASN1(map_key_type(key.key.define.private_key_type),
2109
0
                                    ssl,
2110
0
                                    key.key.define.private_key.u_byte,
2111
0
                                    (long)key.key.define.private_key_len))) {
2112
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2113
0
                                      COAP_DEFINE_FAIL_BAD,
2114
0
                                      &key, role, 0);
2115
0
      }
2116
0
      break;
2117
0
    case COAP_PKI_KEY_DEF_PKCS11: /* define private key */
2118
0
      if (!check_pkcs11_engine()) {
2119
0
        return 0;
2120
0
      }
2121
0
      if (key.key.define.user_pin) {
2122
        /* If not set, pin-value may be held in pkcs11: URI */
2123
0
        if (ENGINE_ctrl_cmd_string(pkcs11_engine,
2124
0
                                   "PIN",
2125
0
                                   key.key.define.user_pin, 0) == 0) {
2126
0
          coap_log_warn("*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
2127
0
                        key.key.define.user_pin);
2128
0
          return 0;
2129
0
        }
2130
0
      }
2131
0
      if (!install_engine_private_key(pkcs11_engine, ssl,
2132
0
                                      key.key.define.private_key.s_byte,
2133
0
                                      role)) {
2134
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2135
0
                                      COAP_DEFINE_FAIL_BAD,
2136
0
                                      &key, role, 0);
2137
0
      }
2138
0
      break;
2139
0
    case COAP_PKI_KEY_DEF_ENGINE: /* define private key */
2140
0
      if (!defined_engine ||
2141
0
          !install_engine_private_key(defined_engine, ssl,
2142
0
                                      key.key.define.private_key.s_byte,
2143
0
                                      role)) {
2144
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2145
0
                                      COAP_DEFINE_FAIL_BAD,
2146
0
                                      &key, role, 0);
2147
0
      }
2148
0
      break;
2149
0
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define private key */
2150
0
    default:
2151
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2152
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2153
0
                                    &key, role, 0);
2154
0
    }
2155
0
  } else if (role == COAP_DTLS_ROLE_SERVER ||
2156
0
             (key.key.define.public_cert.u_byte &&
2157
0
              key.key.define.public_cert.u_byte[0])) {
2158
0
    return coap_dtls_define_issue(COAP_DEFINE_KEY_PRIVATE,
2159
0
                                  COAP_DEFINE_FAIL_NONE,
2160
0
                                  &key, role, 0);
2161
0
  }
2162
2163
  /*
2164
   * Configure the Public Certificate / Key
2165
   */
2166
0
  if (key.key.define.public_cert.u_byte &&
2167
0
      key.key.define.public_cert.u_byte[0]) {
2168
0
    switch (key.key.define.public_cert_def) {
2169
0
    case COAP_PKI_KEY_DEF_PEM: /* define public cert */
2170
0
      if (key.key.define.ca.u_byte &&
2171
0
          key.key.define.ca.u_byte[0]) {
2172
        /* If CA is separately defined */
2173
0
        if (!(SSL_use_certificate_file(ssl,
2174
0
                                       key.key.define.public_cert.s_byte,
2175
0
                                       SSL_FILETYPE_PEM))) {
2176
0
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2177
0
                                        COAP_DEFINE_FAIL_BAD,
2178
0
                                        &key, role, 0);
2179
0
        }
2180
0
      } else {
2181
0
        if (!SSL_use_certificate_chain_file(ssl,
2182
0
                                            key.key.define.public_cert.s_byte)) {
2183
0
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2184
0
                                        COAP_DEFINE_FAIL_BAD,
2185
0
                                        &key, role, 0);
2186
0
        }
2187
0
      }
2188
0
      break;
2189
0
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define public cert */
2190
0
      if (key.key.define.public_cert_len) {
2191
0
        BIO *bp = BIO_new_mem_buf(key.key.define.public_cert.s_byte,
2192
0
                                  (int)key.key.define.public_cert_len);
2193
0
        X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
2194
2195
0
        if (!cert || !SSL_use_certificate(ssl, cert)) {
2196
0
          if (bp)
2197
0
            BIO_free(bp);
2198
0
          if (cert)
2199
0
            X509_free(cert);
2200
0
          return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2201
0
                                        COAP_DEFINE_FAIL_BAD,
2202
0
                                        &key, role, 0);
2203
0
        }
2204
0
        if (bp)
2205
0
          BIO_free(bp);
2206
0
        if (cert)
2207
0
          X509_free(cert);
2208
0
      } else {
2209
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2210
0
                                      COAP_DEFINE_FAIL_BAD,
2211
0
                                      &key, role, 0);
2212
0
      }
2213
0
      break;
2214
0
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define public cert */
2215
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2216
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2217
0
                                    &key, role, 0);
2218
0
    case COAP_PKI_KEY_DEF_DER: /* define public cert */
2219
0
      if (!(SSL_use_certificate_file(ssl,
2220
0
                                     key.key.define.public_cert.s_byte,
2221
0
                                     SSL_FILETYPE_ASN1))) {
2222
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2223
0
                                      COAP_DEFINE_FAIL_BAD,
2224
0
                                      &key, role, 0);
2225
0
      }
2226
0
      break;
2227
0
    case COAP_PKI_KEY_DEF_DER_BUF: /* define public cert */
2228
0
      if (key.key.define.public_cert_len == 0 ||
2229
0
          !(SSL_use_certificate_ASN1(ssl,
2230
0
                                     key.key.define.public_cert.u_byte,
2231
0
                                     (int)key.key.define.public_cert_len))) {
2232
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2233
0
                                      COAP_DEFINE_FAIL_BAD,
2234
0
                                      &key, role, 0);
2235
0
      }
2236
0
      break;
2237
0
    case COAP_PKI_KEY_DEF_PKCS11: /* define public cert */
2238
0
      if (!check_pkcs11_engine()) {
2239
0
        return 0;
2240
0
      }
2241
0
      if (!install_engine_public_cert(pkcs11_engine, ssl,
2242
0
                                      key.key.define.public_cert.s_byte,
2243
0
                                      role)) {
2244
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2245
0
                                      COAP_DEFINE_FAIL_BAD,
2246
0
                                      &key, role, 0);
2247
0
      }
2248
0
      break;
2249
0
    case COAP_PKI_KEY_DEF_ENGINE: /* define public cert */
2250
0
      if (!defined_engine ||
2251
0
          !install_engine_public_cert(defined_engine, ssl,
2252
0
                                      key.key.define.public_cert.s_byte,
2253
0
                                      role)) {
2254
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2255
0
                                      COAP_DEFINE_FAIL_BAD,
2256
0
                                      &key, role, 0);
2257
0
      }
2258
0
      break;
2259
0
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define public cert */
2260
0
    default:
2261
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2262
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2263
0
                                    &key, role, 0);
2264
0
    }
2265
0
  } else if (role == COAP_DTLS_ROLE_SERVER ||
2266
0
             (key.key.define.private_key.u_byte &&
2267
0
              key.key.define.private_key.u_byte[0])) {
2268
0
    return coap_dtls_define_issue(COAP_DEFINE_KEY_PUBLIC,
2269
0
                                  COAP_DEFINE_FAIL_NONE,
2270
0
                                  &key, role, 0);
2271
0
  }
2272
2273
  /*
2274
   * Configure the CA
2275
   */
2276
0
  if (key.key.define.ca.u_byte &&
2277
0
      key.key.define.ca.u_byte[0]) {
2278
0
    switch (key.key.define.ca_def) {
2279
0
    case COAP_PKI_KEY_DEF_PEM:
2280
0
      if (!load_in_cas(ssl, key.key.define.ca.s_byte, role)) {
2281
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2282
0
                                      COAP_DEFINE_FAIL_BAD,
2283
0
                                      &key, role, 0);
2284
0
      }
2285
0
      break;
2286
0
    case COAP_PKI_KEY_DEF_PEM_BUF: /* define ca */
2287
0
      if (key.key.define.ca_len) {
2288
0
        BIO *bp = BIO_new_mem_buf(key.key.define.ca.u_byte,
2289
0
                                  (int)key.key.define.ca_len);
2290
0
        SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
2291
0
        X509 *x;
2292
0
        X509_STORE *st = ctx? SSL_CTX_get_cert_store(ctx) : NULL;
2293
2294
0
        if (bp) {
2295
0
          for (;;) {
2296
0
            if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
2297
0
              break;
2298
0
            if (st)
2299
0
              add_ca_to_cert_store(st, x);
2300
0
            SSL_add_client_CA(ssl, x);
2301
0
            X509_free(x);
2302
0
          }
2303
0
          BIO_free(bp);
2304
0
        }
2305
0
      } else {
2306
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2307
0
                                      COAP_DEFINE_FAIL_BAD,
2308
0
                                      &key, role, 0);
2309
0
      }
2310
0
      break;
2311
0
    case COAP_PKI_KEY_DEF_RPK_BUF: /* define ca */
2312
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2313
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2314
0
                                    &key, role, 0);
2315
0
    case COAP_PKI_KEY_DEF_DER: /* define ca */
2316
0
      if (!(SSL_use_certificate_file(ssl,
2317
0
                                     key.key.define.ca.s_byte,
2318
0
                                     SSL_FILETYPE_ASN1))) {
2319
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2320
0
                                      COAP_DEFINE_FAIL_BAD,
2321
0
                                      &key, role, 0);
2322
0
      }
2323
0
      break;
2324
0
    case COAP_PKI_KEY_DEF_DER_BUF: /* define ca */
2325
0
      if (key.key.define.ca_len > 0) {
2326
        /* Need to use a temp variable as it gets incremented*/
2327
0
        const uint8_t *p = key.key.define.ca.u_byte;
2328
0
        X509 *x509 = d2i_X509(NULL, &p, (long)key.key.define.ca_len);
2329
0
        X509_STORE *st;
2330
0
        SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
2331
2332
0
        if (role == COAP_DTLS_ROLE_SERVER) {
2333
0
          if (!x509 || !SSL_add_client_CA(ssl, x509)) {
2334
0
            X509_free(x509);
2335
0
            return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2336
0
                                          COAP_DEFINE_FAIL_BAD,
2337
0
                                          &key, role, 0);
2338
0
          }
2339
0
        }
2340
2341
        /* Add CA to the trusted root CA store */
2342
0
        st = ctx ? SSL_CTX_get_cert_store(ctx) : NULL;
2343
0
        if (st)
2344
0
          add_ca_to_cert_store(st, x509);
2345
0
        X509_free(x509);
2346
0
      }
2347
0
      break;
2348
0
    case COAP_PKI_KEY_DEF_PKCS11: /* define ca */
2349
0
      if (!check_pkcs11_engine()) {
2350
0
        return 0;
2351
0
      }
2352
0
      if (!install_engine_ca(pkcs11_engine, ssl,
2353
0
                             key.key.define.ca.s_byte,
2354
0
                             role)) {
2355
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2356
0
                                      COAP_DEFINE_FAIL_BAD,
2357
0
                                      &key, role, 0);
2358
0
      }
2359
0
      break;
2360
0
    case COAP_PKI_KEY_DEF_ENGINE: /* define ca */
2361
0
      if (!defined_engine ||
2362
0
          !install_engine_ca(defined_engine, ssl,
2363
0
                             key.key.define.ca.s_byte,
2364
0
                             role)) {
2365
0
        return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2366
0
                                      COAP_DEFINE_FAIL_BAD,
2367
0
                                      &key, role, 0);
2368
0
      }
2369
0
      break;
2370
0
    case COAP_PKI_KEY_DEF_PKCS11_RPK: /* define ca */
2371
0
    default:
2372
0
      return coap_dtls_define_issue(COAP_DEFINE_KEY_CA,
2373
0
                                    COAP_DEFINE_FAIL_NOT_SUPPORTED,
2374
0
                                    &key, role, 0);
2375
0
    }
2376
0
  }
2377
2378
0
  return 1;
2379
0
}
2380
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT */
2381
2382
static char *
2383
0
get_san_or_cn_from_cert(X509 *x509) {
2384
0
  if (x509) {
2385
0
    char *cn;
2386
0
    int n;
2387
0
    STACK_OF(GENERAL_NAME) *san_list;
2388
0
    char buffer[256];
2389
2390
0
    san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
2391
0
    if (san_list) {
2392
0
      int san_count = sk_GENERAL_NAME_num(san_list);
2393
2394
0
      for (n = 0; n < san_count; n++) {
2395
0
        const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n);
2396
2397
0
        if (name && name->type == GEN_DNS) {
2398
0
          const char *dns_name = (const char *)ASN1_STRING_get0_data(name->d.dNSName);
2399
2400
          /* Make sure that there is not an embedded NUL in the dns_name */
2401
0
          if (ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name))
2402
0
            continue;
2403
0
          cn = OPENSSL_strdup(dns_name);
2404
0
          sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
2405
0
          return cn;
2406
0
        }
2407
0
      }
2408
0
      sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
2409
0
    }
2410
    /* Otherwise look for the CN= field */
2411
0
    X509_NAME_oneline(X509_get_subject_name(x509), buffer, sizeof(buffer));
2412
2413
    /* Need to emulate strcasestr() here.  Looking for CN= */
2414
0
    n = (int)strlen(buffer) - 3;
2415
0
    cn = buffer;
2416
0
    while (n > 0) {
2417
0
      if (((cn[0] == 'C') || (cn[0] == 'c')) &&
2418
0
          ((cn[1] == 'N') || (cn[1] == 'n')) &&
2419
0
          (cn[2] == '=')) {
2420
0
        cn += 3;
2421
0
        break;
2422
0
      }
2423
0
      cn++;
2424
0
      n--;
2425
0
    }
2426
0
    if (n > 0) {
2427
0
      char *ecn = strchr(cn, '/');
2428
0
      if (ecn) {
2429
0
        return OPENSSL_strndup(cn, ecn-cn);
2430
0
      } else {
2431
0
        return OPENSSL_strdup(cn);
2432
0
      }
2433
0
    }
2434
0
  }
2435
0
  return NULL;
2436
0
}
2437
2438
static int
2439
0
tls_verify_call_back(int preverify_ok, X509_STORE_CTX *ctx) {
2440
0
  int index = SSL_get_ex_data_X509_STORE_CTX_idx();
2441
0
  SSL *ssl = index >= 0 ? X509_STORE_CTX_get_ex_data(ctx, index) : NULL;
2442
0
  coap_session_t *session = ssl ? SSL_get_app_data(ssl) : NULL;
2443
0
  coap_openssl_context_t *context = (session && session->context) ?
2444
0
                                    ((coap_openssl_context_t *)session->context->dtls_context) : NULL;
2445
0
  coap_dtls_pki_t *setup_data = context ? &context->setup_data : NULL;
2446
0
  int depth = X509_STORE_CTX_get_error_depth(ctx);
2447
0
  int err = X509_STORE_CTX_get_error(ctx);
2448
0
  X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
2449
0
  char *cn = x509 ? get_san_or_cn_from_cert(x509) : NULL;
2450
0
  int keep_preverify_ok = preverify_ok;
2451
2452
0
  coap_dtls_log(COAP_LOG_DEBUG, "depth %d error %x preverify %d cert '%s'\n",
2453
0
                depth, err, preverify_ok, cn);
2454
0
  if (!setup_data) {
2455
0
    X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
2456
0
    OPENSSL_free(cn);
2457
0
    return 0;
2458
0
  }
2459
0
  if (!preverify_ok) {
2460
0
    switch (err) {
2461
0
    case X509_V_ERR_CERT_NOT_YET_VALID:
2462
0
    case X509_V_ERR_CERT_HAS_EXPIRED:
2463
0
      if (setup_data->allow_expired_certs)
2464
0
        preverify_ok = 1;
2465
0
      break;
2466
0
    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
2467
0
      if (setup_data->allow_self_signed && !setup_data->check_common_ca)
2468
0
        preverify_ok = 1;
2469
0
      break;
2470
0
    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: /* Set if the CA is not known */
2471
0
      if (!setup_data->verify_peer_cert)
2472
0
        preverify_ok = 1;
2473
0
      break;
2474
0
    case X509_V_ERR_UNABLE_TO_GET_CRL:
2475
0
      if (setup_data->allow_no_crl)
2476
0
        preverify_ok = 1;
2477
0
      break;
2478
0
    case X509_V_ERR_CRL_NOT_YET_VALID:
2479
0
    case X509_V_ERR_CRL_HAS_EXPIRED:
2480
0
      if (setup_data->allow_expired_crl)
2481
0
        preverify_ok = 1;
2482
0
      break;
2483
0
    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
2484
0
    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
2485
0
    case X509_V_ERR_AKID_SKID_MISMATCH:
2486
0
      if (!setup_data->verify_peer_cert)
2487
0
        preverify_ok = 1;
2488
0
      break;
2489
0
    default:
2490
0
      break;
2491
0
    }
2492
0
    if (setup_data->cert_chain_validation &&
2493
0
        depth > (setup_data->cert_chain_verify_depth + 1)) {
2494
0
      preverify_ok = 0;
2495
0
      err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
2496
0
      X509_STORE_CTX_set_error(ctx, err);
2497
0
    }
2498
0
    if (!preverify_ok) {
2499
0
      if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
2500
0
        coap_log_warn("   %s: %s: '%s' depth=%d\n",
2501
0
                      coap_session_str(session),
2502
0
                      "Unknown CA", cn ? cn : "?", depth);
2503
0
      } else {
2504
0
        coap_log_warn("   %s: %s: '%s' depth=%d\n",
2505
0
                      coap_session_str(session),
2506
0
                      X509_verify_cert_error_string(err), cn ? cn : "?", depth);
2507
0
      }
2508
0
    } else {
2509
0
      coap_log_info("   %s: %s: overridden: '%s' depth=%d\n",
2510
0
                    coap_session_str(session),
2511
0
                    X509_verify_cert_error_string(err), cn ? cn : "?", depth);
2512
0
    }
2513
0
  }
2514
  /* Certificate - depth == 0 is the Client Cert */
2515
0
  if (setup_data->validate_cn_call_back && keep_preverify_ok) {
2516
0
    int length = i2d_X509(x509, NULL);
2517
0
    uint8_t *base_buf;
2518
0
    uint8_t *base_buf2 = base_buf = length > 0 ? OPENSSL_malloc(length) : NULL;
2519
0
    int ret;
2520
2521
0
    if (base_buf) {
2522
      /* base_buf2 gets moved to the end */
2523
0
      assert(i2d_X509(x509, &base_buf2) > 0);
2524
0
      (void)base_buf2;
2525
0
      coap_lock_callback_ret(ret,
2526
0
                             setup_data->validate_cn_call_back(cn, base_buf, length, session,
2527
0
                                                               depth, preverify_ok,
2528
0
                                                               setup_data->cn_call_back_arg));
2529
0
      if (!ret) {
2530
0
        if (depth == 0) {
2531
0
          X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
2532
0
        } else {
2533
0
          X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
2534
0
        }
2535
0
        preverify_ok = 0;
2536
0
      }
2537
0
      OPENSSL_free(base_buf);
2538
0
    } else {
2539
0
      X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
2540
0
      preverify_ok = 0;
2541
0
    }
2542
0
  }
2543
0
  OPENSSL_free(cn);
2544
0
  return preverify_ok;
2545
0
}
2546
2547
#if COAP_SERVER_SUPPORT
2548
#if OPENSSL_VERSION_NUMBER < 0x10101000L
2549
/* OpenSSL < 1.1.1 */
2550
/*
2551
 * During the SSL/TLS initial negotiations, tls_secret_call_back() is called so
2552
 * it is possible to determine whether this is a PKI or PSK incoming
2553
 * request and adjust the ciphers if necessary
2554
 *
2555
 * Set up by SSL_set_session_secret_cb() in tls_server_name_call_back()
2556
 */
2557
static int
2558
tls_secret_call_back(SSL *ssl,
2559
                     void *secret,
2560
                     int *secretlen,
2561
                     STACK_OF(SSL_CIPHER) *peer_ciphers,
2562
                     const SSL_CIPHER **cipher COAP_UNUSED,
2563
                     void *arg) {
2564
  int     ii;
2565
  int     psk_requested = 0;
2566
  coap_session_t *session;
2567
  coap_dtls_pki_t *setup_data = (coap_dtls_pki_t *)arg;
2568
2569
  session = (coap_session_t *)SSL_get_app_data(ssl);
2570
  assert(session != NULL);
2571
  assert(session->context != NULL);
2572
  if (session == NULL ||
2573
      session->context == NULL)
2574
    return 0;
2575
2576
  if ((session->psk_key) ||
2577
      (session->context->spsk_setup_data.psk_info.key.s &&
2578
       session->context->spsk_setup_data.psk_info.key.length)) {
2579
    /* Is PSK being requested - if so, we need to change algorithms */
2580
    for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2581
      const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2582
2583
      coap_dtls_log(COAP_LOG_INFO, "Client cipher: %s\n",
2584
                    SSL_CIPHER_get_name(peer_cipher));
2585
      if (strstr(SSL_CIPHER_get_name(peer_cipher), "PSK")) {
2586
        psk_requested = 1;
2587
        break;
2588
      }
2589
    }
2590
  }
2591
  if (!psk_requested) {
2592
    coap_log_debug("   %s: Using PKI ciphers\n",
2593
                   coap_session_str(session));
2594
2595
    if (setup_data->verify_peer_cert) {
2596
      SSL_set_verify(ssl,
2597
                     SSL_VERIFY_PEER |
2598
                     SSL_VERIFY_CLIENT_ONCE |
2599
                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2600
                     tls_verify_call_back);
2601
    } else {
2602
      SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2603
    }
2604
2605
    /* Check CA Chain */
2606
    if (setup_data->cert_chain_validation)
2607
      SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 2);
2608
2609
    /* Certificate Revocation */
2610
    if (setup_data->check_cert_revocation) {
2611
      X509_VERIFY_PARAM *param;
2612
2613
      param = X509_VERIFY_PARAM_new();
2614
      if (param) {
2615
        X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2616
        SSL_set1_param(ssl, param);
2617
        X509_VERIFY_PARAM_free(param);
2618
      }
2619
    }
2620
    if (setup_data->additional_tls_setup_call_back) {
2621
      /* Additional application setup wanted */
2622
      if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
2623
        return 0;
2624
    }
2625
  } else {
2626
    if (session->psk_key) {
2627
      memcpy(secret, session->psk_key->s, session->psk_key->length);
2628
      *secretlen = session->psk_key->length;
2629
    } else if (session->context->spsk_setup_data.psk_info.key.s &&
2630
               session->context->spsk_setup_data.psk_info.key.length) {
2631
      memcpy(secret, session->context->spsk_setup_data.psk_info.key.s,
2632
             session->context->spsk_setup_data.psk_info.key.length);
2633
      *secretlen = session->context->spsk_setup_data.psk_info.key.length;
2634
    }
2635
    coap_log_debug("   %s: Setting PSK ciphers\n",
2636
                   coap_session_str(session));
2637
    /*
2638
     * Force a PSK algorithm to be used, so we do PSK
2639
     */
2640
    SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2641
#ifdef COAP_OPENSSL_PSK_SECURITY_LEVEL
2642
    /*
2643
     * Set to 0 if, for example, PSK-AES128-CCM8 is to be supported (64 bits).
2644
     * Potentially opens up security vulnerabilities.
2645
     * Default value is 1.
2646
    */
2647
    SSL_set_security_level(ssl, COAP_OPENSSL_PSK_SECURITY_LEVEL);
2648
#endif /* COAP_OPENSSL_PSK_SECURITY_LEVEL */
2649
    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2650
  }
2651
  return 0;
2652
}
2653
2654
/* OpenSSL < 1.1.1 */
2655
/*
2656
 * During the SSL/TLS initial negotiations, tls_server_name_call_back() is
2657
 * called so it is possible to set up an extra callback to determine whether
2658
 * this is a PKI or PSK incoming request and adjust the ciphers if necessary
2659
 *
2660
 * Set up by SSL_CTX_set_tlsext_servername_callback() in
2661
 * coap_dtls_context_set_pki()
2662
 */
2663
static int
2664
tls_server_name_call_back(SSL *ssl,
2665
                          int *sd COAP_UNUSED,
2666
                          void *arg) {
2667
  coap_dtls_pki_t *setup_data = (coap_dtls_pki_t *)arg;
2668
2669
  if (!ssl) {
2670
    return SSL_TLSEXT_ERR_NOACK;
2671
  }
2672
2673
  if (setup_data->validate_sni_call_back) {
2674
    /* SNI checking requested */
2675
    coap_session_t *session = (coap_session_t *)SSL_get_app_data(ssl);
2676
    coap_openssl_context_t *context = (session && session->context) ?
2677
                                      ((coap_openssl_context_t *)session->context->dtls_context) : NULL;
2678
    const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2679
    size_t i;
2680
2681
    if (!context)
2682
      return SSL_TLSEXT_ERR_NOACK;
2683
2684
    if (!sni || !sni[0]) {
2685
      sni = "";
2686
    }
2687
    for (i = 0; i < context->sni_count; i++) {
2688
      if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2689
        break;
2690
      }
2691
    }
2692
    if (i == context->sni_count) {
2693
      SSL_CTX *ctx;
2694
      coap_dtls_pki_t sni_setup_data;
2695
      coap_dtls_key_t *new_entry;
2696
2697
      coap_lock_callback_ret(new_entry,
2698
                             setup_data->validate_sni_call_back(sni,
2699
                                                                setup_data->sni_call_back_arg));
2700
      if (!new_entry) {
2701
        return SSL_TLSEXT_ERR_ALERT_FATAL;
2702
      }
2703
      /* Need to set up a new SSL_CTX to switch to */
2704
      if (session->proto == COAP_PROTO_DTLS) {
2705
        /* Set up DTLS context */
2706
        ctx = SSL_CTX_new(DTLS_method());
2707
        if (!ctx)
2708
          goto error;
2709
        SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2710
        SSL_CTX_set_app_data(ctx, &context->dtls);
2711
        SSL_CTX_set_read_ahead(ctx, 1);
2712
        coap_set_user_prefs(ctx);
2713
        SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2714
        SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2715
        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2716
        SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2717
      }
2718
#if !COAP_DISABLE_TCP
2719
      else {
2720
        /* Set up TLS context */
2721
        ctx = SSL_CTX_new(TLS_method());
2722
        if (!ctx)
2723
          goto error;
2724
        SSL_CTX_set_app_data(ctx, &context->tls);
2725
        SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2726
        coap_set_user_prefs(ctx);
2727
        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2728
        SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2729
      }
2730
#endif /* !COAP_DISABLE_TCP */
2731
      sni_setup_data = *setup_data;
2732
      sni_setup_data.pki_key = *new_entry;
2733
      setup_pki_server(ctx, &sni_setup_data);
2734
2735
      context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2736
                                                (context->sni_count+1)*sizeof(sni_entry));
2737
      context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2738
      context->sni_entry_list[context->sni_count].ctx = ctx;
2739
      context->sni_count++;
2740
    }
2741
    SSL_set_SSL_CTX(ssl, context->sni_entry_list[i].ctx);
2742
    SSL_clear_options(ssl, 0xFFFFFFFFL);
2743
    SSL_set_options(ssl, SSL_CTX_get_options(context->sni_entry_list[i].ctx));
2744
  }
2745
2746
  /*
2747
   * Have to do extra call back next to get client algorithms
2748
   * SSL_get_client_ciphers() does not work this early on
2749
   */
2750
  SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2751
  return SSL_TLSEXT_ERR_OK;
2752
2753
error:
2754
  return SSL_TLSEXT_ERR_ALERT_WARNING;
2755
}
2756
2757
/* OpenSSL < 1.1.1 */
2758
/*
2759
 * During the SSL/TLS initial negotiations, psk_tls_server_name_call_back() is
2760
 * called to see if SNI is being used.
2761
 *
2762
 * Set up by SSL_CTX_set_tlsext_servername_callback()
2763
 * in coap_dtls_context_set_spsk()
2764
 */
2765
static int
2766
psk_tls_server_name_call_back(SSL *ssl,
2767
                              int *sd COAP_UNUSED,
2768
                              void *arg
2769
                             ) {
2770
  coap_dtls_spsk_t *setup_data = (coap_dtls_spsk_t *)arg;
2771
2772
  if (!ssl) {
2773
    return SSL_TLSEXT_ERR_NOACK;
2774
  }
2775
2776
  if (setup_data->validate_sni_call_back) {
2777
    /* SNI checking requested */
2778
    coap_session_t *c_session = (coap_session_t *)SSL_get_app_data(ssl);
2779
    coap_openssl_context_t *o_context = (c_session && c_session->context) ?
2780
                                        ((coap_openssl_context_t *)c_session->context->dtls_context) : NULL;
2781
    const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2782
    size_t i;
2783
    char lhint[COAP_DTLS_HINT_LENGTH];
2784
2785
    if (!o_context)
2786
      return SSL_TLSEXT_ERR_ALERT_FATAL;
2787
2788
    if (!sni || !sni[0]) {
2789
      sni = "";
2790
    }
2791
    for (i = 0; i < o_context->psk_sni_count; i++) {
2792
      if (!strcasecmp(sni, (char *)o_context->psk_sni_entry_list[i].sni)) {
2793
        break;
2794
      }
2795
    }
2796
    if (i == o_context->psk_sni_count) {
2797
      SSL_CTX *ctx;
2798
      const coap_dtls_spsk_info_t *new_entry;
2799
2800
      coap_lock_callback_ret(new_entry,
2801
                             setup_data->validate_sni_call_back(sni,
2802
                                                                c_session,
2803
                                                                setup_data->sni_call_back_arg));
2804
      if (!new_entry) {
2805
        return SSL_TLSEXT_ERR_ALERT_FATAL;
2806
      }
2807
      /* Need to set up a new SSL_CTX to switch to */
2808
      if (c_session->proto == COAP_PROTO_DTLS) {
2809
        /* Set up DTLS context */
2810
        ctx = SSL_CTX_new(DTLS_method());
2811
        if (!ctx)
2812
          goto error;
2813
        SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2814
        SSL_CTX_set_app_data(ctx, &o_context->dtls);
2815
        SSL_CTX_set_read_ahead(ctx, 1);
2816
        SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2817
        SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2818
        SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2819
        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2820
        SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2821
      }
2822
#if !COAP_DISABLE_TCP
2823
      else {
2824
        /* Set up TLS context */
2825
        ctx = SSL_CTX_new(TLS_method());
2826
        if (!ctx)
2827
          goto error;
2828
        SSL_CTX_set_app_data(ctx, &o_context->tls);
2829
        SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2830
        SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2831
        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2832
        SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2833
      }
2834
#endif /* !COAP_DISABLE_TCP */
2835
2836
      o_context->psk_sni_entry_list =
2837
          OPENSSL_realloc(o_context->psk_sni_entry_list,
2838
                          (o_context->psk_sni_count+1)*sizeof(psk_sni_entry));
2839
      o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2840
          OPENSSL_strdup(sni);
2841
      o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2842
          *new_entry;
2843
      o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
2844
          ctx;
2845
      o_context->psk_sni_count++;
2846
    }
2847
    SSL_set_SSL_CTX(ssl, o_context->psk_sni_entry_list[i].ctx);
2848
    SSL_clear_options(ssl, 0xFFFFFFFFL);
2849
    SSL_set_options(ssl,
2850
                    SSL_CTX_get_options(o_context->psk_sni_entry_list[i].ctx));
2851
    coap_session_refresh_psk_key(c_session,
2852
                                 &o_context->psk_sni_entry_list[i].psk_info.key);
2853
    snprintf(lhint, sizeof(lhint), "%.*s",
2854
             (int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2855
             o_context->psk_sni_entry_list[i].psk_info.hint.s);
2856
    SSL_use_psk_identity_hint(ssl, lhint);
2857
  }
2858
2859
  /*
2860
   * Have to do extra call back next to get client algorithms
2861
   * SSL_get_client_ciphers() does not work this early on
2862
   */
2863
  SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2864
  return SSL_TLSEXT_ERR_OK;
2865
2866
error:
2867
  return SSL_TLSEXT_ERR_ALERT_WARNING;
2868
}
2869
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
2870
/* OpenSSL >= 1.1.1 */
2871
/*
2872
 * During the SSL/TLS initial negotiations, tls_client_hello_call_back() is
2873
 * called early in the Client Hello processing so it is possible to determine
2874
 * whether this is a PKI or PSK incoming request and adjust the ciphers if
2875
 * necessary.
2876
 *
2877
 * Set up by SSL_CTX_set_client_hello_cb().
2878
 */
2879
static int
2880
tls_client_hello_call_back(SSL *ssl,
2881
                           int *al,
2882
                           void *arg COAP_UNUSED
2883
0
                          ) {
2884
0
  coap_session_t *session;
2885
0
  coap_openssl_context_t *dtls_context;
2886
0
  coap_dtls_pki_t *setup_data;
2887
0
  int psk_requested = 0;
2888
0
  const unsigned char *out;
2889
0
  size_t outlen;
2890
2891
0
  if (!ssl) {
2892
0
    *al = SSL_AD_INTERNAL_ERROR;
2893
0
    return SSL_CLIENT_HELLO_ERROR;
2894
0
  }
2895
0
  session = (coap_session_t *)SSL_get_app_data(ssl);
2896
0
  assert(session != NULL);
2897
0
  assert(session->context != NULL);
2898
0
  assert(session->context->dtls_context != NULL);
2899
0
  if (session == NULL ||
2900
0
      session->context == NULL ||
2901
0
      session->context->dtls_context == NULL) {
2902
0
    *al = SSL_AD_INTERNAL_ERROR;
2903
0
    return SSL_CLIENT_HELLO_ERROR;
2904
0
  }
2905
0
  dtls_context = (coap_openssl_context_t *)session->context->dtls_context;
2906
0
  setup_data = &dtls_context->setup_data;
2907
2908
  /*
2909
   * See if PSK being requested
2910
   */
2911
0
  if ((session->psk_key) ||
2912
0
      (session->context->spsk_setup_data.psk_info.key.s &&
2913
0
       session->context->spsk_setup_data.psk_info.key.length)) {
2914
0
    size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
2915
0
    STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
2916
0
    STACK_OF(SSL_CIPHER) *scsvc = NULL;
2917
2918
0
    if (len && SSL_bytes_to_cipher_list(ssl, out, len,
2919
0
                                        SSL_client_hello_isv2(ssl),
2920
0
                                        &peer_ciphers, &scsvc)) {
2921
0
      int ii;
2922
0
      for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2923
0
        const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2924
2925
0
        coap_dtls_log(COAP_LOG_INFO,
2926
0
                      "Client cipher: %s (%04x)\n",
2927
0
                      SSL_CIPHER_get_name(peer_cipher),
2928
0
                      SSL_CIPHER_get_protocol_id(peer_cipher));
2929
0
        if (strstr(SSL_CIPHER_get_name(peer_cipher), "PSK")) {
2930
0
          psk_requested = 1;
2931
0
          break;
2932
0
        }
2933
0
      }
2934
0
    }
2935
0
    sk_SSL_CIPHER_free(peer_ciphers);
2936
0
    sk_SSL_CIPHER_free(scsvc);
2937
0
  }
2938
2939
0
  if (psk_requested) {
2940
    /*
2941
     * Client has requested PSK and it is supported
2942
     */
2943
0
    coap_log_debug("   %s: PSK request\n",
2944
0
                   coap_session_str(session));
2945
0
    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2946
0
    if (setup_data->additional_tls_setup_call_back) {
2947
      /* Additional application setup wanted */
2948
0
      if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
2949
0
        return 0;
2950
0
    }
2951
0
    return SSL_CLIENT_HELLO_SUCCESS;
2952
0
  }
2953
2954
  /*
2955
   * Handle Certificate requests
2956
   */
2957
2958
  /*
2959
   * Determine what type of certificate is being requested
2960
   */
2961
0
  if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
2962
0
                                &out, &outlen)) {
2963
0
    size_t ii;
2964
0
    for (ii = 0; ii < outlen; ii++) {
2965
0
      switch (out[ii]) {
2966
0
      case 0:
2967
        /* RFC6091 X.509 */
2968
0
        if (outlen >= 2) {
2969
          /* X.509 cannot be the singular entry. RFC6091 3.1. Client Hello */
2970
0
          goto is_x509;
2971
0
        }
2972
0
        break;
2973
0
      case 2:
2974
        /* RFC7250 RPK - not yet supported */
2975
0
        break;
2976
0
      default:
2977
0
        break;
2978
0
      }
2979
0
    }
2980
0
    *al = SSL_AD_UNSUPPORTED_EXTENSION;
2981
0
    return SSL_CLIENT_HELLO_ERROR;
2982
0
  }
2983
2984
0
is_x509:
2985
0
  if (setup_data->validate_sni_call_back) {
2986
    /*
2987
     * SNI checking requested
2988
     */
2989
0
    coap_dtls_pki_t sni_setup_data;
2990
0
    coap_openssl_context_t *context =
2991
0
        ((coap_openssl_context_t *)session->context->dtls_context);
2992
0
    const char *sni = "";
2993
0
    char *sni_tmp = NULL;
2994
0
    size_t i;
2995
2996
0
    if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2997
0
        outlen > 5 &&
2998
0
        (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2999
0
        out[2] == TLSEXT_NAMETYPE_host_name &&
3000
0
        (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
3001
      /* Skip over length, type and length */
3002
0
      out += 5;
3003
0
      outlen -= 5;
3004
0
      sni_tmp = OPENSSL_malloc(outlen+1);
3005
0
      sni_tmp[outlen] = '\000';
3006
0
      memcpy(sni_tmp, out, outlen);
3007
0
      sni = sni_tmp;
3008
0
    }
3009
    /* Is this a cached entry? */
3010
0
    for (i = 0; i < context->sni_count; i++) {
3011
0
      if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
3012
0
        break;
3013
0
      }
3014
0
    }
3015
0
    if (i == context->sni_count) {
3016
      /*
3017
       * New SNI request
3018
       */
3019
0
      coap_dtls_key_t *new_entry;
3020
3021
0
      coap_lock_callback_ret(new_entry,
3022
0
                             setup_data->validate_sni_call_back(sni,
3023
0
                                                                setup_data->sni_call_back_arg));
3024
0
      if (!new_entry) {
3025
0
        *al = SSL_AD_UNRECOGNIZED_NAME;
3026
0
        return SSL_CLIENT_HELLO_ERROR;
3027
0
      }
3028
3029
3030
0
      context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
3031
0
                                                (context->sni_count+1)*sizeof(sni_entry));
3032
0
      context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
3033
0
      context->sni_entry_list[context->sni_count].pki_key = *new_entry;
3034
0
      context->sni_count++;
3035
0
    }
3036
0
    if (sni_tmp) {
3037
0
      OPENSSL_free(sni_tmp);
3038
0
    }
3039
0
    sni_setup_data = *setup_data;
3040
0
    sni_setup_data.pki_key = context->sni_entry_list[i].pki_key;
3041
0
    setup_pki_ssl(ssl, &sni_setup_data, COAP_DTLS_ROLE_SERVER);
3042
0
  } else {
3043
0
    setup_pki_ssl(ssl, setup_data, COAP_DTLS_ROLE_SERVER);
3044
0
  }
3045
3046
0
  coap_log_debug("   %s: Using PKI ciphers\n",
3047
0
                 coap_session_str(session));
3048
3049
0
  if (setup_data->verify_peer_cert) {
3050
0
    SSL_set_verify(ssl,
3051
0
                   SSL_VERIFY_PEER |
3052
0
                   SSL_VERIFY_CLIENT_ONCE |
3053
0
                   SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3054
0
                   tls_verify_call_back);
3055
0
  } else {
3056
0
    SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
3057
0
  }
3058
3059
  /* Check CA Chain */
3060
0
  if (setup_data->cert_chain_validation)
3061
0
    SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 2);
3062
3063
  /* Certificate Revocation */
3064
0
  if (setup_data->check_cert_revocation) {
3065
0
    X509_VERIFY_PARAM *param;
3066
3067
0
    param = X509_VERIFY_PARAM_new();
3068
0
    if (param) {
3069
0
      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
3070
0
      SSL_set1_param(ssl, param);
3071
0
      X509_VERIFY_PARAM_free(param);
3072
0
    }
3073
0
  }
3074
0
  if (setup_data->additional_tls_setup_call_back) {
3075
    /* Additional application setup wanted */
3076
0
    if (!setup_data->additional_tls_setup_call_back(ssl, setup_data))
3077
0
      return 0;
3078
0
  }
3079
0
  return SSL_CLIENT_HELLO_SUCCESS;
3080
0
}
3081
3082
/* OpenSSL >= 1.1.1 */
3083
/*
3084
 * During the SSL/TLS initial negotiations, psk_tls_client_hello_call_back() is
3085
 * called early in the Client Hello processing so it is possible to determine
3086
 * whether SNI needs to be handled
3087
 *
3088
 * Set up by SSL_CTX_set_client_hello_cb().
3089
 */
3090
static int
3091
psk_tls_client_hello_call_back(SSL *ssl,
3092
                               int *al,
3093
                               void *arg COAP_UNUSED
3094
0
                              ) {
3095
0
  coap_session_t *c_session;
3096
0
  coap_openssl_context_t *o_context;
3097
0
  coap_dtls_spsk_t *setup_data;
3098
0
  const unsigned char *out;
3099
0
  size_t outlen;
3100
3101
0
  if (!ssl)
3102
0
    goto int_err;
3103
0
  c_session = (coap_session_t *)SSL_get_app_data(ssl);
3104
0
  if (!c_session || !c_session->context) {
3105
0
    goto int_err;
3106
0
  }
3107
0
  o_context = (coap_openssl_context_t *)c_session->context->dtls_context;
3108
0
  if (!o_context) {
3109
0
    goto int_err;
3110
0
  }
3111
0
  setup_data = &c_session->context->spsk_setup_data;
3112
3113
0
  if (setup_data->validate_sni_call_back) {
3114
    /*
3115
     * SNI checking requested
3116
     */
3117
0
    const char *sni = "";
3118
0
    char *sni_tmp = NULL;
3119
0
    char lhint[COAP_DTLS_HINT_LENGTH];
3120
3121
0
    if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
3122
0
        outlen > 5 &&
3123
0
        (((out[0]<<8) + out[1] +2) == (int)outlen) &&
3124
0
        out[2] == TLSEXT_NAMETYPE_host_name &&
3125
0
        (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
3126
      /* Skip over length, type and length */
3127
0
      out += 5;
3128
0
      outlen -= 5;
3129
0
      sni_tmp = OPENSSL_malloc(outlen+1);
3130
0
      if (sni_tmp) {
3131
0
        sni_tmp[outlen] = '\000';
3132
0
        memcpy(sni_tmp, out, outlen);
3133
0
        sni = sni_tmp;
3134
0
      }
3135
0
    }
3136
3137
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3138
    size_t i;
3139
    /* Is this a cached entry? */
3140
    for (i = 0; i < o_context->psk_sni_count; i++) {
3141
      if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
3142
        break;
3143
      }
3144
    }
3145
    if (i == o_context->psk_sni_count) {
3146
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3147
      /*
3148
       * New SNI request
3149
       */
3150
0
      const coap_dtls_spsk_info_t *new_entry;
3151
3152
0
      coap_lock_callback_ret(new_entry,
3153
0
                             setup_data->validate_sni_call_back(
3154
0
                                 sni,
3155
0
                                 c_session,
3156
0
                                 setup_data->sni_call_back_arg));
3157
0
      if (!new_entry) {
3158
0
        *al = SSL_AD_UNRECOGNIZED_NAME;
3159
0
        return SSL_CLIENT_HELLO_ERROR;
3160
0
      }
3161
3162
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3163
      psk_sni_entry *tmp_entry;
3164
      tmp_entry =
3165
          OPENSSL_realloc(o_context->psk_sni_entry_list,
3166
                          (o_context->psk_sni_count+1)*sizeof(sni_entry));
3167
      if (tmp_entry) {
3168
        o_context->psk_sni_entry_list = tmp_entry;
3169
        o_context->psk_sni_entry_list[o_context->psk_sni_count]
3170
        .sni =
3171
            OPENSSL_strdup(sni);
3172
        if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
3173
          o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
3174
              *new_entry;
3175
          o_context->psk_sni_count++;
3176
        }
3177
      }
3178
    } else {
3179
      new_entry = &o_context->psk_sni_entry_list[i].psk_info;
3180
    }
3181
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3182
3183
0
    if (sni_tmp) {
3184
0
      OPENSSL_free(sni_tmp);
3185
0
    }
3186
0
    if (coap_session_refresh_psk_hint(c_session,
3187
0
                                      &new_entry->hint)
3188
0
        == 0) {
3189
0
      goto int_err;
3190
0
    }
3191
0
    if (coap_session_refresh_psk_key(c_session,
3192
0
                                     &new_entry->key)
3193
0
        == 0) {
3194
0
      goto int_err;
3195
0
    }
3196
0
    if (new_entry->hint.s) {
3197
0
      snprintf(lhint, sizeof(lhint), "%.*s",
3198
0
               (int)new_entry->hint.length,
3199
0
               new_entry->hint.s);
3200
0
      SSL_use_psk_identity_hint(ssl, lhint);
3201
0
    }
3202
0
  }
3203
0
  return SSL_CLIENT_HELLO_SUCCESS;
3204
3205
0
int_err:
3206
0
  *al = SSL_AD_INTERNAL_ERROR;
3207
0
  return SSL_CLIENT_HELLO_ERROR;
3208
0
}
3209
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3210
#endif /* COAP_SERVER_SUPPORT */
3211
3212
int
3213
coap_dtls_context_set_pki(coap_context_t *ctx,
3214
                          const coap_dtls_pki_t *setup_data,
3215
0
                          const coap_dtls_role_t role) {
3216
0
  coap_openssl_context_t *context =
3217
0
      ((coap_openssl_context_t *)ctx->dtls_context);
3218
0
  BIO *bio;
3219
0
  if (!setup_data)
3220
0
    return 0;
3221
0
  context->setup_data = *setup_data;
3222
3223
0
  if (context->setup_data.pki_key.key_type == COAP_PKI_KEY_DEFINE) {
3224
0
    if (context->setup_data.pki_key.key.define.ca_def == COAP_PKI_KEY_DEF_ENGINE ||
3225
0
        context->setup_data.pki_key.key.define.public_cert_def == COAP_PKI_KEY_DEF_ENGINE ||
3226
0
        context->setup_data.pki_key.key.define.private_key_def == COAP_PKI_KEY_DEF_ENGINE) {
3227
0
      if (!defined_engine) {
3228
0
        coap_log_warn("setup_pki: OpenSSL Engine not configured, PKI not set up\n");
3229
0
        return 0;
3230
0
      }
3231
0
    }
3232
0
  }
3233
3234
0
  if (!context->setup_data.verify_peer_cert) {
3235
    /* Needs to be clear so that no CA DNs are transmitted */
3236
0
    context->setup_data.check_common_ca = 0;
3237
    /* Allow all of these but warn if issue */
3238
0
    context->setup_data.allow_self_signed = 1;
3239
0
    context->setup_data.allow_expired_certs = 1;
3240
0
    context->setup_data.cert_chain_validation = 1;
3241
0
    context->setup_data.cert_chain_verify_depth = 10;
3242
0
    context->setup_data.check_cert_revocation = 1;
3243
0
    context->setup_data.allow_no_crl = 1;
3244
0
    context->setup_data.allow_expired_crl = 1;
3245
0
    context->setup_data.allow_bad_md_hash = 1;
3246
0
    context->setup_data.allow_short_rsa_length = 1;
3247
0
  }
3248
0
#if COAP_SERVER_SUPPORT
3249
0
  if (role == COAP_DTLS_ROLE_SERVER) {
3250
0
    if (context->dtls.ctx) {
3251
      /* SERVER DTLS */
3252
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3253
      if (!setup_pki_server(context->dtls.ctx, setup_data))
3254
        return 0;
3255
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3256
      /* libcoap is managing TLS connection based on setup_data options */
3257
      /* Need to set up logic to differentiate between a PSK or PKI session */
3258
      /*
3259
       * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
3260
       * which is not in 1.1.0
3261
       */
3262
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3263
      if (SSLeay() >= 0x10101000L) {
3264
        coap_log_warn("OpenSSL compiled with %lux, linked with %lux, so "
3265
                      "no certificate checking\n",
3266
                      OPENSSL_VERSION_NUMBER, SSLeay());
3267
      }
3268
      SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
3269
      SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
3270
                                             tls_server_name_call_back);
3271
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3272
0
      SSL_CTX_set_client_hello_cb(context->dtls.ctx,
3273
0
                                  tls_client_hello_call_back,
3274
0
                                  NULL);
3275
0
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3276
0
    }
3277
0
#if !COAP_DISABLE_TCP
3278
0
    if (context->tls.ctx) {
3279
      /* SERVER TLS */
3280
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3281
      if (!setup_pki_server(context->tls.ctx, setup_data))
3282
        return 0;
3283
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3284
      /* libcoap is managing TLS connection based on setup_data options */
3285
      /* Need to set up logic to differentiate between a PSK or PKI session */
3286
      /*
3287
       * For OpenSSL 1.1.1, we need to use SSL_CTX_set_client_hello_cb()
3288
       * which is not in 1.1.0
3289
       */
3290
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3291
      if (SSLeay() >= 0x10101000L) {
3292
        coap_log_warn("OpenSSL compiled with %lux, linked with %lux, so "
3293
                      "no certificate checking\n",
3294
                      OPENSSL_VERSION_NUMBER, SSLeay());
3295
      }
3296
      SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
3297
      SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
3298
                                             tls_server_name_call_back);
3299
#else /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3300
0
      SSL_CTX_set_client_hello_cb(context->tls.ctx,
3301
0
                                  tls_client_hello_call_back,
3302
0
                                  NULL);
3303
0
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3304
      /* TLS Only */
3305
0
      SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
3306
0
    }
3307
0
#endif /* !COAP_DISABLE_TCP */
3308
0
  }
3309
#else /* ! COAP_SERVER_SUPPORT */
3310
  (void)role;
3311
#endif /* ! COAP_SERVER_SUPPORT */
3312
3313
0
  if (!context->dtls.ssl) {
3314
    /* This is set up to handle new incoming sessions to a server */
3315
0
    context->dtls.ssl = SSL_new(context->dtls.ctx);
3316
0
    if (!context->dtls.ssl)
3317
0
      return 0;
3318
0
    bio = BIO_new(context->dtls.meth);
3319
0
    if (!bio) {
3320
0
      SSL_free(context->dtls.ssl);
3321
0
      context->dtls.ssl = NULL;
3322
0
      return 0;
3323
0
    }
3324
0
    SSL_set_bio(context->dtls.ssl, bio, bio);
3325
0
    SSL_set_app_data(context->dtls.ssl, NULL);
3326
0
    SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
3327
0
    SSL_set_mtu(context->dtls.ssl, COAP_DEFAULT_MTU);
3328
0
  }
3329
0
  context->psk_pki_enabled |= IS_PKI;
3330
0
  if (setup_data->use_cid) {
3331
0
    coap_log_warn("OpenSSL has no Connection-ID support\n");
3332
0
  }
3333
0
  return 1;
3334
0
}
3335
3336
int
3337
coap_dtls_context_set_pki_root_cas(coap_context_t *ctx,
3338
                                   const char *ca_file,
3339
                                   const char *ca_dir
3340
0
                                  ) {
3341
0
  coap_openssl_context_t *context =
3342
0
      ((coap_openssl_context_t *)ctx->dtls_context);
3343
0
  if (context->dtls.ctx) {
3344
0
    if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
3345
0
      coap_log_warn("Unable to install root CAs (%s : %s)\n",
3346
0
                    ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL");
3347
0
      return 0;
3348
0
    }
3349
0
  }
3350
0
#if !COAP_DISABLE_TCP
3351
0
  if (context->tls.ctx) {
3352
0
    if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
3353
0
      coap_log_warn("Unable to install root CAs (%s : %s)\n",
3354
0
                    ca_file ? ca_file : "NULL", ca_dir ? ca_dir : "NULL");
3355
0
      return 0;
3356
0
    }
3357
0
  }
3358
0
#endif /* !COAP_DISABLE_TCP */
3359
0
  return 1;
3360
0
}
3361
3362
int
3363
0
coap_dtls_context_load_pki_trust_store(coap_context_t *ctx) {
3364
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
3365
  coap_openssl_context_t *context =
3366
      ((coap_openssl_context_t *)ctx->dtls_context);
3367
  if (context->dtls.ctx) {
3368
    if (!SSL_CTX_set_default_verify_store(context->dtls.ctx)) {
3369
      coap_log_warn("Unable to load trusted root CAs\n");
3370
      return 0;
3371
    }
3372
  }
3373
#if !COAP_DISABLE_TCP
3374
  if (context->tls.ctx) {
3375
    if (!SSL_CTX_set_default_verify_store(context->tls.ctx)) {
3376
      coap_log_warn("Unable to load trusted root CAs\n");
3377
      return 0;
3378
    }
3379
  }
3380
#endif /* !COAP_DISABLE_TCP */
3381
  return 1;
3382
#else /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3383
0
  (void)ctx;
3384
0
  coap_log_warn("coap_context_set_pki_trust_store: (D)TLS environment "
3385
0
                "not supported for OpenSSL < v3.0.0\n");
3386
0
  return 0;
3387
0
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
3388
0
}
3389
3390
int
3391
0
coap_dtls_context_check_keys_enabled(coap_context_t *ctx) {
3392
0
  coap_openssl_context_t *context =
3393
0
      ((coap_openssl_context_t *)ctx->dtls_context);
3394
0
  return context->psk_pki_enabled ? 1 : 0;
3395
0
}
3396
3397
3398
void
3399
0
coap_dtls_free_context(void *handle) {
3400
0
  size_t i;
3401
0
  coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
3402
3403
0
  if (context->dtls.ssl)
3404
0
    SSL_free(context->dtls.ssl);
3405
0
  if (context->dtls.ctx)
3406
0
    SSL_CTX_free(context->dtls.ctx);
3407
0
  if (context->dtls.cookie_hmac)
3408
0
    HMAC_CTX_free(context->dtls.cookie_hmac);
3409
0
  if (context->dtls.meth)
3410
0
    BIO_meth_free(context->dtls.meth);
3411
0
  if (context->dtls.bio_addr)
3412
0
    BIO_ADDR_free(context->dtls.bio_addr);
3413
0
#if !COAP_DISABLE_TCP
3414
0
  if (context->tls.ctx)
3415
0
    SSL_CTX_free(context->tls.ctx);
3416
0
  if (context->tls.meth)
3417
0
    BIO_meth_free(context->tls.meth);
3418
0
#endif /* !COAP_DISABLE_TCP */
3419
0
  for (i = 0; i < context->sni_count; i++) {
3420
0
    OPENSSL_free(context->sni_entry_list[i].sni);
3421
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3422
    SSL_CTX_free(context->sni_entry_list[i].ctx);
3423
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3424
0
  }
3425
0
  if (context->sni_count)
3426
0
    OPENSSL_free(context->sni_entry_list);
3427
#if OPENSSL_VERSION_NUMBER < 0x10101000L
3428
  for (i = 0; i < context->psk_sni_count; i++) {
3429
    OPENSSL_free((char *)context->psk_sni_entry_list[i].sni);
3430
    SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
3431
  }
3432
  if (context->psk_sni_count)
3433
    OPENSSL_free(context->psk_sni_entry_list);
3434
#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
3435
0
  coap_free_type(COAP_STRING, context);
3436
0
}
3437
3438
#if COAP_SERVER_SUPPORT
3439
void *
3440
0
coap_dtls_new_server_session(coap_session_t *session) {
3441
0
  BIO *nbio = NULL;
3442
0
  SSL *nssl = NULL, *ssl = NULL;
3443
0
  coap_ssl_data *data;
3444
0
  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls;
3445
0
  int r;
3446
0
  const coap_bin_const_t *psk_hint;
3447
0
  BIO *rbio;
3448
3449
0
  nssl = SSL_new(dtls->ctx);
3450
0
  if (!nssl)
3451
0
    goto error;
3452
0
  nbio = BIO_new(dtls->meth);
3453
0
  if (!nbio)
3454
0
    goto error;
3455
0
  SSL_set_bio(nssl, nbio, nbio);
3456
0
  SSL_set_app_data(nssl, NULL);
3457
0
  SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
3458
0
  SSL_set_mtu(nssl, (long)session->mtu);
3459
0
  ssl = dtls->ssl;
3460
0
  dtls->ssl = nssl;
3461
0
  nssl = NULL;
3462
0
  SSL_set_app_data(ssl, session);
3463
3464
0
  rbio = SSL_get_rbio(ssl);
3465
0
  data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3466
0
  if (!data)
3467
0
    goto error;
3468
0
  data->session = session;
3469
3470
  /* hint may get updated if/when handling SNI callback */
3471
0
  psk_hint = coap_get_session_server_psk_hint(session);
3472
0
  if (psk_hint != NULL && psk_hint->length) {
3473
0
    char *hint = OPENSSL_malloc(psk_hint->length + 1);
3474
3475
0
    if (hint) {
3476
0
      memcpy(hint, psk_hint->s, psk_hint->length);
3477
0
      hint[psk_hint->length] = '\000';
3478
0
      SSL_use_psk_identity_hint(ssl, hint);
3479
0
      OPENSSL_free(hint);
3480
0
    } else {
3481
0
      coap_log_warn("hint malloc failure\n");
3482
0
    }
3483
0
  }
3484
3485
0
  r = SSL_accept(ssl);
3486
0
  if (r == -1) {
3487
0
    int err = SSL_get_error(ssl, r);
3488
0
    if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3489
0
      r = 0;
3490
0
  }
3491
3492
0
  if (r == 0) {
3493
0
    SSL_free(ssl);
3494
0
    return NULL;
3495
0
  }
3496
3497
0
  return ssl;
3498
3499
0
error:
3500
0
  if (nssl)
3501
0
    SSL_free(nssl);
3502
0
  return NULL;
3503
0
}
3504
#endif /* COAP_SERVER_SUPPORT */
3505
3506
#if COAP_CLIENT_SUPPORT
3507
static int
3508
setup_client_ssl_session(coap_session_t *session, SSL *ssl
3509
0
                        ) {
3510
0
  coap_openssl_context_t *context =
3511
0
      ((coap_openssl_context_t *)session->context->dtls_context);
3512
3513
0
  if (context->psk_pki_enabled & IS_PSK) {
3514
0
    coap_dtls_cpsk_t *setup_data = &session->cpsk_setup_data;
3515
3516
    /* Issue SNI if requested */
3517
0
    if (setup_data->client_sni &&
3518
0
        SSL_set_tlsext_host_name(ssl, setup_data->client_sni) != 1) {
3519
0
      coap_log_warn("SSL_set_tlsext_host_name: set '%s' failed",
3520
0
                    setup_data->client_sni);
3521
0
    }
3522
0
    SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
3523
0
#if COAP_SERVER_SUPPORT
3524
0
    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
3525
0
#endif /* COAP_SERVER_SUPPORT */
3526
0
    SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
3527
#ifdef COAP_OPENSSL_PSK_SECURITY_LEVEL
3528
    /*
3529
     * Set to 0 if, for example, PSK-AES128-CCM8 is to be supported (64 bits).
3530
     * Potentially opens up security vulnerabilities.
3531
     * Default value is 1.
3532
    */
3533
    SSL_set_security_level(ssl, COAP_OPENSSL_PSK_SECURITY_LEVEL);
3534
#endif /* COAP_OPENSSL_PSK_SECURITY_LEVEL */
3535
0
    if (setup_data->validate_ih_call_back) {
3536
0
      if (session->proto == COAP_PROTO_DTLS) {
3537
0
        SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
3538
0
      }
3539
0
#if !COAP_DISABLE_TCP
3540
0
      else {
3541
0
        SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
3542
0
      }
3543
0
#endif /* !COAP_DISABLE_TCP */
3544
0
      coap_log_debug("CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
3545
0
    }
3546
0
  }
3547
0
  if ((context->psk_pki_enabled & IS_PKI) ||
3548
0
      (context->psk_pki_enabled & (IS_PSK | IS_PKI)) == 0) {
3549
    /*
3550
     * If neither PSK or PKI have been set up, use PKI basics.
3551
     * This works providing COAP_PKI_KEY_PEM has a value of 0.
3552
     */
3553
0
    coap_dtls_pki_t *setup_data = &context->setup_data;
3554
3555
0
    if (!(context->psk_pki_enabled & IS_PKI)) {
3556
      /* PKI not defined - set up some defaults */
3557
0
      setup_data->verify_peer_cert        = 1;
3558
0
      setup_data->check_common_ca         = 0;
3559
0
      setup_data->allow_self_signed       = 1;
3560
0
      setup_data->allow_expired_certs     = 1;
3561
0
      setup_data->cert_chain_validation   = 1;
3562
0
      setup_data->cert_chain_verify_depth = 2;
3563
0
      setup_data->check_cert_revocation   = 1;
3564
0
      setup_data->allow_no_crl            = 1;
3565
0
      setup_data->allow_expired_crl       = 1;
3566
0
      setup_data->is_rpk_not_cert         = 0;
3567
0
      setup_data->use_cid                 = 0;
3568
0
    }
3569
0
    if (!setup_pki_ssl(ssl, setup_data, COAP_DTLS_ROLE_CLIENT))
3570
0
      return 0;
3571
    /* libcoap is managing (D)TLS connection based on setup_data options */
3572
0
#if !COAP_DISABLE_TCP
3573
0
    if (session->proto == COAP_PROTO_TLS)
3574
0
      SSL_set_alpn_protos(ssl, coap_alpn, sizeof(coap_alpn));
3575
0
#endif /* !COAP_DISABLE_TCP */
3576
3577
    /* Issue SNI if requested */
3578
0
    if (setup_data->client_sni &&
3579
0
        SSL_set_tlsext_host_name(ssl, setup_data->client_sni) != 1) {
3580
0
      coap_log_warn("SSL_set_tlsext_host_name: set '%s' failed",
3581
0
                    setup_data->client_sni);
3582
0
    }
3583
    /* Certificate Revocation */
3584
0
    if (setup_data->check_cert_revocation) {
3585
0
      X509_VERIFY_PARAM *param;
3586
3587
0
      param = X509_VERIFY_PARAM_new();
3588
0
      if (param) {
3589
0
        X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
3590
0
        SSL_set1_param(ssl, param);
3591
0
        X509_VERIFY_PARAM_free(param);
3592
0
      }
3593
0
    }
3594
3595
    /* Verify Peer */
3596
0
    if (setup_data->verify_peer_cert)
3597
0
      SSL_set_verify(ssl,
3598
0
                     SSL_VERIFY_PEER |
3599
0
                     SSL_VERIFY_CLIENT_ONCE |
3600
0
                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3601
0
                     tls_verify_call_back);
3602
0
    else
3603
0
      SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
3604
3605
    /* Check CA Chain */
3606
0
    if (setup_data->cert_chain_validation)
3607
0
      SSL_set_verify_depth(ssl, setup_data->cert_chain_verify_depth + 1);
3608
3609
0
  }
3610
#if COAP_DTLS_RETRANSMIT_MS != 1000
3611
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
3612
  if (session->proto == COAP_PROTO_DTLS) {
3613
    DTLS_set_timer_cb(ssl, timer_cb);
3614
  }
3615
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
3616
#endif /* COAP_DTLS_RETRANSMIT_MS != 1000 */
3617
0
  return 1;
3618
0
}
3619
3620
void *
3621
0
coap_dtls_new_client_session(coap_session_t *session) {
3622
0
  BIO *bio = NULL;
3623
0
  SSL *ssl = NULL;
3624
0
  coap_ssl_data *data;
3625
0
  int r;
3626
0
  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context);
3627
0
  coap_dtls_context_t *dtls = &context->dtls;
3628
3629
0
  ssl = SSL_new(dtls->ctx);
3630
0
  if (!ssl)
3631
0
    goto error;
3632
0
  bio = BIO_new(dtls->meth);
3633
0
  if (!bio)
3634
0
    goto error;
3635
0
  data = (coap_ssl_data *)BIO_get_data(bio);
3636
0
  if (!data)
3637
0
    goto error;
3638
0
  data->session = session;
3639
0
  SSL_set_bio(ssl, bio, bio);
3640
0
  SSL_set_app_data(ssl, session);
3641
0
  SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
3642
0
  SSL_set_mtu(ssl, (long)session->mtu);
3643
3644
0
  if (!setup_client_ssl_session(session, ssl))
3645
0
    goto error;
3646
3647
0
  session->dtls_timeout_count = 0;
3648
3649
0
  r = SSL_connect(ssl);
3650
0
  if (r == -1) {
3651
0
    int ret = SSL_get_error(ssl, r);
3652
0
    if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3653
0
      r = 0;
3654
0
  }
3655
3656
0
  if (r == 0)
3657
0
    goto error;
3658
3659
0
  session->tls = ssl;
3660
0
  return ssl;
3661
3662
0
error:
3663
0
  if (ssl)
3664
0
    SSL_free(ssl);
3665
0
  return NULL;
3666
0
}
3667
3668
void
3669
0
coap_dtls_session_update_mtu(coap_session_t *session) {
3670
0
  SSL *ssl = (SSL *)session->tls;
3671
0
  if (ssl)
3672
0
    SSL_set_mtu(ssl, (long)session->mtu);
3673
0
}
3674
#endif /* COAP_CLIENT_SUPPORT */
3675
3676
void
3677
0
coap_dtls_free_session(coap_session_t *session) {
3678
0
  SSL *ssl = (SSL *)session->tls;
3679
0
  if (ssl) {
3680
0
    if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3681
0
      int r = SSL_shutdown(ssl);
3682
0
      if (r == 0)
3683
0
        SSL_shutdown(ssl);
3684
0
    }
3685
0
    SSL_free(ssl);
3686
0
    session->tls = NULL;
3687
0
    if (session->context)
3688
0
      coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CLOSED, session);
3689
0
  }
3690
0
}
3691
3692
ssize_t
3693
coap_dtls_send(coap_session_t *session,
3694
0
               const uint8_t *data, size_t data_len) {
3695
0
  int r;
3696
0
  SSL *ssl = (SSL *)session->tls;
3697
3698
0
  if (ssl == NULL) {
3699
0
    session->dtls_event = COAP_EVENT_DTLS_CLOSED;
3700
0
    return -1;
3701
0
  }
3702
3703
0
  session->dtls_event = -1;
3704
0
  coap_log_debug("*  %s: dtls:  sent %4d bytes\n",
3705
0
                 coap_session_str(session), (int)data_len);
3706
0
  ERR_clear_error();
3707
0
  r = SSL_write(ssl, data, (int)data_len);
3708
3709
0
  if (r <= 0) {
3710
0
    int err = SSL_get_error(ssl, r);
3711
0
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3712
0
      r = 0;
3713
0
    } else {
3714
0
      if (err == SSL_ERROR_ZERO_RETURN)
3715
0
        session->dtls_event = COAP_EVENT_DTLS_CLOSED;
3716
0
      else if (err == SSL_ERROR_SSL) {
3717
0
        unsigned long e = ERR_get_error();
3718
3719
0
        coap_log_info("***%s: coap_dtls_send: cannot send PDU: %d: %s\n",
3720
0
                      coap_session_str(session),
3721
0
                      ERR_GET_REASON(e), ERR_reason_error_string(e));
3722
0
        session->dtls_event = COAP_EVENT_DTLS_ERROR;
3723
0
      } else {
3724
0
        coap_log_info("***%s: coap_dtls_send: cannot send PDU: %d\n",
3725
0
                      coap_session_str(session), err);
3726
0
      }
3727
0
      r = -1;
3728
0
    }
3729
0
  }
3730
3731
0
  if (session->dtls_event >= 0) {
3732
0
    coap_handle_event_lkd(session->context, session->dtls_event, session);
3733
0
    if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
3734
0
        session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
3735
0
      r = -1;
3736
0
    }
3737
0
  }
3738
3739
0
  return r;
3740
0
}
3741
3742
int
3743
0
coap_dtls_is_context_timeout(void) {
3744
0
  return 0;
3745
0
}
3746
3747
coap_tick_t
3748
0
coap_dtls_get_context_timeout(void *dtls_context) {
3749
0
  (void)dtls_context;
3750
0
  return 0;
3751
0
}
3752
3753
coap_tick_t
3754
0
coap_dtls_get_timeout(coap_session_t *session, coap_tick_t now COAP_UNUSED) {
3755
0
  SSL *ssl = (SSL *)session->tls;
3756
0
  coap_ssl_data *ssl_data;
3757
0
  BIO *rbio;
3758
3759
0
  assert(ssl != NULL && session->state == COAP_SESSION_STATE_HANDSHAKE);
3760
0
  rbio = ssl ? SSL_get_rbio(ssl) : NULL;
3761
0
  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3762
0
  return ssl_data ? ssl_data->timeout : 1000;
3763
0
}
3764
3765
/*
3766
 * return 1 timed out
3767
 *        0 still timing out
3768
 */
3769
int
3770
0
coap_dtls_handle_timeout(coap_session_t *session) {
3771
0
  SSL *ssl = (SSL *)session->tls;
3772
3773
0
  if (ssl != NULL && session->state == COAP_SESSION_STATE_HANDSHAKE) {
3774
0
    if ((++session->dtls_timeout_count > session->max_retransmit) ||
3775
0
        (DTLSv1_handle_timeout(ssl) < 0)) {
3776
      /* Too many retries */
3777
0
      coap_session_disconnected_lkd(session, COAP_NACK_TLS_FAILED);
3778
0
      return 1;
3779
0
    }
3780
0
    return 0;
3781
0
  }
3782
0
  return 1;
3783
0
}
3784
3785
#if COAP_SERVER_SUPPORT
3786
int
3787
coap_dtls_hello(coap_session_t *session,
3788
0
                const uint8_t *data, size_t data_len) {
3789
0
  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->context->dtls_context)->dtls;
3790
0
  coap_ssl_data *ssl_data;
3791
0
  int r;
3792
0
  BIO *rbio;
3793
3794
0
  SSL_set_mtu(dtls->ssl, (long)session->mtu);
3795
0
  rbio = dtls->ssl ? SSL_get_rbio(dtls->ssl) : NULL;
3796
0
  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3797
0
  assert(ssl_data != NULL);
3798
0
  if (!ssl_data) {
3799
0
    errno = ENOMEM;
3800
0
    return -1;
3801
0
  }
3802
0
  if (ssl_data->pdu_len) {
3803
0
    coap_log_err("** %s: Previous data not read %u bytes\n",
3804
0
                 coap_session_str(session), ssl_data->pdu_len);
3805
0
  }
3806
0
  ssl_data->session = session;
3807
0
  ssl_data->pdu = data;
3808
0
  ssl_data->pdu_len = (unsigned)data_len;
3809
0
  r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
3810
0
  if (r <= 0) {
3811
0
    int err = SSL_get_error(dtls->ssl, r);
3812
0
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3813
      /* Got a ClientHello, sent-out a VerifyRequest */
3814
0
      r = 0;
3815
0
    }
3816
0
  } else {
3817
    /* Got a valid answer to a VerifyRequest */
3818
0
    r = 1;
3819
0
  }
3820
3821
  /*
3822
   * Cannot check if data is left on the stack in error as DTLSv1_listen()
3823
   * only does a 'peek' read of the incoming data.
3824
   *
3825
   */
3826
0
  return r;
3827
0
}
3828
#endif /* COAP_SERVER_SUPPORT */
3829
3830
int
3831
0
coap_dtls_receive(coap_session_t *session, const uint8_t *data, size_t data_len) {
3832
0
  coap_ssl_data *ssl_data;
3833
0
  SSL *ssl = (SSL *)session->tls;
3834
0
  int r;
3835
0
  BIO *rbio;
3836
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
3837
  int retry = 0;
3838
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
3839
3840
0
  assert(ssl != NULL);
3841
3842
0
  int in_init = SSL_in_init(ssl);
3843
0
  uint8_t pdu[COAP_RXBUFFER_SIZE];
3844
0
  rbio = ssl ? SSL_get_rbio(ssl) : NULL;
3845
0
  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3846
0
  if (!ssl_data) {
3847
0
    errno = ENOTCONN;
3848
0
    return -1;
3849
0
  }
3850
3851
0
  if (ssl_data->pdu_len) {
3852
0
    coap_log_err("** %s: Previous data not read %u bytes\n",
3853
0
                 coap_session_str(session), ssl_data->pdu_len);
3854
0
  }
3855
0
  ssl_data->pdu = data;
3856
0
  ssl_data->pdu_len = (unsigned)data_len;
3857
3858
0
  session->dtls_event = -1;
3859
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
3860
retry:
3861
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
3862
0
  ERR_clear_error();
3863
0
  r = SSL_read(ssl, pdu, (int)sizeof(pdu));
3864
0
  if (r > 0) {
3865
0
    coap_log_debug("*  %s: dtls:  recv %4d bytes\n",
3866
0
                   coap_session_str(session), r);
3867
0
    r =  coap_handle_dgram(session->context, session, pdu, (size_t)r);
3868
    /* Possible there was a DTLS error */
3869
0
    ssl_data = (coap_ssl_data *)BIO_get_data(rbio);
3870
0
    goto finished;
3871
0
  } else {
3872
0
    int err = SSL_get_error(ssl, r);
3873
0
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3874
0
      if (in_init && SSL_is_init_finished(ssl)) {
3875
0
        coap_dtls_log(COAP_LOG_INFO, "*  %s: Using cipher: %s\n",
3876
0
                      coap_session_str(session), SSL_get_cipher_name(ssl));
3877
0
        coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
3878
0
        session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
3879
0
      }
3880
0
      r = 0;
3881
0
    } else {
3882
0
      if (err == SSL_ERROR_ZERO_RETURN)        /* Got a close notify alert from the remote side */
3883
0
        session->dtls_event = COAP_EVENT_DTLS_CLOSED;
3884
0
      else if (err == SSL_ERROR_SSL) {
3885
0
        unsigned long e = ERR_get_error();
3886
3887
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
3888
#include <openssl/proverr.h>
3889
        if (ERR_GET_REASON(e) == PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES && !retry) {
3890
          /* Loading trust store - first access causes a directory read error */
3891
          retry = 1;
3892
          goto retry;
3893
        }
3894
#endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
3895
0
        coap_log_info("***%s: coap_dtls_receive: cannot recv PDU: %d: %s\n",
3896
0
                      coap_session_str(session),
3897
0
                      ERR_GET_REASON(e), ERR_reason_error_string(e));
3898
0
        session->dtls_event = COAP_EVENT_DTLS_ERROR;
3899
0
      } else {
3900
0
        coap_log_info("***%s: coap_dtls_receive: cannot send PDU %d\n",
3901
0
                      coap_session_str(session), err);
3902
0
      }
3903
0
      r = -1;
3904
0
    }
3905
0
    if (session->dtls_event >= 0) {
3906
0
      coap_handle_event_lkd(session->context, session->dtls_event, session);
3907
0
      if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
3908
0
          session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
3909
        /* Cause disconnect on a read */
3910
0
        coap_session_disconnected_lkd(session, COAP_NACK_TLS_FAILED);
3911
0
        ssl_data = NULL;
3912
0
        r = -1;
3913
0
      }
3914
0
    }
3915
0
  }
3916
3917
0
finished:
3918
0
  if (ssl_data && ssl_data->pdu_len) {
3919
    /* pdu data is held on stack which will not stay there */
3920
0
    coap_log_debug("coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
3921
0
    ssl_data->pdu_len = 0;
3922
0
    ssl_data->pdu = NULL;
3923
0
  }
3924
0
  return r;
3925
0
}
3926
3927
unsigned int
3928
0
coap_dtls_get_overhead(coap_session_t *session) {
3929
0
  unsigned int overhead = 37;
3930
0
  const SSL_CIPHER *s_ciph = NULL;
3931
0
  if (session->tls != NULL)
3932
0
    s_ciph = SSL_get_current_cipher(session->tls);
3933
0
  if (s_ciph) {
3934
0
    unsigned int ivlen, maclen, blocksize = 1, pad = 0;
3935
3936
0
    const EVP_CIPHER *e_ciph;
3937
0
    const EVP_MD *e_md;
3938
0
    char cipher[128];
3939
3940
0
    e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
3941
3942
0
    switch (EVP_CIPHER_mode(e_ciph)) {
3943
0
    case EVP_CIPH_GCM_MODE:
3944
0
      ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
3945
0
      maclen = EVP_GCM_TLS_TAG_LEN;
3946
0
      break;
3947
3948
0
    case EVP_CIPH_CCM_MODE:
3949
0
      ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
3950
0
      SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher));
3951
0
      if (strstr(cipher, "CCM8"))
3952
0
        maclen = 8;
3953
0
      else
3954
0
        maclen = 16;
3955
0
      break;
3956
3957
0
    case EVP_CIPH_CBC_MODE:
3958
0
      e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
3959
0
      blocksize = EVP_CIPHER_block_size(e_ciph);
3960
0
      ivlen = EVP_CIPHER_iv_length(e_ciph);
3961
0
      pad = 1;
3962
0
      maclen = EVP_MD_size(e_md);
3963
0
      break;
3964
3965
0
    case EVP_CIPH_STREAM_CIPHER:
3966
      /* Seen with PSK-CHACHA20-POLY1305 */
3967
0
      ivlen = 8;
3968
0
      maclen = 8;
3969
0
      break;
3970
3971
0
    default:
3972
0
      SSL_CIPHER_description(s_ciph, cipher, sizeof(cipher));
3973
0
      coap_log_warn("Unknown overhead for DTLS with cipher %s\n",
3974
0
                    cipher);
3975
0
      ivlen = 8;
3976
0
      maclen = 16;
3977
0
      break;
3978
0
    }
3979
0
    overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
3980
0
  }
3981
0
  return overhead;
3982
0
}
3983
3984
#if !COAP_DISABLE_TCP
3985
#if COAP_CLIENT_SUPPORT
3986
void *
3987
0
coap_tls_new_client_session(coap_session_t *session) {
3988
0
  BIO *bio = NULL;
3989
0
  SSL *ssl = NULL;
3990
0
  int r;
3991
0
  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->context->dtls_context);
3992
0
  coap_tls_context_t *tls = &context->tls;
3993
3994
0
  ssl = SSL_new(tls->ctx);
3995
0
  if (!ssl)
3996
0
    goto error;
3997
0
  bio = BIO_new(tls->meth);
3998
0
  if (!bio)
3999
0
    goto error;
4000
0
  BIO_set_data(bio, session);
4001
0
  SSL_set_bio(ssl, bio, bio);
4002
0
  SSL_set_app_data(ssl, session);
4003
4004
0
  if (!setup_client_ssl_session(session, ssl))
4005
0
    return 0;
4006
4007
0
  r = SSL_connect(ssl);
4008
0
  if (r == -1) {
4009
0
    int ret = SSL_get_error(ssl, r);
4010
0
    if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
4011
0
      r = 0;
4012
0
    if (ret == SSL_ERROR_WANT_READ)
4013
0
      session->sock.flags |= COAP_SOCKET_WANT_READ;
4014
0
    if (ret == SSL_ERROR_WANT_WRITE) {
4015
0
      session->sock.flags |= COAP_SOCKET_WANT_WRITE;
4016
0
#ifdef COAP_EPOLL_SUPPORT
4017
0
      coap_epoll_ctl_mod(&session->sock,
4018
0
                         EPOLLOUT |
4019
0
                         ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
4020
0
                          EPOLLIN : 0),
4021
0
                         __func__);
4022
0
#endif /* COAP_EPOLL_SUPPORT */
4023
0
    }
4024
0
  }
4025
4026
0
  if (r == 0)
4027
0
    goto error;
4028
4029
0
  session->tls = ssl;
4030
0
  if (SSL_is_init_finished(ssl)) {
4031
0
    coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4032
0
    session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4033
0
  }
4034
4035
0
  return ssl;
4036
4037
0
error:
4038
0
  if (ssl)
4039
0
    SSL_free(ssl);
4040
0
  return NULL;
4041
0
}
4042
#endif /* COAP_CLIENT_SUPPORT */
4043
4044
#if COAP_SERVER_SUPPORT
4045
void *
4046
0
coap_tls_new_server_session(coap_session_t *session) {
4047
0
  BIO *bio = NULL;
4048
0
  SSL *ssl = NULL;
4049
0
  coap_tls_context_t *tls = &((coap_openssl_context_t *)session->context->dtls_context)->tls;
4050
0
  int r;
4051
0
  const coap_bin_const_t *psk_hint;
4052
4053
0
  ssl = SSL_new(tls->ctx);
4054
0
  if (!ssl)
4055
0
    goto error;
4056
0
  bio = BIO_new(tls->meth);
4057
0
  if (!bio)
4058
0
    goto error;
4059
0
  BIO_set_data(bio, session);
4060
0
  SSL_set_bio(ssl, bio, bio);
4061
0
  SSL_set_app_data(ssl, session);
4062
4063
0
  psk_hint = coap_get_session_server_psk_hint(session);
4064
0
  if (psk_hint != NULL && psk_hint->length) {
4065
0
    char *hint = OPENSSL_malloc(psk_hint->length + 1);
4066
4067
0
    if (hint) {
4068
0
      memcpy(hint, psk_hint->s, psk_hint->length);
4069
0
      hint[psk_hint->length] = '\000';
4070
0
      SSL_use_psk_identity_hint(ssl, hint);
4071
0
      OPENSSL_free(hint);
4072
0
    } else {
4073
0
      coap_log_warn("hint malloc failure\n");
4074
0
    }
4075
0
  }
4076
4077
0
  r = SSL_accept(ssl);
4078
0
  if (r == -1) {
4079
0
    int err = SSL_get_error(ssl, r);
4080
0
    if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
4081
0
      r = 0;
4082
0
    if (err == SSL_ERROR_WANT_READ)
4083
0
      session->sock.flags |= COAP_SOCKET_WANT_READ;
4084
0
    if (err == SSL_ERROR_WANT_WRITE) {
4085
0
      session->sock.flags |= COAP_SOCKET_WANT_WRITE;
4086
0
#ifdef COAP_EPOLL_SUPPORT
4087
0
      coap_epoll_ctl_mod(&session->sock,
4088
0
                         EPOLLOUT |
4089
0
                         ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
4090
0
                          EPOLLIN : 0),
4091
0
                         __func__);
4092
0
#endif /* COAP_EPOLL_SUPPORT */
4093
0
    }
4094
0
  }
4095
4096
0
  if (r == 0)
4097
0
    goto error;
4098
4099
0
  session->tls = ssl;
4100
0
  if (SSL_is_init_finished(ssl)) {
4101
0
    coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4102
0
    session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4103
0
  }
4104
4105
#if COAP_DTLS_RETRANSMIT_MS != 1000
4106
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
4107
  if (session->proto == COAP_PROTO_DTLS) {
4108
    DTLS_set_timer_cb(ssl, timer_cb);
4109
  }
4110
#endif /* OPENSSL_VERSION_NUMBER >= 0x10101000L */
4111
#endif /* COAP_DTLS_RETRANSMIT_MS != 1000 */
4112
4113
0
  return ssl;
4114
4115
0
error:
4116
0
  if (ssl)
4117
0
    SSL_free(ssl);
4118
0
  return NULL;
4119
0
}
4120
#endif /* COAP_SERVER_SUPPORT */
4121
4122
void
4123
0
coap_tls_free_session(coap_session_t *session) {
4124
0
  SSL *ssl = (SSL *)session->tls;
4125
0
  if (ssl) {
4126
0
    if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
4127
0
      int r = SSL_shutdown(ssl);
4128
0
      if (r == 0)
4129
0
        SSL_shutdown(ssl);
4130
0
    }
4131
0
    SSL_free(ssl);
4132
0
    session->tls = NULL;
4133
0
    if (session->context)
4134
0
      coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CLOSED, session);
4135
0
  }
4136
0
}
4137
4138
/*
4139
 * strm
4140
 * return +ve Number of bytes written.
4141
 *         -1 Error (error in errno).
4142
 */
4143
ssize_t
4144
0
coap_tls_write(coap_session_t *session, const uint8_t *data, size_t data_len) {
4145
0
  SSL *ssl = (SSL *)session->tls;
4146
0
  int r, in_init;
4147
4148
0
  if (ssl == NULL)
4149
0
    return -1;
4150
4151
0
  in_init = !SSL_is_init_finished(ssl);
4152
0
  session->dtls_event = -1;
4153
0
  ERR_clear_error();
4154
0
  r = SSL_write(ssl, data, (int)data_len);
4155
4156
0
  if (r <= 0) {
4157
0
    int err = SSL_get_error(ssl, r);
4158
0
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
4159
0
      if (in_init && SSL_is_init_finished(ssl)) {
4160
0
        coap_dtls_log(COAP_LOG_INFO, "*  %s: Using cipher: %s\n",
4161
0
                      coap_session_str(session), SSL_get_cipher_name(ssl));
4162
0
        coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4163
0
        session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4164
0
      }
4165
0
      if (err == SSL_ERROR_WANT_READ)
4166
0
        session->sock.flags |= COAP_SOCKET_WANT_READ;
4167
0
      else if (err == SSL_ERROR_WANT_WRITE) {
4168
0
        session->sock.flags |= COAP_SOCKET_WANT_WRITE;
4169
0
#ifdef COAP_EPOLL_SUPPORT
4170
0
        coap_epoll_ctl_mod(&session->sock,
4171
0
                           EPOLLOUT |
4172
0
                           ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
4173
0
                            EPOLLIN : 0),
4174
0
                           __func__);
4175
0
#endif /* COAP_EPOLL_SUPPORT */
4176
0
      }
4177
0
      r = 0;
4178
0
    } else {
4179
0
      if (err == SSL_ERROR_ZERO_RETURN)
4180
0
        session->dtls_event = COAP_EVENT_DTLS_CLOSED;
4181
0
      else if (err == SSL_ERROR_SSL) {
4182
0
        unsigned long e = ERR_get_error();
4183
4184
0
        coap_log_info("***%s: coap_tls_write: cannot send PDU: %d: %s\n",
4185
0
                      coap_session_str(session),
4186
0
                      ERR_GET_REASON(e), ERR_reason_error_string(e));
4187
0
        session->dtls_event = COAP_EVENT_DTLS_ERROR;
4188
0
      } else {
4189
0
        coap_log_info("***%s: coap_tls_send: cannot send PDU: %d\n",
4190
0
                      coap_session_str(session), err);
4191
0
      }
4192
0
      r = -1;
4193
0
    }
4194
0
  } else if (in_init && SSL_is_init_finished(ssl)) {
4195
0
    coap_dtls_log(COAP_LOG_INFO, "*  %s: Using cipher: %s\n",
4196
0
                  coap_session_str(session), SSL_get_cipher_name(ssl));
4197
0
    coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4198
0
    session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4199
0
  }
4200
4201
0
  if (session->dtls_event >= 0) {
4202
0
    coap_handle_event_lkd(session->context, session->dtls_event, session);
4203
0
    if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
4204
0
        session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
4205
0
      r = -1;
4206
0
    }
4207
0
  }
4208
4209
0
  if (r >= 0) {
4210
0
    if (r == (ssize_t)data_len)
4211
0
      coap_log_debug("*  %s: tls:   sent %4d bytes\n",
4212
0
                     coap_session_str(session), r);
4213
0
    else
4214
0
      coap_log_debug("*  %s: tls:   sent %4d of %4" PRIdS " bytes\n",
4215
0
                     coap_session_str(session), r, data_len);
4216
0
  }
4217
0
  return r;
4218
0
}
4219
4220
/*
4221
 * strm
4222
 * return >=0 Number of bytes read.
4223
 *         -1 Error (error in errno).
4224
 */
4225
ssize_t
4226
0
coap_tls_read(coap_session_t *session, uint8_t *data, size_t data_len) {
4227
0
  SSL *ssl = (SSL *)session->tls;
4228
0
  int r, in_init;
4229
4230
0
  if (ssl == NULL) {
4231
0
    errno = ENXIO;
4232
0
    return -1;
4233
0
  }
4234
4235
0
  in_init = !SSL_is_init_finished(ssl);
4236
0
  session->dtls_event = -1;
4237
0
  ERR_clear_error();
4238
0
  r = SSL_read(ssl, data, (int)data_len);
4239
0
  if (r <= 0) {
4240
0
    int err = SSL_get_error(ssl, r);
4241
0
    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
4242
0
      if (in_init && SSL_is_init_finished(ssl)) {
4243
0
        coap_dtls_log(COAP_LOG_INFO, "*  %s: Using cipher: %s\n",
4244
0
                      coap_session_str(session), SSL_get_cipher_name(ssl));
4245
0
        coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4246
0
        session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4247
0
      }
4248
0
      if (err == SSL_ERROR_WANT_READ)
4249
0
        session->sock.flags |= COAP_SOCKET_WANT_READ;
4250
0
      if (err == SSL_ERROR_WANT_WRITE) {
4251
0
        session->sock.flags |= COAP_SOCKET_WANT_WRITE;
4252
0
#ifdef COAP_EPOLL_SUPPORT
4253
0
        coap_epoll_ctl_mod(&session->sock,
4254
0
                           EPOLLOUT |
4255
0
                           ((session->sock.flags & COAP_SOCKET_WANT_READ) ?
4256
0
                            EPOLLIN : 0),
4257
0
                           __func__);
4258
0
#endif /* COAP_EPOLL_SUPPORT */
4259
0
      }
4260
0
      r = 0;
4261
0
    } else {
4262
0
      if (err == SSL_ERROR_ZERO_RETURN)        /* Got a close notify alert from the remote side */
4263
0
        session->dtls_event = COAP_EVENT_DTLS_CLOSED;
4264
0
      else if (err == SSL_ERROR_SSL) {
4265
0
        unsigned long e = ERR_get_error();
4266
4267
0
        coap_log_info("***%s: coap_tls_read: cannot recv PDU: %d: %s\n",
4268
0
                      coap_session_str(session),
4269
0
                      ERR_GET_REASON(e), ERR_reason_error_string(e));
4270
0
        session->dtls_event = COAP_EVENT_DTLS_ERROR;
4271
0
      } else {
4272
0
        coap_log_info("***%s: coap_tls_read: cannot read PDU %d\n",
4273
0
                      coap_session_str(session), err);
4274
0
      }
4275
0
      r = -1;
4276
0
    }
4277
0
  } else if (in_init && SSL_is_init_finished(ssl)) {
4278
0
    coap_dtls_log(COAP_LOG_INFO, "*  %s: Using cipher: %s\n",
4279
0
                  coap_session_str(session), SSL_get_cipher_name(ssl));
4280
0
    coap_handle_event_lkd(session->context, COAP_EVENT_DTLS_CONNECTED, session);
4281
0
    session->sock.lfunc[COAP_LAYER_TLS].l_establish(session);
4282
0
  }
4283
4284
0
  if (session->dtls_event >= 0) {
4285
0
    coap_handle_event_lkd(session->context, session->dtls_event, session);
4286
0
    if (session->dtls_event == COAP_EVENT_DTLS_ERROR ||
4287
0
        session->dtls_event == COAP_EVENT_DTLS_CLOSED) {
4288
      /* Cause disconnect on a read */
4289
0
      coap_session_disconnected_lkd(session, COAP_NACK_TLS_FAILED);
4290
0
      r = -1;
4291
0
    }
4292
0
  }
4293
4294
0
  if (r > 0) {
4295
0
    coap_log_debug("*  %s: tls:   recv %4d bytes\n",
4296
0
                   coap_session_str(session), r);
4297
0
  }
4298
0
  return r;
4299
0
}
4300
#endif /* !COAP_DISABLE_TCP */
4301
4302
#if COAP_SERVER_SUPPORT
4303
coap_digest_ctx_t *
4304
0
coap_digest_setup(void) {
4305
0
  EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new();
4306
4307
0
  if (digest_ctx) {
4308
0
    EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL);
4309
0
  }
4310
0
  return digest_ctx;
4311
0
}
4312
4313
void
4314
0
coap_digest_free(coap_digest_ctx_t *digest_ctx) {
4315
0
  if (digest_ctx)
4316
0
    EVP_MD_CTX_free(digest_ctx);
4317
0
}
4318
4319
int
4320
coap_digest_update(coap_digest_ctx_t *digest_ctx,
4321
                   const uint8_t *data,
4322
0
                   size_t data_len) {
4323
0
  return EVP_DigestUpdate(digest_ctx, data, data_len);
4324
0
}
4325
4326
int
4327
coap_digest_final(coap_digest_ctx_t *digest_ctx,
4328
0
                  coap_digest_t *digest_buffer) {
4329
0
  unsigned int size = sizeof(coap_digest_t);
4330
0
  int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
4331
4332
0
  coap_digest_free(digest_ctx);
4333
0
  return ret;
4334
0
}
4335
#endif /* COAP_SERVER_SUPPORT */
4336
4337
#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT
4338
static void
4339
0
coap_crypto_output_errors(const char *prefix) {
4340
#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN
4341
  (void)prefix;
4342
#else /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_WARN */
4343
0
  unsigned long e;
4344
4345
0
  while ((e = ERR_get_error()))
4346
0
    coap_log_warn("%s: %s%s\n",
4347
0
                  prefix,
4348
0
                  ERR_reason_error_string(e),
4349
0
                  ssl_function_definition(e));
4350
0
#endif /* COAP_MAX_LOGGING_LEVEL >= _COAP_LOG_WARN */
4351
0
}
4352
#endif /* COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT */
4353
4354
#if COAP_WS_SUPPORT
4355
/*
4356
 * The struct hash_algs and the function get_hash_alg() are used to
4357
 * determine which hash type to use for creating the required hash object.
4358
 */
4359
static struct hash_algs {
4360
  cose_alg_t alg;
4361
  const EVP_MD *(*get_hash)(void);
4362
  size_t length; /* in bytes */
4363
} hashs[] = {
4364
  {COSE_ALGORITHM_SHA_1, EVP_sha1, 20},
4365
  {COSE_ALGORITHM_SHA_256_64, EVP_sha256, 8},
4366
  {COSE_ALGORITHM_SHA_256_256, EVP_sha256, 32},
4367
  {COSE_ALGORITHM_SHA_512, EVP_sha512, 64},
4368
};
4369
4370
static const EVP_MD *
4371
0
get_hash_alg(cose_alg_t alg, size_t *length) {
4372
0
  size_t idx;
4373
4374
0
  for (idx = 0; idx < sizeof(hashs) / sizeof(struct hash_algs); idx++) {
4375
0
    if (hashs[idx].alg == alg) {
4376
0
      *length = hashs[idx].length;
4377
0
      return hashs[idx].get_hash();
4378
0
    }
4379
0
  }
4380
0
  coap_log_debug("get_hash_alg: COSE hash %d not supported\n", alg);
4381
0
  return NULL;
4382
0
}
4383
4384
int
4385
coap_crypto_hash(cose_alg_t alg,
4386
                 const coap_bin_const_t *data,
4387
0
                 coap_bin_const_t **hash) {
4388
0
  unsigned int length;
4389
0
  const EVP_MD *evp_md;
4390
0
  EVP_MD_CTX *evp_ctx = NULL;
4391
0
  coap_binary_t *dummy = NULL;
4392
0
  size_t hash_length;
4393
4394
0
  if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) {
4395
0
    coap_log_debug("coap_crypto_hash: algorithm %d not supported\n", alg);
4396
0
    return 0;
4397
0
  }
4398
0
  evp_ctx = EVP_MD_CTX_new();
4399
0
  if (evp_ctx == NULL)
4400
0
    goto error;
4401
0
  if (EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0)
4402
0
    goto error;
4403
0
  ;
4404
0
  if (EVP_DigestUpdate(evp_ctx, data->s, data->length) == 0)
4405
0
    goto error;
4406
0
  ;
4407
0
  dummy = coap_new_binary(EVP_MAX_MD_SIZE);
4408
0
  if (dummy == NULL)
4409
0
    goto error;
4410
0
  if (EVP_DigestFinal_ex(evp_ctx, dummy->s, &length) == 0)
4411
0
    goto error;
4412
0
  dummy->length = length;
4413
0
  if (hash_length < dummy->length)
4414
0
    dummy->length = hash_length;
4415
0
  *hash = (coap_bin_const_t *)(dummy);
4416
0
  EVP_MD_CTX_free(evp_ctx);
4417
0
  return 1;
4418
4419
0
error:
4420
0
  coap_crypto_output_errors("coap_crypto_hash");
4421
0
  coap_delete_binary(dummy);
4422
0
  if (evp_ctx)
4423
0
    EVP_MD_CTX_free(evp_ctx);
4424
0
  return 0;
4425
0
}
4426
#endif /* COAP_WS_SUPPORT */
4427
4428
#if COAP_OSCORE_SUPPORT
4429
int
4430
0
coap_oscore_is_supported(void) {
4431
0
  return 1;
4432
0
}
4433
4434
#include <openssl/evp.h>
4435
#include <openssl/hmac.h>
4436
4437
/*
4438
 * The struct cipher_algs and the function get_cipher_alg() are used to
4439
 * determine which cipher type to use for creating the required cipher
4440
 * suite object.
4441
 */
4442
static struct cipher_algs {
4443
  cose_alg_t alg;
4444
  const EVP_CIPHER *(*get_cipher)(void);
4445
} ciphers[] = {{COSE_ALGORITHM_AES_CCM_16_64_128, EVP_aes_128_ccm},
4446
  {COSE_ALGORITHM_AES_CCM_16_64_256, EVP_aes_256_ccm}
4447
};
4448
4449
static const EVP_CIPHER *
4450
0
get_cipher_alg(cose_alg_t alg) {
4451
0
  size_t idx;
4452
4453
0
  for (idx = 0; idx < sizeof(ciphers) / sizeof(struct cipher_algs); idx++) {
4454
0
    if (ciphers[idx].alg == alg)
4455
0
      return ciphers[idx].get_cipher();
4456
0
  }
4457
0
  coap_log_debug("get_cipher_alg: COSE cipher %d not supported\n", alg);
4458
0
  return NULL;
4459
0
}
4460
4461
/*
4462
 * The struct hmac_algs and the function get_hmac_alg() are used to
4463
 * determine which hmac type to use for creating the required hmac
4464
 * suite object.
4465
 */
4466
static struct hmac_algs {
4467
  cose_hmac_alg_t hmac_alg;
4468
  const EVP_MD *(*get_hmac)(void);
4469
} hmacs[] = {
4470
  {COSE_HMAC_ALG_HMAC256_256, EVP_sha256},
4471
  {COSE_HMAC_ALG_HMAC384_384, EVP_sha384},
4472
  {COSE_HMAC_ALG_HMAC512_512, EVP_sha512},
4473
};
4474
4475
static const EVP_MD *
4476
0
get_hmac_alg(cose_hmac_alg_t hmac_alg) {
4477
0
  size_t idx;
4478
4479
0
  for (idx = 0; idx < sizeof(hmacs) / sizeof(struct hmac_algs); idx++) {
4480
0
    if (hmacs[idx].hmac_alg == hmac_alg)
4481
0
      return hmacs[idx].get_hmac();
4482
0
  }
4483
0
  coap_log_debug("get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
4484
0
  return NULL;
4485
0
}
4486
4487
int
4488
0
coap_crypto_check_cipher_alg(cose_alg_t alg) {
4489
0
  return get_cipher_alg(alg) != NULL;
4490
0
}
4491
4492
int
4493
0
coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg) {
4494
0
  cose_hmac_alg_t hmac_alg;
4495
4496
0
  if (!cose_get_hmac_alg_for_hkdf(hkdf_alg, &hmac_alg))
4497
0
    return 0;
4498
0
  return get_hmac_alg(hmac_alg) != NULL;
4499
0
}
4500
4501
#define C(Func)                                                                \
4502
0
  if (1 != (Func)) {                                                           \
4503
0
    goto error;                                                                \
4504
0
  }
4505
4506
int
4507
coap_crypto_aead_encrypt(const coap_crypto_param_t *params,
4508
                         coap_bin_const_t *data,
4509
                         coap_bin_const_t *aad,
4510
                         uint8_t *result,
4511
0
                         size_t *max_result_len) {
4512
0
  const EVP_CIPHER *cipher;
4513
0
  const coap_crypto_aes_ccm_t *ccm;
4514
0
  int tmp;
4515
0
  int result_len = (int)(*max_result_len & INT_MAX);
4516
0
  EVP_CIPHER_CTX *ctx;
4517
4518
0
  if (data == NULL)
4519
0
    return 0;
4520
4521
0
  assert(params != NULL);
4522
0
  if (!params || ((cipher = get_cipher_alg(params->alg)) == NULL)) {
4523
0
    return 0;
4524
0
  }
4525
4526
  /* TODO: set evp_md depending on params->alg */
4527
0
  ccm = &params->params.aes;
4528
4529
0
  ctx = EVP_CIPHER_CTX_new();
4530
0
  if (!ctx)
4531
0
    return 0;
4532
4533
  /* EVP_CIPHER_CTX_init(ctx); */
4534
0
  C(EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL));
4535
0
  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (int)ccm->l, NULL));
4536
0
  C(EVP_CIPHER_CTX_ctrl(ctx,
4537
0
                        EVP_CTRL_AEAD_SET_IVLEN,
4538
0
                        (int)(15 - ccm->l),
4539
0
                        NULL));
4540
0
  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ccm->tag_len, NULL));
4541
0
  C(EVP_EncryptInit_ex(ctx, NULL, NULL, ccm->key.s, ccm->nonce));
4542
  /* C(EVP_CIPHER_CTX_set_padding(ctx, 0)); */
4543
4544
0
  C(EVP_EncryptUpdate(ctx, NULL, &result_len, NULL, (int)data->length));
4545
0
  if (aad && aad->s && (aad->length > 0)) {
4546
0
    C(EVP_EncryptUpdate(ctx, NULL, &result_len, aad->s, (int)aad->length));
4547
0
  }
4548
0
  C(EVP_EncryptUpdate(ctx, result, &result_len, data->s, (int)data->length));
4549
  /* C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp)); */
4550
0
  tmp = result_len;
4551
0
  C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp));
4552
0
  result_len += tmp;
4553
4554
  /* retrieve the tag */
4555
0
  C(EVP_CIPHER_CTX_ctrl(ctx,
4556
0
                        EVP_CTRL_CCM_GET_TAG,
4557
0
                        (int)ccm->tag_len,
4558
0
                        result + result_len));
4559
4560
0
  *max_result_len = result_len + ccm->tag_len;
4561
0
  EVP_CIPHER_CTX_free(ctx);
4562
0
  return 1;
4563
4564
0
error:
4565
0
  coap_crypto_output_errors("coap_crypto_aead_encrypt");
4566
0
  return 0;
4567
0
}
4568
4569
int
4570
coap_crypto_aead_decrypt(const coap_crypto_param_t *params,
4571
                         coap_bin_const_t *data,
4572
                         coap_bin_const_t *aad,
4573
                         uint8_t *result,
4574
0
                         size_t *max_result_len) {
4575
0
  const EVP_CIPHER *cipher;
4576
0
  const coap_crypto_aes_ccm_t *ccm;
4577
0
  int tmp;
4578
0
  int len;
4579
0
  const uint8_t *tag;
4580
0
  uint8_t *rwtag;
4581
0
  EVP_CIPHER_CTX *ctx;
4582
4583
0
  if (data == NULL)
4584
0
    return 0;
4585
4586
0
  assert(params != NULL);
4587
0
  if (!params || ((cipher = get_cipher_alg(params->alg)) == NULL)) {
4588
0
    return 0;
4589
0
  }
4590
4591
0
  ccm = &params->params.aes;
4592
4593
0
  if (data->length < ccm->tag_len) {
4594
0
    return 0;
4595
0
  } else {
4596
0
    tag = data->s + data->length - ccm->tag_len;
4597
0
    data->length -= ccm->tag_len;
4598
    /* Kludge to stop compiler warning */
4599
0
    memcpy(&rwtag, &tag, sizeof(rwtag));
4600
0
  }
4601
4602
0
  ctx = EVP_CIPHER_CTX_new();
4603
0
  if (!ctx)
4604
0
    return 0;
4605
4606
0
  C(EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL));
4607
0
  C(EVP_CIPHER_CTX_ctrl(ctx,
4608
0
                        EVP_CTRL_AEAD_SET_IVLEN,
4609
0
                        (int)(15 - ccm->l),
4610
0
                        NULL));
4611
0
  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)ccm->tag_len, rwtag));
4612
0
  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (int)ccm->l, NULL));
4613
  /* C(EVP_CIPHER_CTX_set_padding(ctx, 0)); */
4614
0
  C(EVP_DecryptInit_ex(ctx, NULL, NULL, ccm->key.s, ccm->nonce));
4615
4616
0
  C(EVP_DecryptUpdate(ctx, NULL, &len, NULL, (int)data->length));
4617
0
  if (aad && aad->s && (aad->length > 0)) {
4618
0
    C(EVP_DecryptUpdate(ctx, NULL, &len, aad->s, (int)aad->length));
4619
0
  }
4620
0
  tmp = EVP_DecryptUpdate(ctx, result, &len, data->s, (int)data->length);
4621
0
  EVP_CIPHER_CTX_free(ctx);
4622
0
  if (tmp <= 0) {
4623
0
    *max_result_len = 0;
4624
0
    return 0;
4625
0
  }
4626
0
  *max_result_len = len;
4627
0
  return 1;
4628
4629
0
error:
4630
0
  coap_crypto_output_errors("coap_crypto_aead_decrypt");
4631
0
  return 0;
4632
0
}
4633
4634
int
4635
coap_crypto_hmac(cose_hmac_alg_t hmac_alg,
4636
                 coap_bin_const_t *key,
4637
                 coap_bin_const_t *data,
4638
0
                 coap_bin_const_t **hmac) {
4639
0
  unsigned int result_len;
4640
0
  const EVP_MD *evp_md;
4641
0
  coap_binary_t *dummy = NULL;
4642
4643
0
  assert(key);
4644
0
  assert(data);
4645
0
  assert(hmac);
4646
4647
0
  if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
4648
0
    coap_log_debug("coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
4649
0
    return 0;
4650
0
  }
4651
0
  dummy = coap_new_binary(EVP_MAX_MD_SIZE);
4652
0
  if (dummy == NULL)
4653
0
    return 0;
4654
0
  result_len = (unsigned int)dummy->length;
4655
0
  if (HMAC(evp_md,
4656
0
           key->s,
4657
0
           (int)key->length,
4658
0
           data->s,
4659
0
           (int)data->length,
4660
0
           dummy->s,
4661
0
           &result_len)) {
4662
0
    dummy->length = result_len;
4663
0
    *hmac = (coap_bin_const_t *)dummy;
4664
0
    return 1;
4665
0
  }
4666
4667
0
  coap_delete_binary(dummy);
4668
0
  coap_crypto_output_errors("coap_crypto_hmac");
4669
0
  return 0;
4670
0
}
4671
4672
#endif /* COAP_OSCORE_SUPPORT */
4673
4674
#else /* ! COAP_WITH_LIBOPENSSL */
4675
4676
#ifdef __clang__
4677
/* Make compilers happy that do not like empty modules. As this function is
4678
 * never used, we ignore -Wunused-function at the end of compiling this file
4679
 */
4680
#pragma GCC diagnostic ignored "-Wunused-function"
4681
#endif
4682
static inline void
4683
dummy(void) {
4684
}
4685
4686
#endif /* ! COAP_WITH_LIBOPENSSL */