Coverage Report

Created: 2026-09-28 06:37

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