20#if COAP_WITH_LIBOPENSSL 
   71#include <openssl/ssl.h> 
   72#include <openssl/engine.h> 
   73#include <openssl/err.h> 
   74#include <openssl/rand.h> 
   75#include <openssl/hmac.h> 
   76#include <openssl/x509v3.h> 
   78#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
   81#pragma GCC diagnostic ignored "-Wdeprecated-declarations" 
   84#if !defined(__MINGW32__) 
   85#pragma warning(disable : 4996) 
   90#ifdef COAP_EPOLL_SUPPORT 
   91# include <sys/epoll.h> 
   94#if OPENSSL_VERSION_NUMBER < 0x10100000L 
   95#error Must be compiled against OpenSSL 1.1.0 or later 
   99#define strcasecmp _stricmp 
  100#define strncasecmp _strnicmp 
  104#ifndef TLSEXT_TYPE_client_certificate_type 
  105#define TLSEXT_TYPE_client_certificate_type 19 
  107#ifndef TLSEXT_TYPE_server_certificate_type 
  108#define TLSEXT_TYPE_server_certificate_type 20 
  111#ifndef COAP_OPENSSL_CIPHERS 
  112#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
  113#define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL" 
  115#define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL" 
  119#ifndef COAP_OPENSSL_PSK_CIPHERS 
  120#define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL" 
  123#ifndef COAP_OPENSSL_PKCS11_ENGINE_ID 
  124#define COAP_OPENSSL_PKCS11_ENGINE_ID "pkcs11" 
  128typedef struct coap_dtls_context_t {
 
  131  HMAC_CTX *cookie_hmac;
 
  134} coap_dtls_context_t;
 
  136typedef struct coap_tls_context_t {
 
  144typedef struct sni_entry {
 
  146#if OPENSSL_VERSION_NUMBER < 0x10101000L 
  153typedef struct psk_sni_entry {
 
  155#if OPENSSL_VERSION_NUMBER < 0x10101000L 
  161typedef struct coap_openssl_context_t {
 
  162  coap_dtls_context_t dtls;
 
  164  coap_tls_context_t tls;
 
  169  sni_entry *sni_entry_list;
 
  170#if OPENSSL_VERSION_NUMBER < 0x10101000L 
  171  size_t psk_sni_count;
 
  172  psk_sni_entry *psk_sni_entry_list;
 
  174} coap_openssl_context_t;
 
  176#if COAP_SERVER_SUPPORT 
  177#if OPENSSL_VERSION_NUMBER < 0x10101000L 
  178static int psk_tls_server_name_call_back(SSL *ssl, 
int *sd, 
void *arg);
 
  180static int psk_tls_client_hello_call_back(SSL *ssl, 
int *al, 
void *arg);
 
  186  if (SSLeay() < 0x10100000L) {
 
  187    coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
 
  190#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
  198  if (SSLeay() < 0x10101000L) {
 
  199    coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
 
  209  if (SSLeay() < 0x10100000L) {
 
  210    coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
 
  213#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
  214  if (SSLeay() < 0x10101000L) {
 
  215    coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
 
  270#if COAP_CLIENT_SUPPORT 
  288static ENGINE *pkcs11_engine = NULL;
 
  289static ENGINE *defined_engine = NULL;
 
  293  SSL_load_error_strings();
 
  295  ENGINE_load_dynamic();
 
  302    ENGINE_finish(pkcs11_engine);
 
  303    pkcs11_engine = NULL;
 
  305  if (defined_engine) {
 
  307    ENGINE_finish(defined_engine);
 
  308    defined_engine = NULL;
 
  320    return c_session->
tls;
 
  326get_split_conf_entry(
const uint8_t **start, 
size_t size, 
const char *get_keyword,
 
  328  const uint8_t *begin = *start;
 
  331  const uint8_t *split;
 
  337  kend = end = memchr(begin, 
'\n', size);
 
  343  if (end > begin && end[-1] == 
'\r')
 
  346  if (begin[0] == 
'#' || (end - begin) == 0) {
 
  348    size -= kend - begin + 1;
 
  354  split = memchr(begin, 
':', end - begin);
 
  358  if ((
size_t)(split - begin) != strlen(get_keyword)) {
 
  359    size -= kend - begin + 1;
 
  363  if (memcmp(begin, get_keyword, split - begin)) {
 
  364    size -= kend - begin + 1;
 
  372  if ((end - begin) == 0)
 
  375  split = memchr(begin, 
':', end - begin);
 
  387    if ((end - split) > 0) {
 
  422  const uint8_t *start;
 
  427  unsigned int defaults = 0;
 
  428  int done_engine_id = 0;
 
  429  int done_engine_init = 0;
 
  435  end = start + conf_mem->
length;
 
  437  if (defined_engine) {
 
  438    coap_log_warn(
"coap_tls_engine_configure: Freeing off previous engine definition\n");
 
  439    ENGINE_finish(defined_engine);
 
  440    defined_engine = NULL;
 
  444  if (!get_split_conf_entry(&start, end - start, 
"engine", &engine_id, &p2)) {
 
  445    coap_log_warn(
"coap_tls_engine_configure: engine not defined\n");
 
  448  defined_engine = ENGINE_by_id((
const char *)engine_id->
s);
 
  449  if (!defined_engine) {
 
  450    coap_log_warn(
"coap_tls_engine_configure: engine '%s' not known\n", engine_id->
s);
 
  460  while (get_split_conf_entry(&start, end - start, 
"pre-cmd", &p1, &p2)) {
 
  461    if (!ENGINE_ctrl_cmd_string(defined_engine, (
const char *)p1->
s, p2 ? (
const char *)p2->
s : NULL,
 
  463      coap_log_warn(
"coap_tls_engine_configure: engine %s pre-cmd '%s:%s' failed\n",
 
  464                    (
const char *)engine_id->
s,
 
  465                    (
const char *)p1->
s, p2 ? (
const char *)p2->
s : 
"(NULL)");
 
  469                    engine_id->
s, p1->
s, p2 ? (
const char *)p2->
s : 
"(NULL)");
 
  478  if (!ENGINE_init(defined_engine)) {
 
  479    coap_log_warn(
"coap_tls_engine_configure: %s failed initialization\n", (
const char *)engine_id->
s);
 
  482    done_engine_init = 1;
 
  484                  (
const char *)engine_id->
s);
 
  489  while (get_split_conf_entry(&start, end - start, 
"post-cmd", &p1, &p2)) {
 
  490    if (!ENGINE_ctrl_cmd_string(defined_engine, (
const char *)p1->
s, p2 ? (
const char *)p2->
s : NULL,
 
  492      coap_log_warn(
"coap_tls_engine_configure: %s post-cmd '%s:%s' failed\n", (
const char *)engine_id->
s,
 
  493                    (
const char *)p1->
s, p2 ? (
const char *)p2->
s : 
"(NULL)");
 
  497                    (
const char *)engine_id->
s,
 
  498                    (
const char *)p1->
s, p2 ? (
const char *)p2->
s : 
"(NULL)");
 
  506  if (!get_split_conf_entry(&start, end - start, 
"enable-methods", &p1, &p2)) {
 
  507    coap_log_warn(
"coap_tls_engine_configure: enable-methods not found\n");
 
  510  defaults = strtoul((
const char *)p1->
s, NULL, 0);
 
  511  if (!ENGINE_set_default(defined_engine, defaults)) {
 
  512    coap_log_warn(
"coap_tls_engine_configure: enable-methods 0x%x invalid\n", defaults);
 
  527    ENGINE_free(defined_engine);
 
  528  if (done_engine_init)
 
  529    ENGINE_finish(defined_engine);
 
  530  defined_engine = NULL;
 
  539  if (defined_engine) {
 
  540    ENGINE_finish(defined_engine);
 
  541    defined_engine = NULL;
 
  562typedef struct coap_ssl_data {
 
  571coap_dgram_create(BIO *a) {
 
  572  coap_ssl_data *data = NULL;
 
  573  data = malloc(
sizeof(coap_ssl_data));
 
  577  BIO_set_data(a, data);
 
  578  memset(data, 0x00, 
sizeof(coap_ssl_data));
 
  583coap_dgram_destroy(BIO *a) {
 
  587  data = (coap_ssl_data *)BIO_get_data(a);
 
  594coap_dgram_read(BIO *a, 
char *out, 
int outl) {
 
  596  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
 
  599    if (data != NULL && data->pdu_len > 0) {
 
  600      if (outl < (
int)data->pdu_len) {
 
  601        memcpy(out, data->pdu, outl);
 
  604        memcpy(out, data->pdu, data->pdu_len);
 
  605        ret = (int)data->pdu_len;
 
  607      if (!data->peekmode) {
 
  614    BIO_clear_retry_flags(a);
 
  616      BIO_set_retry_read(a);
 
  622coap_dgram_write(BIO *a, 
const char *in, 
int inl) {
 
  624  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
 
  626  if (data && data->session) {
 
  628#if COAP_SERVER_SUPPORT 
  629        && data->session->endpoint == NULL
 
  633      BIO_clear_retry_flags(a);
 
  637    ret = (int)data->session->sock.lfunc[
COAP_LAYER_TLS].l_write(data->session,
 
  640    BIO_clear_retry_flags(a);
 
  642      if (ret < 0 && (errno == ENOTCONN || errno == ECONNREFUSED))
 
  644      BIO_set_retry_write(a);
 
  647    BIO_clear_retry_flags(a);
 
  654coap_dgram_puts(BIO *a, 
const char *pstr) {
 
  655  return coap_dgram_write(a, pstr, (
int)strlen(pstr));
 
  659coap_dgram_ctrl(BIO *a, 
int cmd, 
long num, 
void *ptr) {
 
  661  coap_ssl_data *data = BIO_get_data(a);
 
  666  case BIO_CTRL_GET_CLOSE:
 
  667    ret = BIO_get_shutdown(a);
 
  669  case BIO_CTRL_SET_CLOSE:
 
  670    BIO_set_shutdown(a, (
int)num);
 
  672  case BIO_CTRL_DGRAM_SET_PEEK_MODE:
 
  674      data->peekmode = (unsigned)num;
 
  678  case BIO_CTRL_DGRAM_CONNECT:
 
  681  case BIO_CTRL_DGRAM_SET_DONT_FRAG:
 
  682  case BIO_CTRL_DGRAM_GET_MTU:
 
  683  case BIO_CTRL_DGRAM_SET_MTU:
 
  684  case BIO_CTRL_DGRAM_QUERY_MTU:
 
  685  case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
 
  690  case BIO_CTRL_DGRAM_MTU_DISCOVER:
 
  691  case BIO_CTRL_DGRAM_SET_CONNECTED:
 
  693  case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
 
  696                                            ((
struct timeval *)ptr)->tv_usec);
 
  701  case BIO_C_FILE_SEEK:
 
  702  case BIO_C_FILE_TELL:
 
  704  case BIO_CTRL_PENDING:
 
  705  case BIO_CTRL_WPENDING:
 
  706  case BIO_CTRL_DGRAM_GET_PEER:
 
  707  case BIO_CTRL_DGRAM_SET_PEER:
 
  708  case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
 
  709  case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
 
  710  case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
 
  711  case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
 
  712  case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
 
  713  case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
 
  714  case BIO_CTRL_DGRAM_MTU_EXCEEDED:
 
  715  case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
 
  724coap_dtls_generate_cookie(SSL *ssl,
 
  725                          unsigned char *cookie,
 
  726                          unsigned int *cookie_len) {
 
  727  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
 
  728  coap_dtls_context_t *dtls = ctx ? (coap_dtls_context_t *)SSL_CTX_get_app_data(ctx) : NULL;
 
  729  coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
 
  732    int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
 
  733    r &= HMAC_Update(dtls->cookie_hmac,
 
  734                     (
const uint8_t *)&data->session->addr_info.local.addr,
 
  735                     (
size_t)data->session->addr_info.local.size);
 
  736    r &= HMAC_Update(dtls->cookie_hmac,
 
  737                     (
const uint8_t *)&data->session->addr_info.remote.addr,
 
  738                     (
size_t)data->session->addr_info.remote.size);
 
  739    r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
 
  746coap_dtls_verify_cookie(SSL *ssl,
 
  747                        const uint8_t *cookie,
 
  748                        unsigned int cookie_len) {
 
  751  if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
 
  752      cookie_len == len && memcmp(cookie, hmac, len) == 0)
 
  758#if COAP_CLIENT_SUPPORT 
  760coap_dtls_psk_client_callback(SSL *ssl,
 
  763                              unsigned int max_identity_len,
 
  765                              unsigned int max_psk_len) {
 
  767  coap_openssl_context_t *o_context;
 
  775  if (c_session == NULL || c_session->
context == NULL)
 
  778  if (o_context == NULL)
 
  782  temp.
s = hint ? (
const uint8_t *)hint : (const uint8_t *)
"";
 
  783  temp.
length = strlen((
const char *)temp.
s);
 
  787                 (
const char *)temp.
s);
 
  799    if (cpsk_info == NULL)
 
  804    psk_identity = &cpsk_info->
identity;
 
  805    psk_key = &cpsk_info->
key;
 
  811  if (psk_identity == NULL || psk_key == NULL) {
 
  817  if (!max_identity_len)
 
  820  if (psk_identity->
length > max_identity_len) {
 
  821    coap_log_warn(
"psk_identity too large, truncated to %d bytes\n",
 
  825    max_identity_len = (
unsigned int)psk_identity->
length;
 
  827  memcpy(identity, psk_identity->
s, max_identity_len);
 
  828  identity[max_identity_len] = 
'\000';
 
  830  if (psk_key->
length > max_psk_len) {
 
  835    max_psk_len = (
unsigned int)psk_key->
length;
 
  837  memcpy(psk, psk_key->
s, max_psk_len);
 
  842#if COAP_SERVER_SUPPORT 
  844coap_dtls_psk_server_callback(
 
  846    const char *identity,
 
  848    unsigned int max_psk_len
 
  856  if (c_session == NULL || c_session->
context == NULL)
 
  862  lidentity.
s = identity ? (
const uint8_t *)identity : (const uint8_t *)
"";
 
  863  lidentity.
length = strlen((
const char *)lidentity.
s);
 
  867                 (
int)lidentity.
length, (
const char *)lidentity.
s);
 
  882  if (psk_key->
length > max_psk_len) {
 
  887    max_psk_len = (
unsigned int)psk_key->
length;
 
  889  memcpy(psk, psk_key->
s, max_psk_len);
 
  895ssl_function_definition(
unsigned long e) {
 
  896#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
  900  static char buff[80];
 
  902  snprintf(buff, 
sizeof(buff), 
" at %s:%s",
 
  903           ERR_lib_error_string(e), ERR_func_error_string(e));
 
  909coap_dtls_info_callback(
const SSL *ssl, 
int where, 
int ret) {
 
  912  int w = where &~SSL_ST_MASK;
 
  916                  "coap_dtls_info_callback: session not determined, where 0x%0x and ret 0x%0x\n", where, ret);
 
  919  if (w & SSL_ST_CONNECT)
 
  920    pstr = 
"SSL_connect";
 
  921  else if (w & SSL_ST_ACCEPT)
 
  926  if (where & SSL_CB_LOOP) {
 
  929  } 
else if (where & SSL_CB_ALERT) {
 
  931    pstr = (where & SSL_CB_READ) ? 
"read" : 
"write";
 
  932    if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
 
  934      if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
 
  938    coap_log(log_level, 
"*  %s: SSL3 alert %s:%s:%s\n",
 
  941             SSL_alert_type_string_long(ret),
 
  942             SSL_alert_desc_string_long(ret));
 
  943  } 
else if (where & SSL_CB_EXIT) {
 
  949        while ((e = ERR_get_error()))
 
  952                        ssl_function_definition(e));
 
  954    } 
else if (ret < 0) {
 
  956        int err = SSL_get_error(ssl, ret);
 
  957        if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE &&
 
  958            err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT &&
 
  959            err != SSL_ERROR_WANT_X509_LOOKUP) {
 
  963          while ((e = ERR_get_error()))
 
  966                          ssl_function_definition(e));
 
  972  if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
 
  978coap_sock_create(BIO *a) {
 
  984coap_sock_destroy(BIO *a) {
 
  996coap_sock_read(BIO *a, 
char *out, 
int outl) {
 
 1000  if (session && out != NULL) {
 
 1005      BIO_set_retry_read(a);
 
 1008      BIO_clear_retry_flags(a);
 
 1021coap_sock_write(BIO *a, 
const char *in, 
int inl) {
 
 1030                                                           (
const uint8_t *)in,
 
 1034  BIO_clear_retry_flags(a);
 
 1036    BIO_set_retry_read(a);
 
 1039    BIO_clear_retry_flags(a);
 
 1043          (errno == EPIPE || errno == ECONNRESET)) {
 
 1063coap_sock_puts(BIO *a, 
const char *pstr) {
 
 1064  return coap_sock_write(a, pstr, (
int)strlen(pstr));
 
 1068coap_sock_ctrl(BIO *a, 
int cmd, 
long num, 
void *ptr) {
 
 1079  case BIO_CTRL_SET_CLOSE:
 
 1081  case BIO_CTRL_FLUSH:
 
 1085  case BIO_CTRL_GET_CLOSE:
 
 1094coap_set_user_prefs(SSL_CTX *ctx) {
 
 1095  SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
 
 1097#ifdef COAP_OPENSSL_SIGALGS 
 1098  SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
 
 1099  SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
 
 1102#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS) 
 1103  SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
 
 1107#if COAP_DTLS_RETRANSMIT_MS != 1000 
 1108#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
 1110timer_cb(SSL *s, 
unsigned int timer_us) {
 
 1113    return COAP_DTLS_RETRANSMIT_MS * 1000;
 
 1115    return 2 * timer_us;
 
 1122  coap_openssl_context_t *context;
 
 1127    uint8_t cookie_secret[32];
 
 1129    memset(context, 0, 
sizeof(coap_openssl_context_t));
 
 1132    context->dtls.ctx = SSL_CTX_new(DTLS_method());
 
 1133    if (!context->dtls.ctx)
 
 1135    SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
 
 1136    SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
 
 1137    SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
 
 1138    coap_set_user_prefs(context->dtls.ctx);
 
 1139    memset(cookie_secret, 0, 
sizeof(cookie_secret));
 
 1140    if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
 
 1142                    "Insufficient entropy for random cookie generation");
 
 1145    context->dtls.cookie_hmac = HMAC_CTX_new();
 
 1146    if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret),
 
 1147                      EVP_sha256(), NULL))
 
 1149    SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
 
 1150    SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
 
 1151    SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
 
 1152    SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
 
 1153#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
 1154    SSL_CTX_set_options(context->dtls.ctx, SSL_OP_LEGACY_SERVER_CONNECT);
 
 1156    context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM, 
"coapdgram");
 
 1157    if (!context->dtls.meth)
 
 1159    context->dtls.bio_addr = BIO_ADDR_new();
 
 1160    if (!context->dtls.bio_addr)
 
 1162    BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
 
 1163    BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
 
 1164    BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
 
 1165    BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
 
 1166    BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
 
 1167    BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
 
 1169#if !COAP_DISABLE_TCP 
 1171    context->tls.ctx = SSL_CTX_new(TLS_method());
 
 1172    if (!context->tls.ctx)
 
 1174    SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
 
 1175    SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
 
 1176    coap_set_user_prefs(context->tls.ctx);
 
 1177    SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
 
 1178    context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET, 
"coapsock");
 
 1179    if (!context->tls.meth)
 
 1181    BIO_meth_set_write(context->tls.meth, coap_sock_write);
 
 1182    BIO_meth_set_read(context->tls.meth, coap_sock_read);
 
 1183    BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
 
 1184    BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
 
 1185    BIO_meth_set_create(context->tls.meth, coap_sock_create);
 
 1186    BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
 
 1197#if COAP_SERVER_SUPPORT 
 1202  coap_openssl_context_t *o_context =
 
 1206  if (!setup_data || !o_context)
 
 1209  SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
 
 1210                                  coap_dtls_psk_server_callback);
 
 1211#if !COAP_DISABLE_TCP 
 1212  SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
 
 1213                                  coap_dtls_psk_server_callback);
 
 1219    SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
 
 1220#if !COAP_DISABLE_TCP 
 1221    SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
 
 1225#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 1226    SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
 
 1228    SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
 
 1229                                           psk_tls_server_name_call_back);
 
 1230#if !COAP_DISABLE_TCP 
 1231    SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
 
 1233    SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
 
 1234                                           psk_tls_server_name_call_back);
 
 1237    SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
 
 1238                                psk_tls_client_hello_call_back,
 
 1240#if !COAP_DISABLE_TCP 
 1241    SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
 
 1242                                psk_tls_client_hello_call_back,
 
 1248  if (!o_context->dtls.ssl) {
 
 1250    o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
 
 1251    if (!o_context->dtls.ssl)
 
 1253    bio = BIO_new(o_context->dtls.meth);
 
 1255      SSL_free(o_context->dtls.ssl);
 
 1256      o_context->dtls.ssl = NULL;
 
 1259    SSL_set_bio(o_context->dtls.ssl, bio, bio);
 
 1260    SSL_set_app_data(o_context->dtls.ssl, NULL);
 
 1261    SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
 
 1267  o_context->psk_pki_enabled |= IS_PSK;
 
 1272#if COAP_CLIENT_SUPPORT 
 1277  coap_openssl_context_t *o_context =
 
 1281  if (!setup_data || !o_context)
 
 1284  if (!o_context->dtls.ssl) {
 
 1286    o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
 
 1287    if (!o_context->dtls.ssl)
 
 1289    bio = BIO_new(o_context->dtls.meth);
 
 1291      SSL_free(o_context->dtls.ssl);
 
 1292      o_context->dtls.ssl = NULL;
 
 1295    SSL_set_bio(o_context->dtls.ssl, bio, bio);
 
 1296    SSL_set_app_data(o_context->dtls.ssl, NULL);
 
 1297    SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
 
 1306  o_context->psk_pki_enabled |= IS_PSK;
 
 1312map_key_type(
int asn1_private_key_type
 
 1314  switch (asn1_private_key_type) {
 
 1316    return EVP_PKEY_NONE;
 
 1318    return EVP_PKEY_RSA;
 
 1320    return EVP_PKEY_RSA2;
 
 1322    return EVP_PKEY_DSA;
 
 1324    return EVP_PKEY_DSA1;
 
 1326    return EVP_PKEY_DSA2;
 
 1328    return EVP_PKEY_DSA3;
 
 1330    return EVP_PKEY_DSA4;
 
 1334    return EVP_PKEY_DHX;
 
 1338    return EVP_PKEY_HMAC;
 
 1340    return EVP_PKEY_CMAC;
 
 1342    return EVP_PKEY_TLS1_PRF;
 
 1344    return EVP_PKEY_HKDF;
 
 1346    coap_log_warn(
"*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
 
 1347                  asn1_private_key_type);
 
 1352#if !COAP_DISABLE_TCP 
 1353static uint8_t coap_alpn[] = { 4, 
'c', 
'o', 
'a', 
'p' };
 
 1355#if COAP_SERVER_SUPPORT 
 1358                     const unsigned char **out,
 
 1359                     unsigned char *outlen,
 
 1360                     const unsigned char *in,
 
 1364  unsigned char *tout = NULL;
 
 1367    return SSL_TLSEXT_ERR_NOACK;
 
 1368  ret = SSL_select_next_proto(&tout,
 
 1375  return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
 
 1381add_ca_to_cert_store(X509_STORE *st, X509 *x509) {
 
 1385  while (ERR_get_error() != 0) {
 
 1388  if (!X509_STORE_add_cert(st, x509)) {
 
 1389    while ((e = ERR_get_error()) != 0) {
 
 1390      int r = ERR_GET_REASON(e);
 
 1391      if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
 
 1394                      ERR_reason_error_string(e),
 
 1395                      ssl_function_definition(e));
 
 1402missing_ENGINE_load_cert(ENGINE *engine, 
const char *cert_id) {
 
 1404    const char *cert_id;
 
 1408  params.cert_id = cert_id;
 
 1412  if (!ENGINE_ctrl_cmd(engine, 
"LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
 
 1419check_pkcs11_engine(
void) {
 
 1420  static int already_tried = 0;
 
 1425  if (!pkcs11_engine) {
 
 1426    pkcs11_engine = ENGINE_by_id(COAP_OPENSSL_PKCS11_ENGINE_ID);
 
 1427    if (!pkcs11_engine) {
 
 1428      coap_log_err(
"*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL %s engine\n",
 
 1429                   COAP_OPENSSL_PKCS11_ENGINE_ID);
 
 1433    if (!ENGINE_init(pkcs11_engine)) {
 
 1435      ENGINE_free(pkcs11_engine);
 
 1436      pkcs11_engine = NULL;
 
 1437      coap_log_err(
"*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
 
 1445    ENGINE_free(pkcs11_engine);
 
 1450#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT 
 1453install_engine_public_cert_ctx(ENGINE *engine, SSL_CTX *ctx,
 
 1454                               const char *public_cert) {
 
 1457  x509 = missing_ENGINE_load_cert(engine, public_cert);
 
 1465  if (!SSL_CTX_use_certificate(ctx, x509)) {
 
 1466    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1478install_engine_private_key_ctx(ENGINE *engine, SSL_CTX *ctx,
 
 1479                               const char *private_key) {
 
 1480  EVP_PKEY *pkey = ENGINE_load_private_key(engine,
 
 1491  if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
 
 1492    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1496    EVP_PKEY_free(pkey);
 
 1499  EVP_PKEY_free(pkey);
 
 1504install_engine_ca_ctx(ENGINE *engine, SSL_CTX *ctx, 
const char *ca) {
 
 1508  x509 = missing_ENGINE_load_cert(engine,
 
 1512                  "%s CA Certificate\n",
 
 1517  if (!SSL_CTX_add_client_CA(ctx, x509)) {
 
 1518    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1519                  "%s CA Certificate\n",
 
 1525  st = SSL_CTX_get_cert_store(ctx);
 
 1526  add_ca_to_cert_store(st, x509);
 
 1532load_in_cas_ctx(SSL_CTX *ctx,
 
 1533                const char *ca_file) {
 
 1534  STACK_OF(X509_NAME) *cert_names;
 
 1538  char *rw_var = NULL;
 
 1539  cert_names = SSL_load_client_CA_file(ca_file);
 
 1540  if (cert_names != NULL)
 
 1541    SSL_CTX_set_client_CA_list(ctx, cert_names);
 
 1543    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1550  st = SSL_CTX_get_cert_store(ctx);
 
 1551  in = BIO_new(BIO_s_file());
 
 1553  memcpy(&rw_var, &ca_file, 
sizeof(rw_var));
 
 1554  if (!BIO_read_filename(in, rw_var)) {
 
 1561    if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
 
 1563    add_ca_to_cert_store(st, x);
 
 1571setup_pki_server(SSL_CTX *ctx,
 
 1587      if (!(SSL_CTX_use_PrivateKey_file(ctx,
 
 1589                                        SSL_FILETYPE_PEM))) {
 
 1599        EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
 
 1601        if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
 
 1605            EVP_PKEY_free(pkey);
 
 1613          EVP_PKEY_free(pkey);
 
 1625      if (!(SSL_CTX_use_PrivateKey_file(ctx,
 
 1627                                        SSL_FILETYPE_ASN1))) {
 
 1645      if (!check_pkcs11_engine()) {
 
 1650        if (ENGINE_ctrl_cmd_string(pkcs11_engine,
 
 1653          coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
 
 1658      if (!install_engine_private_key_ctx(pkcs11_engine, ctx,
 
 1666      if (!defined_engine ||
 
 1667          !install_engine_private_key_ctx(defined_engine, ctx,
 
 1696        if (!(SSL_CTX_use_certificate_file(ctx,
 
 1698                                           SSL_FILETYPE_PEM))) {
 
 1704        if (!SSL_CTX_use_certificate_chain_file(ctx,
 
 1716        X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
 
 1718        if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
 
 1742      if (!(SSL_CTX_use_certificate_file(ctx,
 
 1744                                         SSL_FILETYPE_ASN1))) {
 
 1752          !(SSL_CTX_use_certificate_ASN1(ctx,
 
 1761      if (!check_pkcs11_engine()) {
 
 1764      if (!install_engine_public_cert_ctx(pkcs11_engine, ctx,
 
 1772      if (!defined_engine ||
 
 1773          !install_engine_public_cert_ctx(defined_engine, ctx,
 
 1811        X509_STORE *st = SSL_CTX_get_cert_store(ctx);
 
 1815            if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
 
 1817            add_ca_to_cert_store(st, x);
 
 1818            SSL_CTX_add_client_CA(ctx, x);
 
 1834      if (!(SSL_CTX_use_certificate_file(ctx,
 
 1836                                         SSL_FILETYPE_ASN1))) {
 
 1849        if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
 
 1857        st = SSL_CTX_get_cert_store(ctx);
 
 1858        add_ca_to_cert_store(st, x509);
 
 1863      if (!check_pkcs11_engine()) {
 
 1866      if (!install_engine_ca_ctx(pkcs11_engine, ctx,
 
 1874      if (!defined_engine ||
 
 1875          !install_engine_ca_ctx(defined_engine, ctx,
 
 1894#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT 
 1897install_engine_public_cert(ENGINE *engine, SSL *ssl, 
const char *public_cert,
 
 1901  x509 = missing_ENGINE_load_cert(engine, public_cert);
 
 1909  if (!SSL_use_certificate(ssl, x509)) {
 
 1910    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1922install_engine_private_key(ENGINE *engine, SSL *ssl, 
const char *private_key,
 
 1924  EVP_PKEY *pkey = ENGINE_load_private_key(engine,
 
 1935  if (!SSL_use_PrivateKey(ssl, pkey)) {
 
 1936    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1940    EVP_PKEY_free(pkey);
 
 1943  EVP_PKEY_free(pkey);
 
 1948install_engine_ca(ENGINE *engine, SSL *ssl, 
const char *ca,
 
 1951  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
 
 1956                  "%s CA Certificate (no ctx)\n",
 
 1961  x509 = missing_ENGINE_load_cert(engine,
 
 1965                  "%s CA Certificate\n",
 
 1970  if (!SSL_add_client_CA(ssl, x509)) {
 
 1971    coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure " 
 1972                  "%s CA Certificate\n",
 
 1978  st = SSL_CTX_get_cert_store(ctx);
 
 1979  add_ca_to_cert_store(st, x509);
 
 1985load_in_cas(SSL *ssl,
 
 1990  char *rw_var = NULL;
 
 1991  SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
 
 1994    STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(ca_file);
 
 1996    if (cert_names != NULL)
 
 1997      SSL_set_client_CA_list(ssl, cert_names);
 
 2007  in = BIO_new(BIO_s_file());
 
 2009  memcpy(&rw_var, &ca_file, 
sizeof(rw_var));
 
 2010  if (!BIO_read_filename(in, rw_var)) {
 
 2014  st = SSL_CTX_get_cert_store(ctx);
 
 2016    if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
 
 2018    add_ca_to_cert_store(st, x);
 
 2026setup_pki_ssl(SSL *ssl,
 
 2042      if (!(SSL_use_PrivateKey_file(ssl,
 
 2044                                    SSL_FILETYPE_PEM))) {
 
 2054        EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
 
 2056        if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
 
 2060            EVP_PKEY_free(pkey);
 
 2068          EVP_PKEY_free(pkey);
 
 2080      if (!(SSL_use_PrivateKey_file(ssl,
 
 2082                                    SSL_FILETYPE_ASN1))) {
 
 2100      if (!check_pkcs11_engine()) {
 
 2105        if (ENGINE_ctrl_cmd_string(pkcs11_engine,
 
 2108          coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
 
 2113      if (!install_engine_private_key(pkcs11_engine, ssl,
 
 2122      if (!defined_engine ||
 
 2123          !install_engine_private_key(defined_engine, ssl,
 
 2155        if (!(SSL_use_certificate_file(ssl,
 
 2157                                       SSL_FILETYPE_PEM))) {
 
 2163        if (!SSL_use_certificate_chain_file(ssl,
 
 2175        X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
 
 2177        if (!cert || !SSL_use_certificate(ssl, cert)) {
 
 2201      if (!(SSL_use_certificate_file(ssl,
 
 2203                                     SSL_FILETYPE_ASN1))) {
 
 2211          !(SSL_use_certificate_ASN1(ssl,
 
 2220      if (!check_pkcs11_engine()) {
 
 2223      if (!install_engine_public_cert(pkcs11_engine, ssl,
 
 2232      if (!defined_engine ||
 
 2233          !install_engine_public_cert(defined_engine, ssl,
 
 2272        SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
 
 2274        X509_STORE *st = ctx? SSL_CTX_get_cert_store(ctx) : NULL;
 
 2278            if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
 
 2281              add_ca_to_cert_store(st, x);
 
 2282            SSL_add_client_CA(ssl, x);
 
 2298      if (!(SSL_use_certificate_file(ssl,
 
 2300                                     SSL_FILETYPE_ASN1))) {
 
 2312        SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
 
 2315          if (!x509 || !SSL_add_client_CA(ssl, x509)) {
 
 2324        st = ctx ? SSL_CTX_get_cert_store(ctx) : NULL;
 
 2326          add_ca_to_cert_store(st, x509);
 
 2331      if (!check_pkcs11_engine()) {
 
 2334      if (!install_engine_ca(pkcs11_engine, ssl,
 
 2343      if (!defined_engine ||
 
 2344          !install_engine_ca(defined_engine, ssl,
 
 2365get_san_or_cn_from_cert(X509 *x509) {
 
 2369    STACK_OF(GENERAL_NAME) *san_list;
 
 2372    san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
 
 2374      int san_count = sk_GENERAL_NAME_num(san_list);
 
 2376      for (n = 0; n < san_count; n++) {
 
 2377        const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n);
 
 2379        if (name && name->type == GEN_DNS) {
 
 2380          const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
 
 2383          if (ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name))
 
 2385          cn = OPENSSL_strdup(dns_name);
 
 2386          sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
 
 2390      sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
 
 2393    X509_NAME_oneline(X509_get_subject_name(x509), buffer, 
sizeof(buffer));
 
 2396    n = (int)strlen(buffer) - 3;
 
 2399      if (((cn[0] == 
'C') || (cn[0] == 
'c')) &&
 
 2400          ((cn[1] == 
'N') || (cn[1] == 
'n')) &&
 
 2409      char *ecn = strchr(cn, 
'/');
 
 2411        return OPENSSL_strndup(cn, ecn-cn);
 
 2413        return OPENSSL_strdup(cn);
 
 2421tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
 
 2422  int index = SSL_get_ex_data_X509_STORE_CTX_idx();
 
 2423  SSL *ssl = index >= 0 ? X509_STORE_CTX_get_ex_data(ctx, index) : NULL;
 
 2425  coap_openssl_context_t *context = (session && session->
context) ?
 
 2428  int depth = X509_STORE_CTX_get_error_depth(ctx);
 
 2429  int err = X509_STORE_CTX_get_error(ctx);
 
 2430  X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
 
 2431  char *cn = x509 ? get_san_or_cn_from_cert(x509) : NULL;
 
 2432  int keep_preverify_ok = preverify_ok;
 
 2435                depth, err, preverify_ok, cn);
 
 2437    X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
 
 2441  if (!preverify_ok) {
 
 2443    case X509_V_ERR_CERT_NOT_YET_VALID:
 
 2444    case X509_V_ERR_CERT_HAS_EXPIRED:
 
 2448    case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
 
 2452    case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: 
 
 2456    case X509_V_ERR_UNABLE_TO_GET_CRL:
 
 2460    case X509_V_ERR_CRL_NOT_YET_VALID:
 
 2461    case X509_V_ERR_CRL_HAS_EXPIRED:
 
 2465    case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
 
 2466    case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
 
 2467    case X509_V_ERR_AKID_SKID_MISMATCH:
 
 2477      err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
 
 2478      X509_STORE_CTX_set_error(ctx, err);
 
 2480    if (!preverify_ok) {
 
 2481      if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
 
 2484                      "Unknown CA", cn ? cn : 
"?", depth);
 
 2488                      X509_verify_cert_error_string(err), cn ? cn : 
"?", depth);
 
 2493                    X509_verify_cert_error_string(err), cn ? cn : 
"?", depth);
 
 2498    int length = i2d_X509(x509, NULL);
 
 2500    uint8_t *base_buf2 = base_buf = length > 0 ? OPENSSL_malloc(length) : NULL;
 
 2505      assert(i2d_X509(x509, &base_buf2) > 0);
 
 2509                                                               depth, preverify_ok,
 
 2513          X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
 
 2515          X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
 
 2519      OPENSSL_free(base_buf);
 
 2521      X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
 
 2526  return preverify_ok;
 
 2529#if COAP_SERVER_SUPPORT 
 2530#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 2540tls_secret_call_back(SSL *ssl,
 
 2543                     STACK_OF(SSL_CIPHER) *peer_ciphers,
 
 2547  int     psk_requested = 0;
 
 2552  assert(session != NULL);
 
 2553  assert(session->
context != NULL);
 
 2554  if (session == NULL ||
 
 2562    for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
 
 2563      const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
 
 2566                    SSL_CIPHER_get_name(peer_cipher));
 
 2567      if (strstr(SSL_CIPHER_get_name(peer_cipher), 
"PSK")) {
 
 2573  if (!psk_requested) {
 
 2580                     SSL_VERIFY_CLIENT_ONCE |
 
 2581                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 
 2582                     tls_verify_call_back);
 
 2584      SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
 
 2593      X509_VERIFY_PARAM *param;
 
 2595      param = X509_VERIFY_PARAM_new();
 
 2596      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
 
 2597      SSL_set1_param(ssl, param);
 
 2598      X509_VERIFY_PARAM_free(param);
 
 2620    SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
 
 2621    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
 
 2636tls_server_name_call_back(SSL *ssl,
 
 2642    return SSL_TLSEXT_ERR_NOACK;
 
 2648    coap_openssl_context_t *context = (session && session->
context) ?
 
 2650    const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
 
 2654    return SSL_TLSEXT_ERR_NOACK;
 
 2656    if (!sni || !sni[0]) {
 
 2659    for (i = 0; i < context->sni_count; i++) {
 
 2660    if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
 
 2664    if (i == context->sni_count) {
 
 2673        return SSL_TLSEXT_ERR_ALERT_FATAL;
 
 2678        ctx = SSL_CTX_new(DTLS_method());
 
 2681        SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
 
 2682        SSL_CTX_set_app_data(ctx, &context->dtls);
 
 2683        SSL_CTX_set_read_ahead(ctx, 1);
 
 2684        coap_set_user_prefs(ctx);
 
 2685        SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
 
 2686        SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
 
 2687        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
 
 2688        SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
 
 2690#if !COAP_DISABLE_TCP 
 2693        ctx = SSL_CTX_new(TLS_method());
 
 2696        SSL_CTX_set_app_data(ctx, &context->tls);
 
 2697        SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
 
 2698        coap_set_user_prefs(ctx);
 
 2699        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
 
 2700        SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
 
 2703      sni_setup_data = *setup_data;
 
 2704      sni_setup_data.
pki_key = *new_entry;
 
 2705      setup_pki_server(ctx, &sni_setup_data);
 
 2707      context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
 
 2708                                                (context->sni_count+1)*
sizeof(sni_entry));
 
 2709      context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
 
 2710      context->sni_entry_list[context->sni_count].ctx = ctx;
 
 2711      context->sni_count++;
 
 2713    SSL_set_SSL_CTX(ssl, context->sni_entry_list[i].ctx);
 
 2714    SSL_clear_options(ssl, 0xFFFFFFFFL);
 
 2715    SSL_set_options(ssl, SSL_CTX_get_options(context->sni_entry_list[i].ctx));
 
 2722  SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
 
 2723  return SSL_TLSEXT_ERR_OK;
 
 2726  return SSL_TLSEXT_ERR_ALERT_WARNING;
 
 2738psk_tls_server_name_call_back(SSL *ssl,
 
 2745    return SSL_TLSEXT_ERR_NOACK;
 
 2751    coap_openssl_context_t *o_context = (c_session && c_session->
context) ?
 
 2753    const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
 
 2758      return SSL_TLSEXT_ERR_ALERT_FATAL;
 
 2760    if (!sni || !sni[0]) {
 
 2763    for (i = 0; i < o_context->psk_sni_count; i++) {
 
 2764      if (!strcasecmp(sni, (
char *)o_context->psk_sni_entry_list[i].sni)) {
 
 2768    if (i == o_context->psk_sni_count) {
 
 2777        return SSL_TLSEXT_ERR_ALERT_FATAL;
 
 2782        ctx = SSL_CTX_new(DTLS_method());
 
 2785        SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
 
 2786        SSL_CTX_set_app_data(ctx, &o_context->dtls);
 
 2787        SSL_CTX_set_read_ahead(ctx, 1);
 
 2788        SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
 
 2789        SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
 
 2790        SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
 
 2791        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
 
 2792        SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
 
 2794#if !COAP_DISABLE_TCP 
 2797        ctx = SSL_CTX_new(TLS_method());
 
 2800        SSL_CTX_set_app_data(ctx, &o_context->tls);
 
 2801        SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
 
 2802        SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
 
 2803        SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
 
 2804        SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
 
 2808      o_context->psk_sni_entry_list =
 
 2809          OPENSSL_realloc(o_context->psk_sni_entry_list,
 
 2810                          (o_context->psk_sni_count+1)*
sizeof(psk_sni_entry));
 
 2811      o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
 
 2812          OPENSSL_strdup(sni);
 
 2813      o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
 
 2815      o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
 
 2817      o_context->psk_sni_count++;
 
 2819    SSL_set_SSL_CTX(ssl, o_context->psk_sni_entry_list[i].ctx);
 
 2820    SSL_clear_options(ssl, 0xFFFFFFFFL);
 
 2821    SSL_set_options(ssl,
 
 2822                    SSL_CTX_get_options(o_context->psk_sni_entry_list[i].ctx));
 
 2824                                 &o_context->psk_sni_entry_list[i].psk_info.key);
 
 2825    snprintf(lhint, 
sizeof(lhint), 
"%.*s",
 
 2826             (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
 
 2827             o_context->psk_sni_entry_list[i].psk_info.hint.s);
 
 2828    SSL_use_psk_identity_hint(ssl, lhint);
 
 2835  SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
 
 2836  return SSL_TLSEXT_ERR_OK;
 
 2839  return SSL_TLSEXT_ERR_ALERT_WARNING;
 
 2852tls_client_hello_call_back(SSL *ssl,
 
 2857  coap_openssl_context_t *dtls_context;
 
 2859  int psk_requested = 0;
 
 2860  const unsigned char *out;
 
 2864    *al = SSL_AD_INTERNAL_ERROR;
 
 2865    return SSL_CLIENT_HELLO_ERROR;
 
 2868  assert(session != NULL);
 
 2869  assert(session->
context != NULL);
 
 2871  if (session == NULL ||
 
 2874    *al = SSL_AD_INTERNAL_ERROR;
 
 2875    return SSL_CLIENT_HELLO_ERROR;
 
 2878  setup_data = &dtls_context->setup_data;
 
 2886    size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
 
 2887    STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
 
 2888    STACK_OF(SSL_CIPHER) *scsvc = NULL;
 
 2890    if (len && SSL_bytes_to_cipher_list(ssl, out, len,
 
 2891                                        SSL_client_hello_isv2(ssl),
 
 2892                                        &peer_ciphers, &scsvc)) {
 
 2894      for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
 
 2895        const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
 
 2898                      "Client cipher: %s (%04x)\n",
 
 2899                      SSL_CIPHER_get_name(peer_cipher),
 
 2900                      SSL_CIPHER_get_protocol_id(peer_cipher));
 
 2901        if (strstr(SSL_CIPHER_get_name(peer_cipher), 
"PSK")) {
 
 2907    sk_SSL_CIPHER_free(peer_ciphers);
 
 2908    sk_SSL_CIPHER_free(scsvc);
 
 2911  if (psk_requested) {
 
 2917    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
 
 2923    return SSL_CLIENT_HELLO_SUCCESS;
 
 2933  if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
 
 2936    for (ii = 0; ii < outlen; ii++) {
 
 2952    *al = SSL_AD_UNSUPPORTED_EXTENSION;
 
 2953    return SSL_CLIENT_HELLO_ERROR;
 
 2962    coap_openssl_context_t *context =
 
 2964    const char *sni = 
"";
 
 2965    char *sni_tmp = NULL;
 
 2968    if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
 
 2970        (((out[0]<<8) + out[1] +2) == (int)outlen) &&
 
 2971        out[2] == TLSEXT_NAMETYPE_host_name &&
 
 2972        (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
 
 2976      sni_tmp = OPENSSL_malloc(outlen+1);
 
 2977      sni_tmp[outlen] = 
'\000';
 
 2978      memcpy(sni_tmp, out, outlen);
 
 2982    for (i = 0; i < context->sni_count; i++) {
 
 2983      if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
 
 2987    if (i == context->sni_count) {
 
 2997        *al = SSL_AD_UNRECOGNIZED_NAME;
 
 2998        return SSL_CLIENT_HELLO_ERROR;
 
 3002      context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
 
 3003                                                (context->sni_count+1)*
sizeof(sni_entry));
 
 3004      context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
 
 3005      context->sni_entry_list[context->sni_count].pki_key = *new_entry;
 
 3006      context->sni_count++;
 
 3009      OPENSSL_free(sni_tmp);
 
 3011    sni_setup_data = *setup_data;
 
 3012    sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
 
 3024                   SSL_VERIFY_CLIENT_ONCE |
 
 3025                   SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 
 3026                   tls_verify_call_back);
 
 3028    SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
 
 3037    X509_VERIFY_PARAM *param;
 
 3039    param = X509_VERIFY_PARAM_new();
 
 3040    X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
 
 3041    SSL_set1_param(ssl, param);
 
 3042    X509_VERIFY_PARAM_free(param);
 
 3049  return SSL_CLIENT_HELLO_SUCCESS;
 
 3061psk_tls_client_hello_call_back(SSL *ssl,
 
 3066  coap_openssl_context_t *o_context;
 
 3068  const unsigned char *out;
 
 3074  if (!c_session || !c_session->
context) {
 
 3087    const char *sni = 
"";
 
 3088    char *sni_tmp = NULL;
 
 3091    if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
 
 3093        (((out[0]<<8) + out[1] +2) == (
int)outlen) &&
 
 3094        out[2] == TLSEXT_NAMETYPE_host_name &&
 
 3095        (((out[3]<<8) + out[4] +2 +3) == (
int)outlen)) {
 
 3099      sni_tmp = OPENSSL_malloc(outlen+1);
 
 3101        sni_tmp[outlen] = 
'\000';
 
 3102        memcpy(sni_tmp, out, outlen);
 
 3107#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3110    for (i = 0; i < o_context->psk_sni_count; i++) {
 
 3111      if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
 
 3115    if (i == o_context->psk_sni_count) {
 
 3128        *al = SSL_AD_UNRECOGNIZED_NAME;
 
 3129        return SSL_CLIENT_HELLO_ERROR;
 
 3132#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3133      psk_sni_entry *tmp_entry;
 
 3135          OPENSSL_realloc(o_context->psk_sni_entry_list,
 
 3136                          (o_context->psk_sni_count+1)*
sizeof(sni_entry));
 
 3138        o_context->psk_sni_entry_list = tmp_entry;
 
 3139        o_context->psk_sni_entry_list[o_context->psk_sni_count]
 
 3141            OPENSSL_strdup(sni);
 
 3142        if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
 
 3143          o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
 
 3145          o_context->psk_sni_count++;
 
 3149      new_entry = &o_context->psk_sni_entry_list[i].psk_info;
 
 3154      OPENSSL_free(sni_tmp);
 
 3166    if (new_entry->
hint.
s) {
 
 3167      snprintf(lhint, 
sizeof(lhint), 
"%.*s",
 
 3170      SSL_use_psk_identity_hint(ssl, lhint);
 
 3173  return SSL_CLIENT_HELLO_SUCCESS;
 
 3176  *al = SSL_AD_INTERNAL_ERROR;
 
 3177  return SSL_CLIENT_HELLO_ERROR;
 
 3186  coap_openssl_context_t *context =
 
 3191  context->setup_data = *setup_data;
 
 3197      if (!defined_engine) {
 
 3198        coap_log_warn(
"setup_pki: OpenSSL Engine not configured, PKI not set up\n");
 
 3204  if (!context->setup_data.verify_peer_cert) {
 
 3206    context->setup_data.check_common_ca = 0;
 
 3208    context->setup_data.allow_self_signed = 1;
 
 3209    context->setup_data.allow_expired_certs = 1;
 
 3210    context->setup_data.cert_chain_validation = 1;
 
 3211    context->setup_data.cert_chain_verify_depth = 10;
 
 3212    context->setup_data.check_cert_revocation = 1;
 
 3213    context->setup_data.allow_no_crl = 1;
 
 3214    context->setup_data.allow_expired_crl = 1;
 
 3215    context->setup_data.allow_bad_md_hash = 1;
 
 3216    context->setup_data.allow_short_rsa_length = 1;
 
 3218#if COAP_SERVER_SUPPORT 
 3220    if (context->dtls.ctx) {
 
 3222#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3223      if (!setup_pki_server(context->dtls.ctx, setup_data))
 
 3232#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3233      if (SSLeay() >= 0x10101000L) {
 
 3234        coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so " 
 3235                      "no certificate checking\n",
 
 3236                      OPENSSL_VERSION_NUMBER, SSLeay());
 
 3238      SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
 
 3239      SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
 
 3240                                             tls_server_name_call_back);
 
 3242      SSL_CTX_set_client_hello_cb(context->dtls.ctx,
 
 3243                                  tls_client_hello_call_back,
 
 3247#if !COAP_DISABLE_TCP 
 3248    if (context->tls.ctx) {
 
 3250#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3251      if (!setup_pki_server(context->tls.ctx, setup_data))
 
 3260#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3261      if (SSLeay() >= 0x10101000L) {
 
 3262        coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so " 
 3263                      "no certificate checking\n",
 
 3264                      OPENSSL_VERSION_NUMBER, SSLeay());
 
 3266      SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
 
 3267      SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
 
 3268                                             tls_server_name_call_back);
 
 3270      SSL_CTX_set_client_hello_cb(context->tls.ctx,
 
 3271                                  tls_client_hello_call_back,
 
 3275      SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
 
 3283  if (!context->dtls.ssl) {
 
 3285    context->dtls.ssl = SSL_new(context->dtls.ctx);
 
 3286    if (!context->dtls.ssl)
 
 3288    bio = BIO_new(context->dtls.meth);
 
 3290      SSL_free(context->dtls.ssl);
 
 3291      context->dtls.ssl = NULL;
 
 3294    SSL_set_bio(context->dtls.ssl, bio, bio);
 
 3295    SSL_set_app_data(context->dtls.ssl, NULL);
 
 3296    SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
 
 3299  context->psk_pki_enabled |= IS_PKI;
 
 3308                                   const char *ca_file,
 
 3311  coap_openssl_context_t *context =
 
 3313  if (context->dtls.ctx) {
 
 3314    if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
 
 3316                    ca_file ? ca_file : 
"NULL", ca_dir ? ca_dir : 
"NULL");
 
 3320#if !COAP_DISABLE_TCP 
 3321  if (context->tls.ctx) {
 
 3322    if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
 
 3324                    ca_file ? ca_file : 
"NULL", ca_dir ? ca_dir : 
"NULL");
 
 3334#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
 3335  coap_openssl_context_t *context =
 
 3337  if (context->dtls.ctx) {
 
 3338    if (!SSL_CTX_set_default_verify_store(context->dtls.ctx)) {
 
 3343#if !COAP_DISABLE_TCP 
 3344  if (context->tls.ctx) {
 
 3345    if (!SSL_CTX_set_default_verify_store(context->tls.ctx)) {
 
 3354  coap_log_warn(
"coap_context_set_pki_trust_store: (D)TLS environment " 
 3355                "not supported for OpenSSL < v3.0.0\n");
 
 3362  coap_openssl_context_t *context =
 
 3364  return context->psk_pki_enabled ? 1 : 0;
 
 3371  coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
 
 3373  if (context->dtls.ssl)
 
 3374    SSL_free(context->dtls.ssl);
 
 3375  if (context->dtls.ctx)
 
 3376    SSL_CTX_free(context->dtls.ctx);
 
 3377  if (context->dtls.cookie_hmac)
 
 3378    HMAC_CTX_free(context->dtls.cookie_hmac);
 
 3379  if (context->dtls.meth)
 
 3380    BIO_meth_free(context->dtls.meth);
 
 3381  if (context->dtls.bio_addr)
 
 3382    BIO_ADDR_free(context->dtls.bio_addr);
 
 3383#if !COAP_DISABLE_TCP 
 3384  if (context->tls.ctx)
 
 3385    SSL_CTX_free(context->tls.ctx);
 
 3386  if (context->tls.meth)
 
 3387    BIO_meth_free(context->tls.meth);
 
 3389  for (i = 0; i < context->sni_count; i++) {
 
 3390    OPENSSL_free(context->sni_entry_list[i].sni);
 
 3391#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3392    SSL_CTX_free(context->sni_entry_list[i].ctx);
 
 3395  if (context->sni_count)
 
 3396    OPENSSL_free(context->sni_entry_list);
 
 3397#if OPENSSL_VERSION_NUMBER < 0x10101000L 
 3398  for (i = 0; i < context->psk_sni_count; i++) {
 
 3399    OPENSSL_free((
char *)context->psk_sni_entry_list[i].sni);
 
 3400    SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
 
 3402  if (context->psk_sni_count)
 
 3403    OPENSSL_free(context->psk_sni_entry_list);
 
 3408#if COAP_SERVER_SUPPORT 
 3412  SSL *nssl = NULL, *ssl = NULL;
 
 3413  coap_ssl_data *data;
 
 3414  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
 
 3419  nssl = SSL_new(dtls->ctx);
 
 3422  nbio = BIO_new(dtls->meth);
 
 3425  SSL_set_bio(nssl, nbio, nbio);
 
 3426  SSL_set_app_data(nssl, NULL);
 
 3427  SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
 
 3428  SSL_set_mtu(nssl, (
long)session->
mtu);
 
 3432  SSL_set_app_data(ssl, session);
 
 3434  rbio = SSL_get_rbio(ssl);
 
 3435  data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
 
 3438  data->session = session;
 
 3442  if (psk_hint != NULL && psk_hint->
length) {
 
 3443    char *hint = OPENSSL_malloc(psk_hint->
length + 1);
 
 3446      memcpy(hint, psk_hint->
s, psk_hint->
length);
 
 3447      hint[psk_hint->
length] = 
'\000';
 
 3448      SSL_use_psk_identity_hint(ssl, hint);
 
 3455  r = SSL_accept(ssl);
 
 3457    int err = SSL_get_error(ssl, r);
 
 3458    if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
 
 3476#if COAP_CLIENT_SUPPORT 
 3480  coap_openssl_context_t *context =
 
 3483  if (context->psk_pki_enabled & IS_PSK) {
 
 3488        SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
 
 3492    SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
 
 3493#if COAP_SERVER_SUPPORT 
 3494    SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
 
 3496    SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
 
 3499        SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
 
 3501#if !COAP_DISABLE_TCP 
 3503        SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
 
 3506      coap_log_debug(
"CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
 
 3509  if ((context->psk_pki_enabled & IS_PKI) ||
 
 3510      (context->psk_pki_enabled & (IS_PSK | IS_PKI)) == 0) {
 
 3517    if (!(context->psk_pki_enabled & IS_PKI)) {
 
 3534#if !COAP_DISABLE_TCP 
 3536      SSL_set_alpn_protos(ssl, coap_alpn, 
sizeof(coap_alpn));
 
 3541        SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
 
 3547      X509_VERIFY_PARAM *param;
 
 3549      param = X509_VERIFY_PARAM_new();
 
 3550      X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
 
 3551      SSL_set1_param(ssl, param);
 
 3552      X509_VERIFY_PARAM_free(param);
 
 3559                     SSL_VERIFY_CLIENT_ONCE |
 
 3560                     SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 
 3561                     tls_verify_call_back);
 
 3563      SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
 
 3570#if COAP_DTLS_RETRANSMIT_MS != 1000 
 3571#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
 3573    DTLS_set_timer_cb(ssl, timer_cb);
 
 3584  coap_ssl_data *data;
 
 3586  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
 
 3587  coap_dtls_context_t *dtls = &context->dtls;
 
 3589  ssl = SSL_new(dtls->ctx);
 
 3592  bio = BIO_new(dtls->meth);
 
 3595  data = (coap_ssl_data *)BIO_get_data(bio);
 
 3598  data->session = session;
 
 3599  SSL_set_bio(ssl, bio, bio);
 
 3600  SSL_set_app_data(ssl, session);
 
 3601  SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
 
 3602  SSL_set_mtu(ssl, (
long)session->
mtu);
 
 3604  if (!setup_client_ssl_session(session, ssl))
 
 3609  r = SSL_connect(ssl);
 
 3611    int ret = SSL_get_error(ssl, r);
 
 3612    if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
 
 3630  SSL *ssl = (SSL *)session->
tls;
 
 3632    SSL_set_mtu(ssl, (
long)session->
mtu);
 
 3638  SSL *ssl = (SSL *)session->
tls;
 
 3640    if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
 
 3641      int r = SSL_shutdown(ssl);
 
 3646    session->
tls = NULL;
 
 3654               const uint8_t *data, 
size_t data_len) {
 
 3656  SSL *ssl = (SSL *)session->
tls;
 
 3665  r = SSL_write(ssl, data, (
int)data_len);
 
 3668    int err = SSL_get_error(ssl, r);
 
 3669    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
 
 3672      if (err == SSL_ERROR_ZERO_RETURN)
 
 3674      else if (err == SSL_ERROR_SSL) {
 
 3675        unsigned long e = ERR_get_error();
 
 3677        coap_log_info(
"***%s: coap_dtls_send: cannot send PDU: %d: %s\n",
 
 3679                      ERR_GET_REASON(e), ERR_reason_error_string(e));
 
 3682        coap_log_info(
"***%s: coap_dtls_send: cannot send PDU: %d\n",
 
 3701    if (r == (ssize_t)data_len)
 
 3724  SSL *ssl = (SSL *)session->
tls;
 
 3725  coap_ssl_data *ssl_data;
 
 3729  rbio = ssl ? SSL_get_rbio(ssl) : NULL;
 
 3730  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
 
 3731  return ssl_data ? ssl_data->timeout : 1000;
 
 3740  SSL *ssl = (SSL *)session->
tls;
 
 3744      (DTLSv1_handle_timeout(ssl) < 0)) {
 
 3752#if COAP_SERVER_SUPPORT 
 3755                const uint8_t *data, 
size_t data_len) {
 
 3756  coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
 
 3757  coap_ssl_data *ssl_data;
 
 3761  SSL_set_mtu(dtls->ssl, (
long)session->
mtu);
 
 3762  rbio = dtls->ssl ? SSL_get_rbio(dtls->ssl) : NULL;
 
 3763  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
 
 3764  assert(ssl_data != NULL);
 
 3769  if (ssl_data->pdu_len) {
 
 3770    coap_log_err(
"** %s: Previous data not read %u bytes\n",
 
 3773  ssl_data->session = session;
 
 3774  ssl_data->pdu = data;
 
 3775  ssl_data->pdu_len = (unsigned)data_len;
 
 3776  r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
 
 3778    int err = SSL_get_error(dtls->ssl, r);
 
 3779    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
 
 3799  coap_ssl_data *ssl_data;
 
 3800  SSL *ssl = (SSL *)session->
tls;
 
 3803#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
 3807  assert(ssl != NULL);
 
 3809  int in_init = SSL_in_init(ssl);
 
 3811  rbio = ssl ? SSL_get_rbio(ssl) : NULL;
 
 3812  ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
 
 3813  assert(ssl_data != NULL);
 
 3819  if (ssl_data->pdu_len) {
 
 3820    coap_log_err(
"** %s: Previous data not read %u bytes\n",
 
 3823  ssl_data->pdu = data;
 
 3824  ssl_data->pdu_len = (unsigned)data_len;
 
 3827#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
 3831  r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
 
 3838    int err = SSL_get_error(ssl, r);
 
 3839    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
 
 3840      if (in_init && SSL_is_init_finished(ssl)) {
 
 3848      if (err == SSL_ERROR_ZERO_RETURN)        
 
 3850      else if (err == SSL_ERROR_SSL) {
 
 3851        unsigned long e = ERR_get_error();
 
 3853#if OPENSSL_VERSION_NUMBER >= 0x30000000L 
 3854#include <openssl/proverr.h> 
 3855        if (ERR_GET_REASON(e) == PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES && !retry) {
 
 3861        coap_log_info(
"***%s: coap_dtls_receive: cannot recv PDU: %d: %s\n",
 
 3863                      ERR_GET_REASON(e), ERR_reason_error_string(e));
 
 3866        coap_log_info(
"***%s: coap_dtls_receive: cannot send PDU %d\n",
 
 3885  if (ssl_data && ssl_data->pdu_len) {
 
 3887    coap_log_debug(
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
 
 3888    ssl_data->pdu_len = 0;
 
 3889    ssl_data->pdu = NULL;
 
 3896  unsigned int overhead = 37;
 
 3897  const SSL_CIPHER *s_ciph = NULL;
 
 3898  if (session->
tls != NULL)
 
 3899    s_ciph = SSL_get_current_cipher(session->
tls);
 
 3901    unsigned int ivlen, maclen, blocksize = 1, pad = 0;
 
 3903    const EVP_CIPHER *e_ciph;
 
 3907    e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
 
 3909    switch (EVP_CIPHER_mode(e_ciph)) {
 
 3910    case EVP_CIPH_GCM_MODE:
 
 3911      ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
 
 3912      maclen = EVP_GCM_TLS_TAG_LEN;
 
 3915    case EVP_CIPH_CCM_MODE:
 
 3916      ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
 
 3917      SSL_CIPHER_description(s_ciph, cipher, 
sizeof(cipher));
 
 3918      if (strstr(cipher, 
"CCM8"))
 
 3924    case EVP_CIPH_CBC_MODE:
 
 3925      e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
 
 3926      blocksize = EVP_CIPHER_block_size(e_ciph);
 
 3927      ivlen = EVP_CIPHER_iv_length(e_ciph);
 
 3929      maclen = EVP_MD_size(e_md);
 
 3932    case EVP_CIPH_STREAM_CIPHER:
 
 3939      SSL_CIPHER_description(s_ciph, cipher, 
sizeof(cipher));
 
 3946    overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
 
 3951#if !COAP_DISABLE_TCP 
 3952#if COAP_CLIENT_SUPPORT 
 3958  coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
 
 3959  coap_tls_context_t *tls = &context->tls;
 
 3961  ssl = SSL_new(tls->ctx);
 
 3964  bio = BIO_new(tls->meth);
 
 3967  BIO_set_data(bio, session);
 
 3968  SSL_set_bio(ssl, bio, bio);
 
 3969  SSL_set_app_data(ssl, session);
 
 3971  if (!setup_client_ssl_session(session, ssl))
 
 3974  r = SSL_connect(ssl);
 
 3976    int ret = SSL_get_error(ssl, r);
 
 3977    if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
 
 3979    if (ret == SSL_ERROR_WANT_READ)
 
 3981    if (ret == SSL_ERROR_WANT_WRITE) {
 
 3983#ifdef COAP_EPOLL_SUPPORT 
 3997  if (SSL_is_init_finished(ssl)) {
 
 4011#if COAP_SERVER_SUPPORT 
 4016  coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
 
 4020  ssl = SSL_new(tls->ctx);
 
 4023  bio = BIO_new(tls->meth);
 
 4026  BIO_set_data(bio, session);
 
 4027  SSL_set_bio(ssl, bio, bio);
 
 4028  SSL_set_app_data(ssl, session);
 
 4031  if (psk_hint != NULL && psk_hint->
length) {
 
 4032    char *hint = OPENSSL_malloc(psk_hint->
length + 1);
 
 4035      memcpy(hint, psk_hint->
s, psk_hint->
length);
 
 4036      hint[psk_hint->
length] = 
'\000';
 
 4037      SSL_use_psk_identity_hint(ssl, hint);
 
 4044  r = SSL_accept(ssl);
 
 4046    int err = SSL_get_error(ssl, r);
 
 4047    if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
 
 4049    if (err == SSL_ERROR_WANT_READ)
 
 4051    if (err == SSL_ERROR_WANT_WRITE) {
 
 4053#ifdef COAP_EPOLL_SUPPORT 
 4067  if (SSL_is_init_finished(ssl)) {
 
 4072#if COAP_DTLS_RETRANSMIT_MS != 1000 
 4073#if OPENSSL_VERSION_NUMBER >= 0x10101000L 
 4075    DTLS_set_timer_cb(ssl, timer_cb);
 
 4091  SSL *ssl = (SSL *)session->
tls;
 
 4093    if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
 
 4094      int r = SSL_shutdown(ssl);
 
 4099    session->
tls = NULL;
 
 4112  SSL *ssl = (SSL *)session->
tls;
 
 4118  in_init = !SSL_is_init_finished(ssl);
 
 4121  r = SSL_write(ssl, data, (
int)data_len);
 
 4124    int err = SSL_get_error(ssl, r);
 
 4125    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
 
 4126      if (in_init && SSL_is_init_finished(ssl)) {
 
 4132      if (err == SSL_ERROR_WANT_READ)
 
 4134      else if (err == SSL_ERROR_WANT_WRITE) {
 
 4136#ifdef COAP_EPOLL_SUPPORT 
 4146      if (err == SSL_ERROR_ZERO_RETURN)
 
 4148      else if (err == SSL_ERROR_SSL) {
 
 4149        unsigned long e = ERR_get_error();
 
 4151        coap_log_info(
"***%s: coap_tls_write: cannot send PDU: %d: %s\n",
 
 4153                      ERR_GET_REASON(e), ERR_reason_error_string(e));
 
 4156        coap_log_info(
"***%s: coap_tls_send: cannot send PDU: %d\n",
 
 4161  } 
else if (in_init && SSL_is_init_finished(ssl)) {
 
 4180    if (r == (ssize_t)data_len)
 
 4197  SSL *ssl = (SSL *)session->
tls;
 
 4205  in_init = !SSL_is_init_finished(ssl);
 
 4208  r = SSL_read(ssl, data, (
int)data_len);
 
 4210    int err = SSL_get_error(ssl, r);
 
 4211    if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
 
 4212      if (in_init && SSL_is_init_finished(ssl)) {
 
 4218      if (err == SSL_ERROR_WANT_READ)
 
 4220      if (err == SSL_ERROR_WANT_WRITE) {
 
 4222#ifdef COAP_EPOLL_SUPPORT 
 4232      if (err == SSL_ERROR_ZERO_RETURN)        
 
 4234      else if (err == SSL_ERROR_SSL) {
 
 4235        unsigned long e = ERR_get_error();
 
 4237        coap_log_info(
"***%s: coap_tls_read: cannot recv PDU: %d: %s\n",
 
 4239                      ERR_GET_REASON(e), ERR_reason_error_string(e));
 
 4247  } 
else if (in_init && SSL_is_init_finished(ssl)) {
 
 4273#if COAP_SERVER_SUPPORT 
 4276  EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new();
 
 4279    EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL);
 
 4287    EVP_MD_CTX_free(digest_ctx);
 
 4292                   const uint8_t *data,
 
 4294  return EVP_DigestUpdate(digest_ctx, data, data_len);
 
 4301  int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
 
 4308#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT 
 4310coap_crypto_output_errors(
const char *prefix) {
 
 4311#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN 
 4316  while ((e = ERR_get_error()))
 
 4319                  ERR_reason_error_string(e),
 
 4320                  ssl_function_definition(e));
 
 4330static struct hash_algs {
 
 4332  const EVP_MD *(*get_hash)(void);
 
 4341static const EVP_MD *
 
 4342get_hash_alg(
cose_alg_t alg, 
size_t *length) {
 
 4345  for (idx = 0; idx < 
sizeof(hashs) / 
sizeof(
struct hash_algs); idx++) {
 
 4346    if (hashs[idx].alg == alg) {
 
 4347      *length = hashs[idx].length;
 
 4348      return hashs[idx].get_hash();
 
 4351  coap_log_debug(
"get_hash_alg: COSE hash %d not supported\n", alg);
 
 4359  unsigned int length;
 
 4360  const EVP_MD *evp_md;
 
 4361  EVP_MD_CTX *evp_ctx = NULL;
 
 4365  if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) {
 
 4366    coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
 
 4369  evp_ctx = EVP_MD_CTX_new();
 
 4370  if (evp_ctx == NULL)
 
 4372  if (EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0)
 
 4375  if (EVP_DigestUpdate(evp_ctx, data->
s, data->
length) == 0)
 
 4381  if (EVP_DigestFinal_ex(evp_ctx, 
dummy->s, &length) == 0)
 
 4383  dummy->length = length;
 
 4384  if (hash_length < dummy->length)
 
 4385    dummy->length = hash_length;
 
 4387  EVP_MD_CTX_free(evp_ctx);
 
 4391  coap_crypto_output_errors(
"coap_crypto_hash");
 
 4394    EVP_MD_CTX_free(evp_ctx);
 
 4399#if COAP_OSCORE_SUPPORT 
 4405#include <openssl/evp.h> 
 4406#include <openssl/hmac.h> 
 4413static struct cipher_algs {
 
 4415  const EVP_CIPHER *(*get_cipher)(void);
 
 4420static const EVP_CIPHER *
 
 4424  for (idx = 0; idx < 
sizeof(ciphers) / 
sizeof(
struct cipher_algs); idx++) {
 
 4425    if (ciphers[idx].alg == alg)
 
 4426      return ciphers[idx].get_cipher();
 
 4428  coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
 
 4437static struct hmac_algs {
 
 4439  const EVP_MD *(*get_hmac)(void);
 
 4446static const EVP_MD *
 
 4450  for (idx = 0; idx < 
sizeof(hmacs) / 
sizeof(
struct hmac_algs); idx++) {
 
 4451    if (hmacs[idx].hmac_alg == hmac_alg)
 
 4452      return hmacs[idx].get_hmac();
 
 4454  coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
 
 4460  return get_cipher_alg(alg) != NULL;
 
 4469  return get_hmac_alg(hmac_alg) != NULL;
 
 4473  if (1 != (Func)) {                                                           \ 
 4482                         size_t *max_result_len) {
 
 4483  const EVP_CIPHER *cipher;
 
 4486  int result_len = (int)(*max_result_len & INT_MAX);
 
 4491  assert(params != NULL);
 
 4492  if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
 
 4499  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
 
 4502  C(EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL));
 
 4503  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
 
 4504  C(EVP_CIPHER_CTX_ctrl(ctx,
 
 4505                        EVP_CTRL_AEAD_SET_IVLEN,
 
 4508  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, NULL));
 
 4509  C(EVP_EncryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
 
 4512  C(EVP_EncryptUpdate(ctx, NULL, &result_len, NULL, (
int)data->
length));
 
 4513  if (aad && aad->
s && (aad->
length > 0)) {
 
 4514    C(EVP_EncryptUpdate(ctx, NULL, &result_len, aad->
s, (
int)aad->
length));
 
 4516  C(EVP_EncryptUpdate(ctx, result, &result_len, data->
s, (
int)data->
length));
 
 4519  C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp));
 
 4523  C(EVP_CIPHER_CTX_ctrl(ctx,
 
 4524                        EVP_CTRL_CCM_GET_TAG,
 
 4526                        result + result_len));
 
 4528  *max_result_len = result_len + ccm->
tag_len;
 
 4529  EVP_CIPHER_CTX_free(ctx);
 
 4533  coap_crypto_output_errors(
"coap_crypto_aead_encrypt");
 
 4542                         size_t *max_result_len) {
 
 4543  const EVP_CIPHER *cipher;
 
 4553  assert(params != NULL);
 
 4554  if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
 
 4566    memcpy(&rwtag, &tag, 
sizeof(rwtag));
 
 4569  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
 
 4571  C(EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL));
 
 4572  C(EVP_CIPHER_CTX_ctrl(ctx,
 
 4573                        EVP_CTRL_AEAD_SET_IVLEN,
 
 4576  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, rwtag));
 
 4577  C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
 
 4579  C(EVP_DecryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
 
 4581  C(EVP_DecryptUpdate(ctx, NULL, &len, NULL, (
int)data->
length));
 
 4582  if (aad && aad->
s && (aad->
length > 0)) {
 
 4583    C(EVP_DecryptUpdate(ctx, NULL, &len, aad->
s, (
int)aad->
length));
 
 4585  tmp = EVP_DecryptUpdate(ctx, result, &len, data->
s, (
int)data->
length);
 
 4586  EVP_CIPHER_CTX_free(ctx);
 
 4588    *max_result_len = 0;
 
 4591  *max_result_len = len;
 
 4595  coap_crypto_output_errors(
"coap_crypto_aead_decrypt");
 
 4604  unsigned int result_len;
 
 4605  const EVP_MD *evp_md;
 
 4612  if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
 
 4613    coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
 
 4619  result_len = (
unsigned int)
dummy->length;
 
 4627    dummy->length = result_len;
 
 4632  coap_crypto_output_errors(
"coap_crypto_hmac");
 
 4644#pragma GCC diagnostic ignored "-Wunused-function" 
#define COAP_RXBUFFER_SIZE
 
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
 
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing
 
void coap_epoll_ctl_mod(coap_socket_t *sock, uint32_t events, const char *func)
Epoll specific function to modify the state of events that epoll is tracking on the appropriate file ...
 
Library specific build wrapper for coap_internal.h.
 
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
 
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
 
int coap_dtls_context_set_pki(coap_context_t *ctx COAP_UNUSED, const coap_dtls_pki_t *setup_data COAP_UNUSED, const coap_dtls_role_t role COAP_UNUSED)
 
coap_tick_t coap_dtls_get_timeout(coap_session_t *session COAP_UNUSED, coap_tick_t now COAP_UNUSED)
 
ssize_t coap_tls_read(coap_session_t *session COAP_UNUSED, uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
 
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED)
 
int coap_dtls_receive(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
 
void * coap_dtls_get_tls(const coap_session_t *c_session COAP_UNUSED, coap_tls_library_t *tls_lib)
 
unsigned int coap_dtls_get_overhead(coap_session_t *session COAP_UNUSED)
 
int coap_dtls_context_load_pki_trust_store(coap_context_t *ctx COAP_UNUSED)
 
static coap_log_t dtls_log_level
 
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
 
ssize_t coap_dtls_send(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
 
ssize_t coap_tls_write(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
 
void coap_dtls_session_update_mtu(coap_session_t *session COAP_UNUSED)
 
int coap_dtls_context_set_pki_root_cas(coap_context_t *ctx COAP_UNUSED, const char *ca_file COAP_UNUSED, const char *ca_path COAP_UNUSED)
 
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
 
void coap_dtls_free_context(void *handle COAP_UNUSED)
 
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
 
void * coap_dtls_new_context(coap_context_t *coap_context COAP_UNUSED)
 
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
 
void coap_digest_free(coap_digest_ctx_t *digest_ctx)
Free off coap_digest_ctx_t.
 
int coap_digest_final(coap_digest_ctx_t *digest_ctx, coap_digest_t *digest_buffer)
Finalize the coap_digest information into the provided digest_buffer.
 
int coap_digest_update(coap_digest_ctx_t *digest_ctx, const uint8_t *data, size_t data_len)
Update the coap_digest information with the next chunk of data.
 
coap_digest_ctx_t * coap_digest_setup(void)
Initialize a coap_digest.
 
coap_tick_t coap_ticks_from_rt_us(uint64_t t)
Helper function that converts POSIX wallclock time in us to coap ticks.
 
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
 
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
 
int coap_handle_event_lkd(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
 
int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *msg, size_t msg_len)
Parses and interprets a CoAP datagram with context ctx.
 
int coap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, coap_bin_const_t *data, coap_bin_const_t **hmac)
Create a HMAC hash of the provided data.
 
int coap_crypto_aead_decrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Decrypt the provided encrypted data into plaintext.
 
int coap_crypto_aead_encrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Encrypt the provided plaintext data.
 
int coap_crypto_hash(cose_alg_t alg, const coap_bin_const_t *data, coap_bin_const_t **hash)
Create a hash of the provided data.
 
int coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg)
Check whether the defined hkdf algorithm is supported by the underlying crypto library.
 
int coap_crypto_check_cipher_alg(cose_alg_t alg)
Check whether the defined cipher algorithm is supported by the underlying crypto library.
 
void * coap_tls_new_server_session(coap_session_t *coap_session)
Create a TLS new server-side session.
 
const coap_bin_const_t * coap_get_session_client_psk_identity(const coap_session_t *coap_session)
Get the current client's PSK identity.
 
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
 
int coap_dtls_define_issue(coap_define_issue_key_t type, coap_define_issue_fail_t fail, coap_dtls_key_t *key, const coap_dtls_role_t role, int ret)
Report PKI DEFINE type issue.
 
void * coap_dtls_new_client_session(coap_session_t *coap_session)
Create a new client-side session.
 
void * coap_dtls_new_server_session(coap_session_t *coap_session)
Create a new DTLS server-side session.
 
int coap_dtls_hello(coap_session_t *coap_session, const uint8_t *data, size_t data_len)
Handling client HELLO messages from a new candiate peer.
 
int coap_dtls_set_cid_tuple_change(coap_context_t *context, uint8_t every)
Set the Connection ID client tuple frequency change for testing CIDs.
 
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
 
int coap_dtls_context_set_cpsk(coap_context_t *coap_context, coap_dtls_cpsk_t *setup_data)
Set the DTLS context's default client PSK information.
 
int coap_dtls_context_set_spsk(coap_context_t *coap_context, coap_dtls_spsk_t *setup_data)
Set the DTLS context's default server PSK information.
 
void coap_dtls_shutdown(void)
Close down the underlying (D)TLS Library layer.
 
const coap_bin_const_t * coap_get_session_client_psk_key(const coap_session_t *coap_session)
Get the current client's PSK key.
 
void * coap_tls_new_client_session(coap_session_t *coap_session)
Create a new TLS client-side session.
 
void coap_dtls_map_key_type_to_define(const coap_dtls_pki_t *setup_data, coap_dtls_key_t *key)
Map the PKI key definitions to the new DEFINE format.
 
const coap_bin_const_t * coap_get_session_server_psk_key(const coap_session_t *coap_session)
Get the current server's PSK key.
 
const coap_bin_const_t * coap_get_session_server_psk_hint(const coap_session_t *coap_session)
Get the current server's PSK identity hint.
 
@ COAP_DEFINE_KEY_PRIVATE
 
@ COAP_DEFINE_FAIL_NOT_SUPPORTED
 
#define COAP_DTLS_HINT_LENGTH
 
int coap_tls_engine_configure(coap_str_const_t *conf_mem)
Configure an ENGINE for a TLS library.
 
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
 
int coap_tls_engine_remove(void)
Remove a previously configured ENGINE from a TLS library.
 
@ COAP_PKI_KEY_DEF_PKCS11
The PKI key type is PKCS11 (pkcs11:...).
 
@ COAP_PKI_KEY_DEF_DER_BUF
The PKI key type is DER buffer (ASN.1).
 
@ COAP_PKI_KEY_DEF_PEM_BUF
The PKI key type is PEM buffer.
 
@ COAP_PKI_KEY_DEF_PEM
The PKI key type is PEM file.
 
@ COAP_PKI_KEY_DEF_ENGINE
The PKI key type is to be passed to ENGINE.
 
@ COAP_PKI_KEY_DEF_RPK_BUF
The PKI key type is RPK in buffer.
 
@ COAP_PKI_KEY_DEF_DER
The PKI key type is DER file.
 
@ COAP_PKI_KEY_DEF_PKCS11_RPK
The PKI key type is PKCS11 w/ RPK (pkcs11:...).
 
@ COAP_DTLS_ROLE_SERVER
Internal function invoked for server.
 
@ COAP_DTLS_ROLE_CLIENT
Internal function invoked for client.
 
@ COAP_PKI_KEY_DEFINE
The individual PKI key types are Definable.
 
@ COAP_ASN1_PKEY_DH
DH type.
 
@ COAP_ASN1_PKEY_NONE
NONE.
 
@ COAP_ASN1_PKEY_TLS1_PRF
TLS1_PRF type.
 
@ COAP_ASN1_PKEY_RSA2
RSA2 type.
 
@ COAP_ASN1_PKEY_DSA
DSA type.
 
@ COAP_ASN1_PKEY_DHX
DHX type.
 
@ COAP_ASN1_PKEY_DSA4
DSA4 type.
 
@ COAP_ASN1_PKEY_DSA2
DSA2 type.
 
@ COAP_ASN1_PKEY_RSA
RSA type.
 
@ COAP_ASN1_PKEY_DSA1
DSA1 type.
 
@ COAP_ASN1_PKEY_HKDF
HKDF type.
 
@ COAP_ASN1_PKEY_EC
EC type.
 
@ COAP_ASN1_PKEY_DSA3
DSA3 type.
 
@ COAP_ASN1_PKEY_HMAC
HMAC type.
 
@ COAP_ASN1_PKEY_CMAC
CMAC type.
 
@ COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
 
@ COAP_EVENT_DTLS_CLOSED
Triggerred when (D)TLS session closed.
 
@ COAP_EVENT_DTLS_CONNECTED
Triggered when (D)TLS session connected.
 
@ COAP_EVENT_DTLS_RENEGOTIATE
Triggered when (D)TLS session renegotiated.
 
@ COAP_EVENT_DTLS_ERROR
Triggered when (D)TLS error occurs.
 
#define coap_lock_callback_ret(r, func)
Dummy for no thread-safe code.
 
#define coap_log_debug(...)
 
coap_log_t coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
 
#define coap_dtls_log(level,...)
Logging function.
 
void coap_dtls_set_log_level(coap_log_t level)
Sets the (D)TLS logging level to the specified level.
 
const char * coap_session_str(const coap_session_t *session)
Get session description.
 
#define coap_log_info(...)
 
#define coap_log_warn(...)
 
#define coap_log_err(...)
 
#define coap_log(level,...)
Logging function.
 
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
 
int cose_get_hmac_alg_for_hkdf(cose_hkdf_alg_t hkdf_alg, cose_hmac_alg_t *hmac_alg)
 
@ COSE_HMAC_ALG_HMAC384_384
 
@ COSE_HMAC_ALG_HMAC256_256
 
@ COSE_HMAC_ALG_HMAC512_512
 
@ COSE_ALGORITHM_SHA_256_64
 
@ COSE_ALGORITHM_SHA_256_256
 
@ COSE_ALGORITHM_AES_CCM_16_64_128
 
@ COSE_ALGORITHM_AES_CCM_16_64_256
 
int coap_session_refresh_psk_hint(coap_session_t *session, const coap_bin_const_t *psk_hint)
Refresh the session's current Identity Hint (PSK).
 
int coap_session_refresh_psk_key(coap_session_t *session, const coap_bin_const_t *psk_key)
Refresh the session's current pre-shared key (PSK).
 
int coap_session_refresh_psk_identity(coap_session_t *session, const coap_bin_const_t *psk_identity)
Refresh the session's current pre-shared identity (PSK).
 
void coap_session_disconnected_lkd(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
 
@ COAP_SESSION_STATE_HANDSHAKE
 
void coap_delete_str_const(coap_str_const_t *s)
Deletes the given const string and releases any memory allocated.
 
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
 
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
 
coap_str_const_t * coap_new_str_const(const uint8_t *data, size_t size)
Returns a new const string object with at least size+1 bytes storage allocated, and the provided data...
 
int coap_dtls_cid_is_supported(void)
Check whether (D)TLS CID is available.
 
int coap_dtls_psk_is_supported(void)
Check whether (D)TLS PSK is available.
 
int coap_tls_is_supported(void)
Check whether TLS is available.
 
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
 
int coap_dtls_is_supported(void)
Check whether DTLS is available.
 
int coap_dtls_pki_is_supported(void)
Check whether (D)TLS PKI is available.
 
int coap_dtls_rpk_is_supported(void)
Check whether (D)TLS RPK is available.
 
int coap_dtls_pkcs11_is_supported(void)
Check whether (D)TLS PKCS11 is available.
 
CoAP binary data definition with const data.
 
size_t length
length of binary data
 
const uint8_t * s
read-only binary data
 
CoAP binary data definition.
 
The CoAP stack's global state is stored in a coap_context_t object.
 
coap_dtls_spsk_t spsk_setup_data
Contains the initial PSK server setup data.
 
The structure that holds the AES Crypto information.
 
size_t l
The number of bytes in the length field.
 
const uint8_t * nonce
must be exactly 15 - l bytes
 
coap_crypto_key_t key
The Key to use.
 
size_t tag_len
The size of the Tag.
 
The common structure that holds the Crypto information.
 
union coap_crypto_param_t::@2 params
 
coap_crypto_aes_ccm_t aes
Used if AES type encryption.
 
cose_alg_t alg
The COSE algorith to use.
 
The structure that holds the Client PSK information.
 
coap_bin_const_t identity
 
The structure used for defining the Client PSK setup data to be used.
 
uint8_t use_cid
Set to 1 if DTLS Connection ID is to be used.
 
void * ih_call_back_arg
Passed in to the Identity Hint callback function.
 
char * client_sni
If not NULL, SNI to use in client TLS setup.
 
coap_dtls_ih_callback_t validate_ih_call_back
Identity Hint check callback function.
 
uint8_t ec_jpake
Set to COAP_DTLS_CPSK_SETUP_VERSION to support this version of the struct.
 
The structure that holds the PKI key information.
 
coap_pki_key_define_t define
for definable type keys
 
union coap_dtls_key_t::@3 key
 
coap_pki_key_t key_type
key format type
 
The structure used for defining the PKI setup data to be used.
 
uint8_t allow_no_crl
1 ignore if CRL not there
 
void * cn_call_back_arg
Passed in to the CN callback function.
 
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
 
uint8_t use_cid
1 if DTLS Connection ID is to be used (Client only, server always enabled) if supported
 
uint8_t check_cert_revocation
1 if revocation checks wanted
 
coap_dtls_pki_sni_callback_t validate_sni_call_back
SNI check callback function.
 
uint8_t cert_chain_verify_depth
recommended depth is 3
 
coap_dtls_security_setup_t additional_tls_setup_call_back
Additional Security callback handler that is invoked when libcoap has done the standard,...
 
uint8_t allow_expired_certs
1 if expired certs are allowed
 
uint8_t verify_peer_cert
Set to COAP_DTLS_PKI_SETUP_VERSION to support this version of the struct.
 
char * client_sni
If not NULL, SNI to use in client TLS setup.
 
uint8_t allow_self_signed
1 if self-signed certs are allowed.
 
void * sni_call_back_arg
Passed in to the sni callback function.
 
coap_dtls_cn_callback_t validate_cn_call_back
CN check callback function.
 
uint8_t allow_expired_crl
1 if expired crl is allowed
 
uint8_t is_rpk_not_cert
1 is RPK instead of Public Certificate.
 
uint8_t check_common_ca
1 if peer cert is to be signed by the same CA as the local cert
 
coap_dtls_key_t pki_key
PKI key definition.
 
The structure that holds the Server Pre-Shared Key and Identity Hint information.
 
The structure used for defining the Server PSK setup data to be used.
 
coap_dtls_psk_sni_callback_t validate_sni_call_back
SNI check callback function.
 
coap_dtls_id_callback_t validate_id_call_back
Identity check callback function.
 
void * id_call_back_arg
Passed in to the Identity callback function.
 
uint8_t ec_jpake
Set to COAP_DTLS_SPSK_SETUP_VERSION to support this version of the struct.
 
void * sni_call_back_arg
Passed in to the SNI callback function.
 
coap_dtls_spsk_info_t psk_info
Server PSK definition.
 
coap_layer_write_t l_write
 
coap_layer_establish_t l_establish
 
coap_const_char_ptr_t public_cert
define: Public Cert
 
coap_asn1_privatekey_type_t private_key_type
define: ASN1 Private Key Type (if needed)
 
const char * user_pin
define: User pin to access type PKCS11.
 
coap_const_char_ptr_t private_key
define: Private Key
 
coap_const_char_ptr_t ca
define: Common CA Certificate
 
size_t public_cert_len
define Public Cert length (if needed)
 
size_t ca_len
define CA Cert length (if needed)
 
coap_pki_define_t private_key_def
define: Private Key type definition
 
size_t private_key_len
define Private Key length (if needed)
 
coap_pki_define_t ca_def
define: Common CA type definition
 
coap_pki_define_t public_cert_def
define: Public Cert type definition
 
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
 
unsigned int dtls_timeout_count
dtls setup retry counter
 
coap_bin_const_t * psk_key
If client, this field contains the current pre-shared key for server; When this field is NULL,...
 
coap_socket_t sock
socket object for the session, if any
 
coap_session_state_t state
current state of relationship with peer
 
coap_proto_t proto
protocol used
 
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
 
size_t mtu
path or CSM mtu (xmt)
 
int dtls_event
Tracking any (D)TLS events on this session.
 
void * tls
security parameters
 
uint16_t max_retransmit
maximum re-transmit count (default 4)
 
coap_context_t * context
session's context
 
coap_layer_func_t lfunc[COAP_LAYER_LAST]
Layer functions to use.
 
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
 
CoAP string data definition with const data.
 
const uint8_t * s
read-only string data
 
size_t length
length of string
 
The structure used for returning the underlying (D)TLS library information.
 
uint64_t built_version
(D)TLS Built against Library Version
 
coap_tls_library_t type
Library type.
 
uint64_t version
(D)TLS runtime Library Version
 
const char * s_byte
signed char ptr
 
const uint8_t * u_byte
unsigned char ptr