20#ifdef 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 size_t psk_sni_count;
171 psk_sni_entry *psk_sni_entry_list;
172} coap_openssl_context_t;
174#if COAP_SERVER_SUPPORT
175#if OPENSSL_VERSION_NUMBER < 0x10101000L
176static int psk_tls_server_name_call_back(SSL *ssl,
int *sd,
void *arg);
178static int psk_tls_client_hello_call_back(SSL *ssl,
int *al,
void *arg);
184 if (SSLeay() < 0x10100000L) {
185 coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
188#if OPENSSL_VERSION_NUMBER >= 0x10101000L
196 if (SSLeay() < 0x10101000L) {
197 coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
207 if (SSLeay() < 0x10100000L) {
208 coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
211#if OPENSSL_VERSION_NUMBER >= 0x10101000L
212 if (SSLeay() < 0x10101000L) {
213 coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
268static ENGINE *pkcs11_engine = NULL;
269static ENGINE *defined_engine = NULL;
273 SSL_load_error_strings();
275 ENGINE_load_dynamic();
282 ENGINE_finish(pkcs11_engine);
283 pkcs11_engine = NULL;
285 if (defined_engine) {
287 ENGINE_finish(defined_engine);
288 defined_engine = NULL;
301 return c_session->
tls;
307get_split_conf_entry(
const uint8_t **start,
size_t size,
const char *get_keyword,
309 const uint8_t *begin = *start;
312 const uint8_t *split;
318 kend = end = memchr(begin,
'\n', size);
324 if (end > begin && end[-1] ==
'\r')
327 if (begin[0] ==
'#' || (end - begin) == 0) {
329 size -= kend - begin + 1;
335 split = memchr(begin,
':', end - begin);
339 if ((
size_t)(split - begin) != strlen(get_keyword)) {
340 size -= kend - begin + 1;
344 if (memcmp(begin, get_keyword, split - begin)) {
345 size -= kend - begin + 1;
353 if ((end - begin) == 0)
356 split = memchr(begin,
':', end - begin);
368 if ((end - split) > 0) {
403 const uint8_t *start;
408 unsigned int defaults = 0;
409 int done_engine_id = 0;
410 int done_engine_init = 0;
416 end = start + conf_mem->
length;
418 if (defined_engine) {
419 coap_log_warn(
"coap_tls_engine_configure: Freeing off previous engine definition\n");
420 ENGINE_finish(defined_engine);
421 defined_engine = NULL;
425 if (!get_split_conf_entry(&start, end - start,
"engine", &engine_id, &p2)) {
426 coap_log_warn(
"coap_tls_engine_configure: engine not defined\n");
429 defined_engine = ENGINE_by_id((
const char *)engine_id->
s);
430 if (!defined_engine) {
431 coap_log_warn(
"coap_tls_engine_configure: engine '%s' not known\n", engine_id->
s);
441 while (get_split_conf_entry(&start, end - start,
"pre-cmd", &p1, &p2)) {
442 if (!ENGINE_ctrl_cmd_string(defined_engine, (
const char *)p1->
s, p2 ? (
const char *)p2->
s : NULL,
444 coap_log_warn(
"coap_tls_engine_configure: engine %s pre-cmd '%s:%s' failed\n",
445 (
const char *)engine_id->
s,
446 (
const char *)p1->
s, p2 ? (
const char *)p2->
s :
"(NULL)");
450 engine_id->
s, p1->
s, p2 ? (
const char *)p2->
s :
"(NULL)");
459 if (!ENGINE_init(defined_engine)) {
460 coap_log_warn(
"coap_tls_engine_configure: %s failed initialization\n", (
const char *)engine_id->
s);
463 done_engine_init = 1;
465 (
const char *)engine_id->
s);
470 while (get_split_conf_entry(&start, end - start,
"post-cmd", &p1, &p2)) {
471 if (!ENGINE_ctrl_cmd_string(defined_engine, (
const char *)p1->
s, p2 ? (
const char *)p2->
s : NULL,
473 coap_log_warn(
"coap_tls_engine_configure: %s post-cmd '%s:%s' failed\n", (
const char *)engine_id->
s,
474 (
const char *)p1->
s, p2 ? (
const char *)p2->
s :
"(NULL)");
478 (
const char *)engine_id->
s,
479 (
const char *)p1->
s, p2 ? (
const char *)p2->
s :
"(NULL)");
487 if (!get_split_conf_entry(&start, end - start,
"enable-methods", &p1, &p2)) {
488 coap_log_warn(
"coap_tls_engine_configure: enable-methods not found\n");
491 defaults = strtoul((
const char *)p1->
s, NULL, 0);
492 if (!ENGINE_set_default(defined_engine, defaults)) {
493 coap_log_warn(
"coap_tls_engine_configure: enable-methods 0x%x invalid\n", defaults);
508 ENGINE_free(defined_engine);
509 if (done_engine_init)
510 ENGINE_finish(defined_engine);
511 defined_engine = NULL;
520 if (defined_engine) {
521 ENGINE_finish(defined_engine);
522 defined_engine = NULL;
543typedef struct coap_ssl_st {
552coap_dgram_create(BIO *a) {
553 coap_ssl_data *data = NULL;
554 data = malloc(
sizeof(coap_ssl_data));
558 BIO_set_data(a, data);
559 memset(data, 0x00,
sizeof(coap_ssl_data));
564coap_dgram_destroy(BIO *a) {
568 data = (coap_ssl_data *)BIO_get_data(a);
575coap_dgram_read(BIO *a,
char *out,
int outl) {
577 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
580 if (data != NULL && data->pdu_len > 0) {
581 if (outl < (
int)data->pdu_len) {
582 memcpy(out, data->pdu, outl);
585 memcpy(out, data->pdu, data->pdu_len);
586 ret = (int)data->pdu_len;
588 if (!data->peekmode) {
595 BIO_clear_retry_flags(a);
597 BIO_set_retry_read(a);
603coap_dgram_write(BIO *a,
const char *in,
int inl) {
605 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
609#if COAP_SERVER_SUPPORT
610 && data->session->endpoint == NULL
614 BIO_clear_retry_flags(a);
618 ret = (int)data->session->sock.lfunc[
COAP_LAYER_TLS].l_write(data->session,
621 BIO_clear_retry_flags(a);
623 BIO_set_retry_write(a);
625 BIO_clear_retry_flags(a);
632coap_dgram_puts(BIO *a,
const char *pstr) {
633 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
637coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
639 coap_ssl_data *data = BIO_get_data(a);
644 case BIO_CTRL_GET_CLOSE:
645 ret = BIO_get_shutdown(a);
647 case BIO_CTRL_SET_CLOSE:
648 BIO_set_shutdown(a, (
int)num);
651 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
652 data->peekmode = (unsigned)num;
654 case BIO_CTRL_DGRAM_CONNECT:
657 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
658 case BIO_CTRL_DGRAM_GET_MTU:
659 case BIO_CTRL_DGRAM_SET_MTU:
660 case BIO_CTRL_DGRAM_QUERY_MTU:
661 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
666 case BIO_CTRL_DGRAM_MTU_DISCOVER:
667 case BIO_CTRL_DGRAM_SET_CONNECTED:
670 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
672 struct timeval *)ptr)->tv_usec);
676 case BIO_C_FILE_SEEK:
677 case BIO_C_FILE_TELL:
679 case BIO_CTRL_PENDING:
680 case BIO_CTRL_WPENDING:
681 case BIO_CTRL_DGRAM_GET_PEER:
682 case BIO_CTRL_DGRAM_SET_PEER:
683 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
684 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
685 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
686 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
687 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
688 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
689 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
690 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
699coap_dtls_generate_cookie(SSL *ssl,
700 unsigned char *cookie,
701 unsigned int *cookie_len) {
702 coap_dtls_context_t *dtls =
703 (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl));
704 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
705 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
706 r &= HMAC_Update(dtls->cookie_hmac,
707 (
const uint8_t *)&data->session->addr_info.local.addr,
708 (
size_t)data->session->addr_info.local.size);
709 r &= HMAC_Update(dtls->cookie_hmac,
710 (
const uint8_t *)&data->session->addr_info.remote.addr,
711 (
size_t)data->session->addr_info.remote.size);
712 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
717coap_dtls_verify_cookie(SSL *ssl,
718 const uint8_t *cookie,
719 unsigned int cookie_len) {
722 if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
723 cookie_len == len && memcmp(cookie, hmac, len) == 0)
729#if COAP_CLIENT_SUPPORT
731coap_dtls_psk_client_callback(SSL *ssl,
734 unsigned int max_identity_len,
736 unsigned int max_psk_len) {
738 coap_openssl_context_t *o_context;
746 if (c_session == NULL)
749 if (o_context == NULL)
753 temp.
s = hint ? (
const uint8_t *)hint : (const uint8_t *)
"";
754 temp.
length = strlen((
const char *)temp.
s);
758 (
const char *)temp.
s);
770 if (cpsk_info == NULL)
775 psk_identity = &cpsk_info->
identity;
776 psk_key = &cpsk_info->
key;
782 if (psk_identity == NULL || psk_key == NULL) {
788 if (!max_identity_len)
791 if (psk_identity->
length > max_identity_len) {
792 coap_log_warn(
"psk_identity too large, truncated to %d bytes\n",
796 max_identity_len = (
unsigned int)psk_identity->
length;
798 memcpy(identity, psk_identity->
s, max_identity_len);
799 identity[max_identity_len] =
'\000';
801 if (psk_key->
length > max_psk_len) {
806 max_psk_len = (
unsigned int)psk_key->
length;
808 memcpy(psk, psk_key->
s, max_psk_len);
813#if COAP_SERVER_SUPPORT
815coap_dtls_psk_server_callback(
817 const char *identity,
819 unsigned int max_psk_len
827 if (c_session == NULL)
833 lidentity.
s = identity ? (
const uint8_t *)identity : (const uint8_t *)
"";
834 lidentity.
length = strlen((
const char *)lidentity.
s);
838 (
int)lidentity.
length, (
const char *)lidentity.
s);
853 if (psk_key->
length > max_psk_len) {
858 max_psk_len = (
unsigned int)psk_key->
length;
860 memcpy(psk, psk_key->
s, max_psk_len);
866ssl_function_definition(
unsigned long e) {
867#if OPENSSL_VERSION_NUMBER >= 0x30000000L
871 static char buff[80];
873 snprintf(buff,
sizeof(buff),
" at %s:%s",
874 ERR_lib_error_string(e), ERR_func_error_string(e));
880coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
883 int w = where &~SSL_ST_MASK;
885 if (w & SSL_ST_CONNECT)
886 pstr =
"SSL_connect";
887 else if (w & SSL_ST_ACCEPT)
892 if (where & SSL_CB_LOOP) {
895 }
else if (where & SSL_CB_ALERT) {
897 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
898 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
900 if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
904 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
907 SSL_alert_type_string_long(ret),
908 SSL_alert_desc_string_long(ret));
909 }
else if (where & SSL_CB_EXIT) {
915 while ((e = ERR_get_error()))
918 ssl_function_definition(e));
920 }
else if (ret < 0) {
922 int err = SSL_get_error(ssl, ret);
923 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE &&
924 err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT &&
925 err != SSL_ERROR_WANT_X509_LOOKUP) {
929 while ((e = ERR_get_error()))
932 ssl_function_definition(e));
938 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
944coap_sock_create(BIO *a) {
950coap_sock_destroy(BIO *a) {
962coap_sock_read(BIO *a,
char *out,
int outl) {
971 BIO_set_retry_read(a);
974 BIO_clear_retry_flags(a);
987coap_sock_write(BIO *a,
const char *in,
int inl) {
995 BIO_clear_retry_flags(a);
997 BIO_set_retry_read(a);
1000 BIO_clear_retry_flags(a);
1004 (errno == EPIPE || errno == ECONNRESET)) {
1024coap_sock_puts(BIO *a,
const char *pstr) {
1025 return coap_sock_write(a, pstr, (
int)strlen(pstr));
1029coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
1040 case BIO_CTRL_SET_CLOSE:
1042 case BIO_CTRL_FLUSH:
1046 case BIO_CTRL_GET_CLOSE:
1055coap_set_user_prefs(SSL_CTX *ctx) {
1056 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1058#ifdef COAP_OPENSSL_SIGALGS
1059 SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
1060 SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
1063#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS)
1064 SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
1068#if COAP_DTLS_RETRANSMIT_MS != 1000
1069#if OPENSSL_VERSION_NUMBER >= 0x10101000L
1071timer_cb(SSL *s,
unsigned int timer_us) {
1074 return COAP_DTLS_RETRANSMIT_MS * 1000;
1076 return 2 * timer_us;
1083 coap_openssl_context_t *context;
1088 uint8_t cookie_secret[32];
1090 memset(context, 0,
sizeof(coap_openssl_context_t));
1093 context->dtls.ctx = SSL_CTX_new(DTLS_method());
1094 if (!context->dtls.ctx)
1096 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
1097 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
1098 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
1099 coap_set_user_prefs(context->dtls.ctx);
1100 memset(cookie_secret, 0,
sizeof(cookie_secret));
1101 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
1103 "Insufficient entropy for random cookie generation");
1104 coap_prng(cookie_secret,
sizeof(cookie_secret));
1106 context->dtls.cookie_hmac = HMAC_CTX_new();
1107 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret),
1108 EVP_sha256(), NULL))
1110 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
1111 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
1112 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
1113 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
1114#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1115 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_LEGACY_SERVER_CONNECT);
1117 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
1118 if (!context->dtls.meth)
1120 context->dtls.bio_addr = BIO_ADDR_new();
1121 if (!context->dtls.bio_addr)
1123 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
1124 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
1125 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
1126 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
1127 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
1128 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
1130#if !COAP_DISABLE_TCP
1132 context->tls.ctx = SSL_CTX_new(TLS_method());
1133 if (!context->tls.ctx)
1135 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
1136 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
1137 coap_set_user_prefs(context->tls.ctx);
1138 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
1139 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
1140 if (!context->tls.meth)
1142 BIO_meth_set_write(context->tls.meth, coap_sock_write);
1143 BIO_meth_set_read(context->tls.meth, coap_sock_read);
1144 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
1145 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
1146 BIO_meth_set_create(context->tls.meth, coap_sock_create);
1147 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
1158#if COAP_SERVER_SUPPORT
1163 coap_openssl_context_t *o_context =
1167 if (!setup_data || !o_context)
1170 SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
1171 coap_dtls_psk_server_callback);
1172#if !COAP_DISABLE_TCP
1173 SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
1174 coap_dtls_psk_server_callback);
1180 SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
1181#if !COAP_DISABLE_TCP
1182 SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
1186#if OPENSSL_VERSION_NUMBER < 0x10101000L
1187 SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
1189 SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
1190 psk_tls_server_name_call_back);
1191#if !COAP_DISABLE_TCP
1192 SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
1194 SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
1195 psk_tls_server_name_call_back);
1198 SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
1199 psk_tls_client_hello_call_back,
1201#if !COAP_DISABLE_TCP
1202 SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
1203 psk_tls_client_hello_call_back,
1209 if (!o_context->dtls.ssl) {
1211 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
1212 if (!o_context->dtls.ssl)
1214 bio = BIO_new(o_context->dtls.meth);
1216 SSL_free(o_context->dtls.ssl);
1217 o_context->dtls.ssl = NULL;
1220 SSL_set_bio(o_context->dtls.ssl, bio, bio);
1221 SSL_set_app_data(o_context->dtls.ssl, NULL);
1222 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1225 o_context->psk_pki_enabled |= IS_PSK;
1230#if COAP_CLIENT_SUPPORT
1235 coap_openssl_context_t *o_context =
1239 if (!setup_data || !o_context)
1242 if (!o_context->dtls.ssl) {
1244 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
1245 if (!o_context->dtls.ssl)
1247 bio = BIO_new(o_context->dtls.meth);
1249 SSL_free(o_context->dtls.ssl);
1250 o_context->dtls.ssl = NULL;
1253 SSL_set_bio(o_context->dtls.ssl, bio, bio);
1254 SSL_set_app_data(o_context->dtls.ssl, NULL);
1255 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1258 o_context->psk_pki_enabled |= IS_PSK;
1264map_key_type(
int asn1_private_key_type
1266 switch (asn1_private_key_type) {
1268 return EVP_PKEY_NONE;
1270 return EVP_PKEY_RSA;
1272 return EVP_PKEY_RSA2;
1274 return EVP_PKEY_DSA;
1276 return EVP_PKEY_DSA1;
1278 return EVP_PKEY_DSA2;
1280 return EVP_PKEY_DSA3;
1282 return EVP_PKEY_DSA4;
1286 return EVP_PKEY_DHX;
1290 return EVP_PKEY_HMAC;
1292 return EVP_PKEY_CMAC;
1294 return EVP_PKEY_TLS1_PRF;
1296 return EVP_PKEY_HKDF;
1298 coap_log_warn(
"*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
1299 asn1_private_key_type);
1304#if !COAP_DISABLE_TCP
1305static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
1307#if COAP_SERVER_SUPPORT
1310 const unsigned char **out,
1311 unsigned char *outlen,
1312 const unsigned char *in,
1316 unsigned char *tout = NULL;
1319 return SSL_TLSEXT_ERR_NOACK;
1320 ret = SSL_select_next_proto(&tout,
1327 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
1333add_ca_to_cert_store(X509_STORE *st, X509 *x509) {
1337 while (ERR_get_error() != 0) {
1340 if (!X509_STORE_add_cert(st, x509)) {
1341 while ((e = ERR_get_error()) != 0) {
1342 int r = ERR_GET_REASON(e);
1343 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1346 ERR_reason_error_string(e),
1347 ssl_function_definition(e));
1354missing_ENGINE_load_cert(ENGINE *engine,
const char *cert_id) {
1356 const char *cert_id;
1360 params.cert_id = cert_id;
1364 if (!ENGINE_ctrl_cmd(engine,
"LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
1371check_pkcs11_engine(
void) {
1372 static int already_tried = 0;
1377 if (!pkcs11_engine) {
1378 pkcs11_engine = ENGINE_by_id(COAP_OPENSSL_PKCS11_ENGINE_ID);
1379 if (!pkcs11_engine) {
1380 coap_log_err(
"*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL %s engine\n",
1381 COAP_OPENSSL_PKCS11_ENGINE_ID);
1385 if (!ENGINE_init(pkcs11_engine)) {
1387 ENGINE_free(pkcs11_engine);
1388 pkcs11_engine = NULL;
1389 coap_log_err(
"*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1397 ENGINE_free(pkcs11_engine);
1402#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT
1405install_engine_public_cert_ctx(ENGINE *engine, SSL_CTX *ctx,
1406 const char *public_cert) {
1409 x509 = missing_ENGINE_load_cert(engine, public_cert);
1417 if (!SSL_CTX_use_certificate(ctx, x509)) {
1418 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1430install_engine_private_key_ctx(ENGINE *engine, SSL_CTX *ctx,
1431 const char *private_key) {
1432 EVP_PKEY *pkey = ENGINE_load_private_key(engine,
1443 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1444 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1448 EVP_PKEY_free(pkey);
1451 EVP_PKEY_free(pkey);
1456install_engine_ca_ctx(ENGINE *engine, SSL_CTX *ctx,
const char *ca) {
1460 x509 = missing_ENGINE_load_cert(engine,
1464 "%s CA Certificate\n",
1469 if (!SSL_CTX_add_client_CA(ctx, x509)) {
1470 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1471 "%s CA Certificate\n",
1477 st = SSL_CTX_get_cert_store(ctx);
1478 add_ca_to_cert_store(st, x509);
1484load_in_cas_ctx(SSL_CTX *ctx,
1485 const char *ca_file) {
1486 STACK_OF(X509_NAME) *cert_names;
1490 char *rw_var = NULL;
1491 cert_names = SSL_load_client_CA_file(ca_file);
1492 if (cert_names != NULL)
1493 SSL_CTX_set_client_CA_list(ctx, cert_names);
1495 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1502 st = SSL_CTX_get_cert_store(ctx);
1503 in = BIO_new(BIO_s_file());
1505 memcpy(&rw_var, &ca_file,
sizeof(rw_var));
1506 if (!BIO_read_filename(in, rw_var)) {
1513 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
1515 add_ca_to_cert_store(st, x);
1523setup_pki_server(SSL_CTX *ctx,
1539 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1541 SSL_FILETYPE_PEM))) {
1551 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1553 if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
1557 EVP_PKEY_free(pkey);
1565 EVP_PKEY_free(pkey);
1577 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1579 SSL_FILETYPE_ASN1))) {
1597 if (!check_pkcs11_engine()) {
1602 if (ENGINE_ctrl_cmd_string(pkcs11_engine,
1605 coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1610 if (!install_engine_private_key_ctx(pkcs11_engine, ctx,
1618 if (!defined_engine ||
1619 !install_engine_private_key_ctx(defined_engine, ctx,
1646 if (!(SSL_CTX_use_certificate_file(ctx,
1648 SSL_FILETYPE_PEM))) {
1658 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1660 if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
1684 if (!(SSL_CTX_use_certificate_file(ctx,
1686 SSL_FILETYPE_ASN1))) {
1694 !(SSL_CTX_use_certificate_ASN1(ctx,
1703 if (!check_pkcs11_engine()) {
1706 if (!install_engine_public_cert_ctx(pkcs11_engine, ctx,
1714 if (!defined_engine ||
1715 !install_engine_public_cert_ctx(defined_engine, ctx,
1753 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
1757 if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
1759 add_ca_to_cert_store(st, x);
1760 SSL_CTX_add_client_CA(ctx, x);
1776 if (!(SSL_CTX_use_certificate_file(ctx,
1778 SSL_FILETYPE_ASN1))) {
1791 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1799 st = SSL_CTX_get_cert_store(ctx);
1800 add_ca_to_cert_store(st, x509);
1805 if (!check_pkcs11_engine()) {
1808 if (!install_engine_ca_ctx(pkcs11_engine, ctx,
1816 if (!defined_engine ||
1817 !install_engine_ca_ctx(defined_engine, ctx,
1836#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT
1839install_engine_public_cert(ENGINE *engine, SSL *ssl,
const char *public_cert,
1843 x509 = missing_ENGINE_load_cert(engine, public_cert);
1851 if (!SSL_use_certificate(ssl, x509)) {
1852 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1864install_engine_private_key(ENGINE *engine, SSL *ssl,
const char *private_key,
1866 EVP_PKEY *pkey = ENGINE_load_private_key(engine,
1877 if (!SSL_use_PrivateKey(ssl, pkey)) {
1878 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1882 EVP_PKEY_free(pkey);
1885 EVP_PKEY_free(pkey);
1890install_engine_ca(ENGINE *engine, SSL *ssl,
const char *ca,
1893 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1896 x509 = missing_ENGINE_load_cert(engine,
1900 "%s CA Certificate\n",
1905 if (!SSL_add_client_CA(ssl, x509)) {
1906 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1907 "%s CA Certificate\n",
1913 st = SSL_CTX_get_cert_store(ctx);
1914 add_ca_to_cert_store(st, x509);
1920load_in_cas(SSL *ssl,
1925 char *rw_var = NULL;
1926 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1929 STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(ca_file);
1931 if (cert_names != NULL)
1932 SSL_set_client_CA_list(ssl, cert_names);
1939 in = BIO_new(BIO_s_file());
1941 memcpy(&rw_var, &ca_file,
sizeof(rw_var));
1942 if (!BIO_read_filename(in, rw_var)) {
1946 st = SSL_CTX_get_cert_store(ctx);
1948 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
1950 add_ca_to_cert_store(st, x);
1958setup_pki_ssl(SSL *ssl,
1974 if (!(SSL_use_PrivateKey_file(ssl,
1976 SSL_FILETYPE_PEM))) {
1986 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1988 if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
1992 EVP_PKEY_free(pkey);
2000 EVP_PKEY_free(pkey);
2012 if (!(SSL_use_PrivateKey_file(ssl,
2014 SSL_FILETYPE_ASN1))) {
2032 if (!check_pkcs11_engine()) {
2037 if (ENGINE_ctrl_cmd_string(pkcs11_engine,
2040 coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
2045 if (!install_engine_private_key(pkcs11_engine, ssl,
2054 if (!defined_engine ||
2055 !install_engine_private_key(defined_engine, ssl,
2084 if (!(SSL_use_certificate_file(ssl,
2086 SSL_FILETYPE_PEM))) {
2096 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
2098 if (!cert || !SSL_use_certificate(ssl, cert)) {
2122 if (!(SSL_use_certificate_file(ssl,
2124 SSL_FILETYPE_ASN1))) {
2132 !(SSL_use_certificate_ASN1(ssl,
2141 if (!check_pkcs11_engine()) {
2144 if (!install_engine_public_cert(pkcs11_engine, ssl,
2153 if (!defined_engine ||
2154 !install_engine_public_cert(defined_engine, ssl,
2193 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
2195 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
2199 if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
2201 add_ca_to_cert_store(st, x);
2202 SSL_add_client_CA(ssl, x);
2218 if (!(SSL_use_certificate_file(ssl,
2220 SSL_FILETYPE_ASN1))) {
2232 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
2235 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
2244 st = SSL_CTX_get_cert_store(ctx);
2245 add_ca_to_cert_store(st, x509);
2250 if (!check_pkcs11_engine()) {
2253 if (!install_engine_ca(pkcs11_engine, ssl,
2262 if (!defined_engine ||
2263 !install_engine_ca(defined_engine, ssl,
2284get_san_or_cn_from_cert(X509 *x509) {
2288 STACK_OF(GENERAL_NAME) *san_list;
2291 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
2293 int san_count = sk_GENERAL_NAME_num(san_list);
2295 for (n = 0; n < san_count; n++) {
2296 const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n);
2298 if (name->type == GEN_DNS) {
2299 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
2302 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name))
2304 cn = OPENSSL_strdup(dns_name);
2305 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
2309 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
2312 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
2315 n = (int)strlen(buffer) - 3;
2318 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
2319 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
2328 char *ecn = strchr(cn,
'/');
2330 return OPENSSL_strndup(cn, ecn-cn);
2332 return OPENSSL_strdup(cn);
2340tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
2341 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
2342 SSL_get_ex_data_X509_STORE_CTX_idx());
2344 coap_openssl_context_t *context =
2347 int depth = X509_STORE_CTX_get_error_depth(ctx);
2348 int err = X509_STORE_CTX_get_error(ctx);
2349 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
2350 char *cn = get_san_or_cn_from_cert(x509);
2351 int keep_preverify_ok = preverify_ok;
2353 if (!preverify_ok) {
2355 case X509_V_ERR_CERT_NOT_YET_VALID:
2356 case X509_V_ERR_CERT_HAS_EXPIRED:
2360 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
2364 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
2368 case X509_V_ERR_UNABLE_TO_GET_CRL:
2372 case X509_V_ERR_CRL_NOT_YET_VALID:
2373 case X509_V_ERR_CRL_HAS_EXPIRED:
2377 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
2378 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
2379 case X509_V_ERR_AKID_SKID_MISMATCH:
2389 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
2390 X509_STORE_CTX_set_error(ctx, err);
2392 if (!preverify_ok) {
2393 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
2396 "Unknown CA", cn ? cn :
"?", depth);
2400 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
2405 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
2410 int length = i2d_X509(x509, NULL);
2412 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
2415 i2d_X509(x509, &base_buf2);
2417 depth, preverify_ok,
2420 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
2422 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
2426 OPENSSL_free(base_buf);
2429 return preverify_ok;
2432#if COAP_SERVER_SUPPORT
2433#if OPENSSL_VERSION_NUMBER < 0x10101000L
2443tls_secret_call_back(SSL *ssl,
2446 STACK_OF(SSL_CIPHER) *peer_ciphers,
2450 int psk_requested = 0;
2455 assert(session != NULL);
2456 assert(session->
context != NULL);
2457 if (session == NULL ||
2465 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2466 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2469 SSL_CIPHER_get_name(peer_cipher));
2470 if (strstr(SSL_CIPHER_get_name(peer_cipher),
"PSK")) {
2476 if (!psk_requested) {
2483 SSL_VERIFY_CLIENT_ONCE |
2484 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2485 tls_verify_call_back);
2487 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2496 X509_VERIFY_PARAM *param;
2498 param = X509_VERIFY_PARAM_new();
2499 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2500 SSL_set1_param(ssl, param);
2501 X509_VERIFY_PARAM_free(param);
2523 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2524 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2539tls_server_name_call_back(SSL *ssl,
2545 return SSL_TLSEXT_ERR_NOACK;
2551 coap_openssl_context_t *context =
2553 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2556 if (!sni || !sni[0]) {
2559 for (i = 0; i < context->sni_count; i++) {
2560 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2564 if (i == context->sni_count) {
2570 return SSL_TLSEXT_ERR_ALERT_FATAL;
2575 ctx = SSL_CTX_new(DTLS_method());
2578 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2579 SSL_CTX_set_app_data(ctx, &context->dtls);
2580 SSL_CTX_set_read_ahead(ctx, 1);
2581 coap_set_user_prefs(ctx);
2582 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2583 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2584 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2585 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2587#if !COAP_DISABLE_TCP
2590 ctx = SSL_CTX_new(TLS_method());
2593 SSL_CTX_set_app_data(ctx, &context->tls);
2594 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2595 coap_set_user_prefs(ctx);
2596 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2597 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2600 sni_setup_data = *setup_data;
2601 sni_setup_data.
pki_key = *new_entry;
2602 setup_pki_server(ctx, &sni_setup_data);
2604 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2605 (context->sni_count+1)*
sizeof(sni_entry));
2606 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2607 context->sni_entry_list[context->sni_count].ctx = ctx;
2608 context->sni_count++;
2610 SSL_set_SSL_CTX(ssl, context->sni_entry_list[i].ctx);
2611 SSL_clear_options(ssl, 0xFFFFFFFFL);
2612 SSL_set_options(ssl, SSL_CTX_get_options(context->sni_entry_list[i].ctx));
2619 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2620 return SSL_TLSEXT_ERR_OK;
2623 return SSL_TLSEXT_ERR_ALERT_WARNING;
2635psk_tls_server_name_call_back(SSL *ssl,
2642 return SSL_TLSEXT_ERR_NOACK;
2648 coap_openssl_context_t *o_context =
2650 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2654 if (!sni || !sni[0]) {
2657 for (i = 0; i < o_context->psk_sni_count; i++) {
2658 if (!strcasecmp(sni, (
char *)o_context->psk_sni_entry_list[i].sni)) {
2662 if (i == o_context->psk_sni_count) {
2669 return SSL_TLSEXT_ERR_ALERT_FATAL;
2674 ctx = SSL_CTX_new(DTLS_method());
2677 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2678 SSL_CTX_set_app_data(ctx, &o_context->dtls);
2679 SSL_CTX_set_read_ahead(ctx, 1);
2680 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2681 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2682 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2683 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2684 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2686#if !COAP_DISABLE_TCP
2689 ctx = SSL_CTX_new(TLS_method());
2692 SSL_CTX_set_app_data(ctx, &o_context->tls);
2693 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2694 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2695 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2696 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2700 o_context->psk_sni_entry_list =
2701 OPENSSL_realloc(o_context->psk_sni_entry_list,
2702 (o_context->psk_sni_count+1)*
sizeof(psk_sni_entry));
2703 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2704 OPENSSL_strdup(sni);
2705 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2707 o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
2709 o_context->psk_sni_count++;
2711 SSL_set_SSL_CTX(ssl, o_context->psk_sni_entry_list[i].ctx);
2712 SSL_clear_options(ssl, 0xFFFFFFFFL);
2713 SSL_set_options(ssl,
2714 SSL_CTX_get_options(o_context->psk_sni_entry_list[i].ctx));
2716 &o_context->psk_sni_entry_list[i].psk_info.key);
2717 snprintf(lhint,
sizeof(lhint),
"%.*s",
2718 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2719 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2720 SSL_use_psk_identity_hint(ssl, lhint);
2727 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2728 return SSL_TLSEXT_ERR_OK;
2731 return SSL_TLSEXT_ERR_ALERT_WARNING;
2744tls_client_hello_call_back(SSL *ssl,
2749 coap_openssl_context_t *dtls_context;
2751 int psk_requested = 0;
2752 const unsigned char *out;
2756 *al = SSL_AD_INTERNAL_ERROR;
2757 return SSL_CLIENT_HELLO_ERROR;
2760 assert(session != NULL);
2761 assert(session->
context != NULL);
2763 if (session == NULL ||
2766 *al = SSL_AD_INTERNAL_ERROR;
2767 return SSL_CLIENT_HELLO_ERROR;
2770 setup_data = &dtls_context->setup_data;
2778 size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
2779 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
2780 STACK_OF(SSL_CIPHER) *scsvc = NULL;
2782 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
2783 SSL_client_hello_isv2(ssl),
2784 &peer_ciphers, &scsvc)) {
2786 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2787 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2790 "Client cipher: %s (%04x)\n",
2791 SSL_CIPHER_get_name(peer_cipher),
2792 SSL_CIPHER_get_protocol_id(peer_cipher));
2793 if (strstr(SSL_CIPHER_get_name(peer_cipher),
"PSK")) {
2799 sk_SSL_CIPHER_free(peer_ciphers);
2800 sk_SSL_CIPHER_free(scsvc);
2803 if (psk_requested) {
2809 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2815 return SSL_CLIENT_HELLO_SUCCESS;
2825 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
2828 for (ii = 0; ii < outlen; ii++) {
2844 *al = SSL_AD_UNSUPPORTED_EXTENSION;
2845 return SSL_CLIENT_HELLO_ERROR;
2854 coap_openssl_context_t *context =
2856 const char *sni =
"";
2857 char *sni_tmp = NULL;
2860 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2862 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2863 out[2] == TLSEXT_NAMETYPE_host_name &&
2864 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2868 sni_tmp = OPENSSL_malloc(outlen+1);
2869 sni_tmp[outlen] =
'\000';
2870 memcpy(sni_tmp, out, outlen);
2874 for (i = 0; i < context->sni_count; i++) {
2875 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2879 if (i == context->sni_count) {
2886 *al = SSL_AD_UNRECOGNIZED_NAME;
2887 return SSL_CLIENT_HELLO_ERROR;
2891 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2892 (context->sni_count+1)*
sizeof(sni_entry));
2893 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2894 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
2895 context->sni_count++;
2898 OPENSSL_free(sni_tmp);
2900 sni_setup_data = *setup_data;
2901 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
2913 SSL_VERIFY_CLIENT_ONCE |
2914 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2915 tls_verify_call_back);
2917 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2926 X509_VERIFY_PARAM *param;
2928 param = X509_VERIFY_PARAM_new();
2929 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2930 SSL_set1_param(ssl, param);
2931 X509_VERIFY_PARAM_free(param);
2938 return SSL_CLIENT_HELLO_SUCCESS;
2950psk_tls_client_hello_call_back(SSL *ssl,
2955 coap_openssl_context_t *o_context;
2957 const unsigned char *out;
2963 if (!c_session || !c_session->
context) {
2976 const char *sni =
"";
2977 char *sni_tmp = NULL;
2981 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2983 (((out[0]<<8) + out[1] +2) == (
int)outlen) &&
2984 out[2] == TLSEXT_NAMETYPE_host_name &&
2985 (((out[3]<<8) + out[4] +2 +3) == (
int)outlen)) {
2989 sni_tmp = OPENSSL_malloc(outlen+1);
2991 sni_tmp[outlen] =
'\000';
2992 memcpy(sni_tmp, out, outlen);
2998 for (i = 0; i < o_context->psk_sni_count; i++) {
2999 if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
3003 if (i == o_context->psk_sni_count) {
3007 psk_sni_entry *tmp_entry;
3013 *al = SSL_AD_UNRECOGNIZED_NAME;
3014 return SSL_CLIENT_HELLO_ERROR;
3018 OPENSSL_realloc(o_context->psk_sni_entry_list,
3019 (o_context->psk_sni_count+1)*
sizeof(sni_entry));
3021 o_context->psk_sni_entry_list = tmp_entry;
3022 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
3023 OPENSSL_strdup(sni);
3024 if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
3025 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
3027 o_context->psk_sni_count++;
3032 OPENSSL_free(sni_tmp);
3035 &o_context->psk_sni_entry_list[i].psk_info.hint)
3040 &o_context->psk_sni_entry_list[i].psk_info.key)
3044 if (o_context->psk_sni_entry_list[i].psk_info.hint.s) {
3045 snprintf(lhint,
sizeof(lhint),
"%.*s",
3046 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
3047 o_context->psk_sni_entry_list[i].psk_info.hint.s);
3048 SSL_use_psk_identity_hint(ssl, lhint);
3051 return SSL_CLIENT_HELLO_SUCCESS;
3054 *al = SSL_AD_INTERNAL_ERROR;
3055 return SSL_CLIENT_HELLO_ERROR;
3064 coap_openssl_context_t *context =
3069 context->setup_data = *setup_data;
3075 if (!defined_engine) {
3076 coap_log_warn(
"setup_pki: OpenSSL Engine not configured, PKI not set up\n");
3082 if (!context->setup_data.verify_peer_cert) {
3084 context->setup_data.check_common_ca = 0;
3086 context->setup_data.allow_self_signed = 1;
3087 context->setup_data.allow_expired_certs = 1;
3088 context->setup_data.cert_chain_validation = 1;
3089 context->setup_data.cert_chain_verify_depth = 10;
3090 context->setup_data.check_cert_revocation = 1;
3091 context->setup_data.allow_no_crl = 1;
3092 context->setup_data.allow_expired_crl = 1;
3093 context->setup_data.allow_bad_md_hash = 1;
3094 context->setup_data.allow_short_rsa_length = 1;
3096#if COAP_SERVER_SUPPORT
3098 if (context->dtls.ctx) {
3100#if OPENSSL_VERSION_NUMBER < 0x10101000L
3101 if (!setup_pki_server(context->dtls.ctx, setup_data))
3110#if OPENSSL_VERSION_NUMBER < 0x10101000L
3111 if (SSLeay() >= 0x10101000L) {
3112 coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so "
3113 "no certificate checking\n",
3114 OPENSSL_VERSION_NUMBER, SSLeay());
3116 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
3117 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
3118 tls_server_name_call_back);
3120 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
3121 tls_client_hello_call_back,
3125#if !COAP_DISABLE_TCP
3126 if (context->tls.ctx) {
3128#if OPENSSL_VERSION_NUMBER < 0x10101000L
3129 if (!setup_pki_server(context->tls.ctx, setup_data))
3138#if OPENSSL_VERSION_NUMBER < 0x10101000L
3139 if (SSLeay() >= 0x10101000L) {
3140 coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so "
3141 "no certificate checking\n",
3142 OPENSSL_VERSION_NUMBER, SSLeay());
3144 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
3145 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
3146 tls_server_name_call_back);
3148 SSL_CTX_set_client_hello_cb(context->tls.ctx,
3149 tls_client_hello_call_back,
3153 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
3161 if (!context->dtls.ssl) {
3163 context->dtls.ssl = SSL_new(context->dtls.ctx);
3164 if (!context->dtls.ssl)
3166 bio = BIO_new(context->dtls.meth);
3168 SSL_free(context->dtls.ssl);
3169 context->dtls.ssl = NULL;
3172 SSL_set_bio(context->dtls.ssl, bio, bio);
3173 SSL_set_app_data(context->dtls.ssl, NULL);
3174 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
3177 context->psk_pki_enabled |= IS_PKI;
3183 const char *ca_file,
3186 coap_openssl_context_t *context =
3188 if (context->dtls.ctx) {
3189 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
3191 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
3195#if !COAP_DISABLE_TCP
3196 if (context->tls.ctx) {
3197 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
3199 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
3209 coap_openssl_context_t *context =
3211 return context->psk_pki_enabled ? 1 : 0;
3218 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
3220 if (context->dtls.ssl)
3221 SSL_free(context->dtls.ssl);
3222 if (context->dtls.ctx)
3223 SSL_CTX_free(context->dtls.ctx);
3224 if (context->dtls.cookie_hmac)
3225 HMAC_CTX_free(context->dtls.cookie_hmac);
3226 if (context->dtls.meth)
3227 BIO_meth_free(context->dtls.meth);
3228 if (context->dtls.bio_addr)
3229 BIO_ADDR_free(context->dtls.bio_addr);
3230#if !COAP_DISABLE_TCP
3231 if (context->tls.ctx)
3232 SSL_CTX_free(context->tls.ctx);
3233 if (context->tls.meth)
3234 BIO_meth_free(context->tls.meth);
3236 for (i = 0; i < context->sni_count; i++) {
3237 OPENSSL_free(context->sni_entry_list[i].sni);
3238#if OPENSSL_VERSION_NUMBER < 0x10101000L
3239 SSL_CTX_free(context->sni_entry_list[i].ctx);
3242 if (context->sni_count)
3243 OPENSSL_free(context->sni_entry_list);
3244 for (i = 0; i < context->psk_sni_count; i++) {
3245 OPENSSL_free((
char *)context->psk_sni_entry_list[i].sni);
3246#if OPENSSL_VERSION_NUMBER < 0x10101000L
3247 SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
3250 if (context->psk_sni_count)
3251 OPENSSL_free(context->psk_sni_entry_list);
3255#if COAP_SERVER_SUPPORT
3259 SSL *nssl = NULL, *ssl = NULL;
3260 coap_ssl_data *data;
3261 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
3265 nssl = SSL_new(dtls->ctx);
3268 nbio = BIO_new(dtls->meth);
3271 SSL_set_bio(nssl, nbio, nbio);
3272 SSL_set_app_data(nssl, NULL);
3273 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
3274 SSL_set_mtu(nssl, (
long)session->
mtu);
3278 SSL_set_app_data(ssl, session);
3280 data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
3281 data->session = session;
3285 if (psk_hint != NULL && psk_hint->
length) {
3286 char *hint = OPENSSL_malloc(psk_hint->
length + 1);
3289 memcpy(hint, psk_hint->
s, psk_hint->
length);
3290 hint[psk_hint->
length] =
'\000';
3291 SSL_use_psk_identity_hint(ssl, hint);
3298 r = SSL_accept(ssl);
3300 int err = SSL_get_error(ssl, r);
3301 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3319#if COAP_CLIENT_SUPPORT
3323 coap_openssl_context_t *context =
3326 if (context->psk_pki_enabled & IS_PSK) {
3331 SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
3335 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
3336#if COAP_SERVER_SUPPORT
3337 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
3339 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
3342 SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
3344#if !COAP_DISABLE_TCP
3346 SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
3349 coap_log_debug(
"CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
3352 if (context->psk_pki_enabled & IS_PKI) {
3357#if !COAP_DISABLE_TCP
3359 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
3364 SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
3370 X509_VERIFY_PARAM *param;
3372 param = X509_VERIFY_PARAM_new();
3373 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
3374 SSL_set1_param(ssl, param);
3375 X509_VERIFY_PARAM_free(param);
3382 SSL_VERIFY_CLIENT_ONCE |
3383 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3384 tls_verify_call_back);
3386 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
3393#if COAP_DTLS_RETRANSMIT_MS != 1000
3394#if OPENSSL_VERSION_NUMBER >= 0x10101000L
3396 DTLS_set_timer_cb(ssl, timer_cb);
3407 coap_ssl_data *data;
3409 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3410 coap_dtls_context_t *dtls = &context->dtls;
3412 ssl = SSL_new(dtls->ctx);
3415 bio = BIO_new(dtls->meth);
3418 data = (coap_ssl_data *)BIO_get_data(bio);
3419 data->session = session;
3420 SSL_set_bio(ssl, bio, bio);
3421 SSL_set_app_data(ssl, session);
3422 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
3423 SSL_set_mtu(ssl, (
long)session->
mtu);
3425 if (!setup_client_ssl_session(session, ssl))
3430 r = SSL_connect(ssl);
3432 int ret = SSL_get_error(ssl, r);
3433 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3451 SSL *ssl = (SSL *)session->
tls;
3453 SSL_set_mtu(ssl, (
long)session->
mtu);
3459 SSL *ssl = (SSL *)session->
tls;
3461 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3462 int r = SSL_shutdown(ssl);
3467 session->
tls = NULL;
3475 const uint8_t *data,
size_t data_len) {
3477 SSL *ssl = (SSL *)session->
tls;
3479 assert(ssl != NULL);
3482 r = SSL_write(ssl, data, (
int)data_len);
3485 int err = SSL_get_error(ssl, r);
3486 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3490 if (err == SSL_ERROR_ZERO_RETURN)
3492 else if (err == SSL_ERROR_SSL)
3510 if (r == (ssize_t)data_len)
3533 SSL *ssl = (SSL *)session->
tls;
3534 coap_ssl_data *ssl_data;
3537 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
3538 return ssl_data->timeout;
3547 SSL *ssl = (SSL *)session->
tls;
3551 (DTLSv1_handle_timeout(ssl) < 0)) {
3559#if COAP_SERVER_SUPPORT
3562 const uint8_t *data,
size_t data_len) {
3563 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
3564 coap_ssl_data *ssl_data;
3567 SSL_set_mtu(dtls->ssl, (
long)session->
mtu);
3568 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(dtls->ssl));
3569 assert(ssl_data != NULL);
3570 if (ssl_data->pdu_len) {
3571 coap_log_err(
"** %s: Previous data not read %u bytes\n",
3574 ssl_data->session = session;
3575 ssl_data->pdu = data;
3576 ssl_data->pdu_len = (unsigned)data_len;
3577 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
3579 int err = SSL_get_error(dtls->ssl, r);
3580 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3600 coap_ssl_data *ssl_data;
3601 SSL *ssl = (SSL *)session->
tls;
3604 assert(ssl != NULL);
3606 int in_init = SSL_in_init(ssl);
3608 ssl_data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
3609 assert(ssl_data != NULL);
3611 if (ssl_data->pdu_len) {
3612 coap_log_err(
"** %s: Previous data not read %u bytes\n",
3615 ssl_data->pdu = data;
3616 ssl_data->pdu_len = (unsigned)data_len;
3619 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
3624 int err = SSL_get_error(ssl, r);
3625 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3626 if (in_init && SSL_is_init_finished(ssl)) {
3634 if (err == SSL_ERROR_ZERO_RETURN)
3636 else if (err == SSL_ERROR_SSL)
3654 if (ssl_data && ssl_data->pdu_len) {
3656 coap_log_debug(
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
3657 ssl_data->pdu_len = 0;
3658 ssl_data->pdu = NULL;
3669 unsigned int overhead = 37;
3670 const SSL_CIPHER *s_ciph = NULL;
3671 if (session->
tls != NULL)
3672 s_ciph = SSL_get_current_cipher(session->
tls);
3674 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
3676 const EVP_CIPHER *e_ciph;
3680 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
3682 switch (EVP_CIPHER_mode(e_ciph)) {
3683 case EVP_CIPH_GCM_MODE:
3684 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
3685 maclen = EVP_GCM_TLS_TAG_LEN;
3688 case EVP_CIPH_CCM_MODE:
3689 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
3690 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3691 if (strstr(cipher,
"CCM8"))
3697 case EVP_CIPH_CBC_MODE:
3698 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
3699 blocksize = EVP_CIPHER_block_size(e_ciph);
3700 ivlen = EVP_CIPHER_iv_length(e_ciph);
3702 maclen = EVP_MD_size(e_md);
3705 case EVP_CIPH_STREAM_CIPHER:
3712 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3719 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
3724#if !COAP_DISABLE_TCP
3725#if COAP_CLIENT_SUPPORT
3731 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3732 coap_tls_context_t *tls = &context->tls;
3734 ssl = SSL_new(tls->ctx);
3737 bio = BIO_new(tls->meth);
3740 BIO_set_data(bio, session);
3741 SSL_set_bio(ssl, bio, bio);
3742 SSL_set_app_data(ssl, session);
3744 if (!setup_client_ssl_session(session, ssl))
3747 r = SSL_connect(ssl);
3749 int ret = SSL_get_error(ssl, r);
3750 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3752 if (ret == SSL_ERROR_WANT_READ)
3754 if (ret == SSL_ERROR_WANT_WRITE) {
3756#ifdef COAP_EPOLL_SUPPORT
3770 if (SSL_is_init_finished(ssl)) {
3784#if COAP_SERVER_SUPPORT
3789 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
3793 ssl = SSL_new(tls->ctx);
3796 bio = BIO_new(tls->meth);
3799 BIO_set_data(bio, session);
3800 SSL_set_bio(ssl, bio, bio);
3801 SSL_set_app_data(ssl, session);
3804 if (psk_hint != NULL && psk_hint->
length) {
3805 char *hint = OPENSSL_malloc(psk_hint->
length + 1);
3808 memcpy(hint, psk_hint->
s, psk_hint->
length);
3809 hint[psk_hint->
length] =
'\000';
3810 SSL_use_psk_identity_hint(ssl, hint);
3817 r = SSL_accept(ssl);
3819 int err = SSL_get_error(ssl, r);
3820 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3822 if (err == SSL_ERROR_WANT_READ)
3824 if (err == SSL_ERROR_WANT_WRITE) {
3826#ifdef COAP_EPOLL_SUPPORT
3840 if (SSL_is_init_finished(ssl)) {
3845#if COAP_DTLS_RETRANSMIT_MS != 1000
3846#if OPENSSL_VERSION_NUMBER >= 0x10101000L
3848 DTLS_set_timer_cb(ssl, timer_cb);
3864 SSL *ssl = (SSL *)session->
tls;
3866 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3867 int r = SSL_shutdown(ssl);
3872 session->
tls = NULL;
3885 SSL *ssl = (SSL *)session->
tls;
3891 in_init = !SSL_is_init_finished(ssl);
3893 r = SSL_write(ssl, data, (
int)data_len);
3896 int err = SSL_get_error(ssl, r);
3897 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3898 if (in_init && SSL_is_init_finished(ssl)) {
3904 if (err == SSL_ERROR_WANT_READ)
3906 else if (err == SSL_ERROR_WANT_WRITE) {
3908#ifdef COAP_EPOLL_SUPPORT
3920 if (err == SSL_ERROR_ZERO_RETURN)
3922 else if (err == SSL_ERROR_SSL)
3926 }
else if (in_init && SSL_is_init_finished(ssl)) {
3945 if (r == (ssize_t)data_len)
3962 SSL *ssl = (SSL *)session->
tls;
3970 in_init = !SSL_is_init_finished(ssl);
3972 r = SSL_read(ssl, data, (
int)data_len);
3974 int err = SSL_get_error(ssl, r);
3975 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3976 if (in_init && SSL_is_init_finished(ssl)) {
3982 if (err == SSL_ERROR_WANT_READ)
3984 if (err == SSL_ERROR_WANT_WRITE) {
3986#ifdef COAP_EPOLL_SUPPORT
3996 if (err == SSL_ERROR_ZERO_RETURN)
3998 else if (err == SSL_ERROR_SSL)
4002 }
else if (in_init && SSL_is_init_finished(ssl)) {
4028#if COAP_SERVER_SUPPORT
4031 EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new();
4034 EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL);
4041 EVP_MD_CTX_free(digest_ctx);
4046 const uint8_t *data,
4048 return EVP_DigestUpdate(digest_ctx, data, data_len);
4055 int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
4062#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT
4064coap_crypto_output_errors(
const char *prefix) {
4065#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN
4070 while ((e = ERR_get_error()))
4073 ERR_reason_error_string(e),
4074 ssl_function_definition(e));
4084static struct hash_algs {
4086 const EVP_MD *(*get_hash)(void);
4095static const EVP_MD *
4096get_hash_alg(
cose_alg_t alg,
size_t *length) {
4099 for (idx = 0; idx <
sizeof(hashs) /
sizeof(
struct hash_algs); idx++) {
4100 if (hashs[idx].alg == alg) {
4101 *length = hashs[idx].length;
4102 return hashs[idx].get_hash();
4105 coap_log_debug(
"get_hash_alg: COSE hash %d not supported\n", alg);
4113 unsigned int length;
4114 const EVP_MD *evp_md;
4115 EVP_MD_CTX *evp_ctx = NULL;
4119 if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) {
4120 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
4123 evp_ctx = EVP_MD_CTX_new();
4124 if (evp_ctx == NULL)
4126 if (EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0)
4129 if (EVP_DigestUpdate(evp_ctx, data->
s, data->
length) == 0)
4135 if (EVP_DigestFinal_ex(evp_ctx,
dummy->s, &length) == 0)
4137 dummy->length = length;
4138 if (hash_length < dummy->length)
4139 dummy->length = hash_length;
4141 EVP_MD_CTX_free(evp_ctx);
4145 coap_crypto_output_errors(
"coap_crypto_hash");
4148 EVP_MD_CTX_free(evp_ctx);
4153#if COAP_OSCORE_SUPPORT
4159#include <openssl/evp.h>
4160#include <openssl/hmac.h>
4167static struct cipher_algs {
4169 const EVP_CIPHER *(*get_cipher)(void);
4174static const EVP_CIPHER *
4178 for (idx = 0; idx <
sizeof(ciphers) /
sizeof(
struct cipher_algs); idx++) {
4179 if (ciphers[idx].alg == alg)
4180 return ciphers[idx].get_cipher();
4182 coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
4191static struct hmac_algs {
4193 const EVP_MD *(*get_hmac)(void);
4200static const EVP_MD *
4204 for (idx = 0; idx <
sizeof(hmacs) /
sizeof(
struct hmac_algs); idx++) {
4205 if (hmacs[idx].hmac_alg == hmac_alg)
4206 return hmacs[idx].get_hmac();
4208 coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
4214 return get_cipher_alg(alg) != NULL;
4223 return get_hmac_alg(hmac_alg) != NULL;
4227 if (1 != (Func)) { \
4236 size_t *max_result_len) {
4237 const EVP_CIPHER *cipher;
4240 int result_len = (int)(*max_result_len & INT_MAX);
4245 assert(params != NULL);
4246 if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
4253 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
4256 C(EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL));
4257 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
4258 C(EVP_CIPHER_CTX_ctrl(ctx,
4259 EVP_CTRL_AEAD_SET_IVLEN,
4262 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, NULL));
4263 C(EVP_EncryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
4266 C(EVP_EncryptUpdate(ctx, NULL, &result_len, NULL, (
int)data->
length));
4267 if (aad && aad->
s && (aad->
length > 0)) {
4268 C(EVP_EncryptUpdate(ctx, NULL, &result_len, aad->
s, (
int)aad->
length));
4270 C(EVP_EncryptUpdate(ctx, result, &result_len, data->
s, (
int)data->
length));
4273 C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp));
4277 C(EVP_CIPHER_CTX_ctrl(ctx,
4278 EVP_CTRL_CCM_GET_TAG,
4280 result + result_len));
4282 *max_result_len = result_len + ccm->
tag_len;
4283 EVP_CIPHER_CTX_free(ctx);
4287 coap_crypto_output_errors(
"coap_crypto_aead_encrypt");
4296 size_t *max_result_len) {
4297 const EVP_CIPHER *cipher;
4307 assert(params != NULL);
4308 if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
4320 memcpy(&rwtag, &tag,
sizeof(rwtag));
4323 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
4325 C(EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL));
4326 C(EVP_CIPHER_CTX_ctrl(ctx,
4327 EVP_CTRL_AEAD_SET_IVLEN,
4330 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, rwtag));
4331 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
4333 C(EVP_DecryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
4335 C(EVP_DecryptUpdate(ctx, NULL, &len, NULL, (
int)data->
length));
4336 if (aad && aad->
s && (aad->
length > 0)) {
4337 C(EVP_DecryptUpdate(ctx, NULL, &len, aad->
s, (
int)aad->
length));
4339 tmp = EVP_DecryptUpdate(ctx, result, &len, data->
s, (
int)data->
length);
4340 EVP_CIPHER_CTX_free(ctx);
4342 *max_result_len = 0;
4345 *max_result_len = len;
4349 coap_crypto_output_errors(
"coap_crypto_aead_decrypt");
4358 unsigned int result_len;
4359 const EVP_MD *evp_md;
4366 if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
4367 coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
4373 result_len = (
unsigned int)
dummy->length;
4381 dummy->length = result_len;
4386 coap_crypto_output_errors(
"coap_crypto_hmac");
4398#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)
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.
struct coap_digest_t coap_digest_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(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 *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_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_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_tls_engine_remove(void)
Remove a previously configured ENGINE from a TLS library.
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_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_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_oscore_is_supported(void)
Check whether OSCORE is available.
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...
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.
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.
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 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 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.
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