21#if COAP_WITH_LIBWOLFSSL
78#include <wolfssl/options.h>
79#include <wolfssl/ssl.h>
80#include <wolfssl/wolfcrypt/settings.h>
81#include <wolfssl/openssl/ssl.h>
82#include <wolfssl/openssl/x509v3.h>
84#ifdef COAP_EPOLL_SUPPORT
85# include <sys/epoll.h>
88#if LIBWOLFSSL_VERSION_HEX < 0x05002000
89#error Must be compiled against wolfSSL 5.2.0 or later
93#define strcasecmp _stricmp
94#define strncasecmp _strnicmp
98#define WOLFSSL3_AL_FATAL 2
99#define WOLFSSL_TLSEXT_ERR_OK 0
102typedef struct coap_dtls_context_t {
104 WOLFSSL_HMAC_CTX *cookie_hmac;
105} coap_dtls_context_t;
107typedef struct coap_tls_context_t {
114typedef struct coap_wolfssl_context_t {
115 coap_dtls_context_t dtls;
117 coap_tls_context_t tls;
123 int trust_store_defined;
124} coap_wolfssl_context_t;
126typedef struct coap_ssl_data_t {
133typedef struct coap_wolfssl_env_t {
136 unsigned int retry_scalar;
137 coap_ssl_data_t data;
142typedef enum coap_enc_method_t {
148wolfssl_malloc(
size_t size) {
149 void *ret = XMALLOC(size,
NULL, DYNAMIC_TYPE_TMP_BUFFER);
155wolfssl_free(
void *ptr) {
157 XFREE(ptr,
NULL, DYNAMIC_TYPE_TMP_BUFFER);
161wolfssl_strdup(
const char *str) {
162 char *ret = (
char *)wolfssl_malloc(strlen(str) + 1);
170static coap_wolfssl_env_t *
172 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)c_session->
tls;
177 w_env = (coap_wolfssl_env_t *)wolfssl_malloc(
sizeof(coap_wolfssl_env_t));
181 memset(w_env, 0,
sizeof(coap_wolfssl_env_t));
187coap_dtls_free_wolfssl_env(coap_wolfssl_env_t *w_env) {
193#if COAP_CLIENT_SUPPORT
194#ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
195#define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096
198#ifdef COAP_WOLFSSL_PSK_CIPHERS
199static char psk_ciphers[] = COAP_WOLFSSL_PSK_CIPHERS;
201static char psk_ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
204#ifdef COAP_WOLFSSL_PKI_CIPHERS
205static char pki_ciphers[] = COAP_WOLFSSL_PKI_CIPHERS;
207static char pki_ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
211set_ciphersuites(WOLFSSL *ssl, coap_enc_method_t method) {
212#if ! defined(COAP_WOLFSSL_PSK_CIPHERS) || ! defined(COAP_WOLFSSL_PKI_CIPHERS)
213 static int processed_ciphers = 0;
215 if (!processed_ciphers) {
216 static char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
217 char *ciphers_ofs = ciphers;
219#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
220 char *psk_ofs = psk_ciphers;
222#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
223 char *pki_ofs = pki_ciphers;
226 if (wolfSSL_get_ciphers(ciphers, (
int)
sizeof(ciphers)) != WOLFSSL_SUCCESS) {
231 while (ciphers_ofs) {
232 cp = strchr(ciphers_ofs,
':');
235 if (strstr(ciphers_ofs,
"NULL")) {
239 if (strcmp(ciphers_ofs,
"RENEGOTIATION-INFO") == 0) {
242 }
else if (strstr(ciphers_ofs,
"PSK")) {
243#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
244 if (psk_ofs != psk_ciphers) {
248 strcpy(psk_ofs, ciphers_ofs);
249 psk_ofs += strlen(ciphers_ofs);
253#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
254 if (pki_ofs != pki_ciphers) {
258 strcpy(pki_ofs, ciphers_ofs);
259 pki_ofs += strlen(ciphers_ofs);
265 ciphers_ofs = cp + 1;
269#ifndef HAVE_SECURE_RENEGOTIATION
275#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
276 if (psk_ofs != psk_ciphers) {
280 strcpy(psk_ofs,
"RENEGOTIATION-INFO");
281 psk_ofs += strlen(
"RENEGOTIATION-INFO");
284#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
285 if (pki_ofs != pki_ciphers) {
289 strcpy(pki_ofs,
"RENEGOTIATION-INFO");
290 pki_ofs += strlen(
"RENEGOTIATION-INFO");
295 processed_ciphers = 1;
299 if (method == COAP_ENC_PSK) {
300 wolfSSL_set_cipher_list(ssl, psk_ciphers);
302 wolfSSL_set_cipher_list(ssl, pki_ciphers);
307#if COAP_SERVER_SUPPORT
308static int psk_tls_server_name_call_back(WOLFSSL *ssl,
int *sd,
void *arg);
310static int tls_verify_call_back(
int preverify_ok, WOLFSSL_X509_STORE_CTX *ctx);
314 if (wolfSSL_lib_version_hex() < 0x05002000) {
315 coap_log_warn(
"wolfSSL version 5.2.0 or later is required\n");
324 if (wolfSSL_lib_version_hex() < 0x05002000) {
325 coap_log_warn(
"wolfSSL version 5.2.0 or later is required\n");
376#if defined(WOLFSSL_DTLS_CID)
383#if COAP_CLIENT_SUPPORT
386#if defined(WOLFSSL_DTLS_CID)
387 c_context->testing_cids = every;
400 version.
version = wolfSSL_lib_version_hex();
408coap_wolfssl_log_func(
int level,
const char *text) {
411 switch ((
int)level) {
436 if (wolfSSL_library_init() != WOLFSSL_SUCCESS) {
440 wolfSSL_load_error_strings();
441 wolfSSL_SetLoggingCb(coap_wolfssl_log_func);
442 wolfSSL_Debugging_ON();
447 wolfSSL_ERR_free_strings();
449 wolfSSL_Debugging_OFF();
470 coap_wolfssl_env_t *w_env;
473 memcpy(&w_env, &c_session->
tls,
sizeof(w_env));
475 return (
void *)&w_env->ssl;
496coap_dgram_read(WOLFSSL *ssl,
char *out,
int outl,
void *ctx) {
498 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
499 coap_ssl_data_t *data = w_env ? &w_env->data :
NULL;
503 if (w_env && !w_env->done_psk_check && w_env->ssl) {
504 if (wolfSSL_SSL_in_init(w_env->ssl)) {
505 const char *name = wolfSSL_get_cipher_name(w_env->ssl);
511 wolfSSL_set_verify(w_env->ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
512 w_env->done_psk_check = 1;
518 if (data !=
NULL && data->pdu_len > 0) {
519 if (outl < (
int)data->pdu_len) {
520 memcpy(out, data->pdu, outl);
523 memcpy(out, data->pdu, data->pdu_len);
524 ret = (int)data->pdu_len;
526 if (!data->peekmode) {
531 w_env->last_timeout = now;
540coap_dgram_write(WOLFSSL *ssl,
char *in,
int inl,
void *ctx) {
542 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
543 coap_ssl_data_t *data = w_env ? &w_env->data :
NULL;
547 if (data && data->session) {
550 && data->session->endpoint ==
NULL
557 ret = (int)data->session->sock.lfunc[
COAP_LAYER_TLS].l_write(data->session,
562 w_env->last_timeout = now;
563 }
else if (ret < 0) {
564 if (errno == ENOTCONN || errno == ECONNREFUSED)
573#if COAP_CLIENT_SUPPORT
575coap_dtls_psk_client_callback(WOLFSSL *ssl,
578 unsigned int max_identity_len,
580 unsigned int max_psk_len) {
582 coap_wolfssl_context_t *w_context;
592 if (w_context ==
NULL)
600 temp.
s = hint ? (
const uint8_t *)hint : (const uint8_t *)
"";
601 temp.
length = strlen((
const char *)temp.
s);
605 (
const char *)temp.
s);
615 if (cpsk_info ==
NULL)
620 psk_identity = &cpsk_info->
identity;
621 psk_key = &cpsk_info->
key;
627 if (psk_identity ==
NULL || psk_key ==
NULL) {
633 if (!max_identity_len)
636 if (psk_identity->
length > max_identity_len) {
637 coap_log_warn(
"psk_identity too large, truncated to %d bytes\n",
641 max_identity_len = (
unsigned int)psk_identity->
length;
643 memcpy(identity, psk_identity->
s, max_identity_len);
644 identity[max_identity_len] =
'\000';
646 if (psk_key->
length > max_psk_len) {
651 max_psk_len = (
unsigned int)psk_key->
length;
653 memcpy(psk, psk_key->
s, max_psk_len);
660coap_dtls_psk_client_cs_callback(WOLFSSL *ssl,
const char *hint,
661 char *identity,
unsigned int max_identity_len,
662 unsigned char *psk,
unsigned int max_psk_len,
663 const char *ciphersuite) {
664 int key_len = coap_dtls_psk_client_callback(ssl,
676coap_tls_psk_client_cs_callback(WOLFSSL *ssl,
const char *hint,
677 char *identity,
unsigned int max_identity_len,
678 unsigned char *psk,
unsigned int max_psk_len,
679 const char **ciphersuite) {
680 int key_len = coap_dtls_psk_client_callback(ssl,
687 *ciphersuite =
"TLS13-AES128-GCM-SHA256";
694#if COAP_SERVER_SUPPORT
696coap_dtls_psk_server_callback(
698 const char *identity,
700 unsigned int max_psk_len) {
710 setup_data = &c_session->
context->spsk_setup_data;
713 lidentity.
s = identity ? (
const uint8_t *)identity : (const uint8_t *)
"";
714 lidentity.
length = strlen((
const char *)lidentity.
s);
718 (
int)lidentity.
length, (
const char *)lidentity.
s);
733 if (psk_key->
length > max_psk_len) {
738 max_psk_len = (
unsigned int)psk_key->
length;
740 memcpy(psk, psk_key->
s, max_psk_len);
746ssl_function_definition(
unsigned long e) {
747 static char buff[80];
749 snprintf(buff,
sizeof(buff),
" at %s:%s",
750 wolfSSL_ERR_lib_error_string(e), wolfSSL_ERR_func_error_string(e));
755coap_dtls_info_callback(
const WOLFSSL *ssl,
int where,
int ret) {
758 int w = where &~SSL_ST_MASK;
762 "coap_dtls_info_callback: session not determined, where 0x%0x and ret 0x%0x\n", where, ret);
766 if (w & SSL_ST_CONNECT)
767 pstr =
"wolfSSL_connect";
768 else if (w & SSL_ST_ACCEPT)
769 pstr =
"wolfSSL_accept";
773 if (where & SSL_CB_LOOP) {
776 }
else if (where & SSL_CB_ALERT) {
778 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
779 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == WOLFSSL3_AL_FATAL) {
781 if ((ret & 0xff) != close_notify)
786 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
789 wolfSSL_alert_type_string_long(ret),
790 wolfSSL_alert_desc_string_long(ret));
791 }
else if (where & SSL_CB_EXIT) {
797 while ((e = wolfSSL_ERR_get_error()))
800 ssl_function_definition(e));
802 }
else if (ret < 0) {
807 memcpy(&rw_ssl, &ssl,
sizeof(rw_ssl));
808 int err = wolfSSL_get_error(rw_ssl, ret);
809 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE &&
810 err != WOLFSSL_ERROR_WANT_CONNECT && err != WOLFSSL_ERROR_WANT_ACCEPT &&
811 err != WOLFSSL_ERROR_WANT_X509_LOOKUP) {
815 while ((e = wolfSSL_ERR_get_error()))
818 ssl_function_definition(e));
824 if (where == SSL_CB_HANDSHAKE_START) {
828 memcpy(&rw_ssl, &ssl,
sizeof(rw_ssl));
829 if (wolfSSL_is_init_finished(rw_ssl))
842coap_sock_read(WOLFSSL *ssl,
char *out,
int outl,
void *ctx) {
843 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
848 if (w_env && !w_env->done_psk_check && w_env->ssl &&
850 if (wolfSSL_SSL_in_init(w_env->ssl)) {
851 const char *name = wolfSSL_get_cipher_name(w_env->ssl);
856 if (strstr(name,
"PSK")) {
857 wolfSSL_set_verify(w_env->ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
858 w_env->done_psk_check = 1;
863 if (session && out !=
NULL) {
880coap_sock_write(WOLFSSL *ssl,
char *in,
int inl,
void *ctx) {
881 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
901 (errno == EPIPE || errno == ECONNRESET)) {
922coap_set_user_prefs(WOLFSSL_CTX *ctx) {
925#ifdef COAP_WOLFSSL_SIGALGS
926 wolfSSL_CTX_set1_sigalgs_list(ctx, COAP_WOLFSSL_SIGALGS);
928#ifdef COAP_WOLFSSL_GROUPS
930 ret = wolfSSL_CTX_set1_groups_list(ctx,
931 (
char *) COAP_WOLFSSL_GROUPS);
932 if (ret != WOLFSSL_SUCCESS) {
940setup_dtls_context(coap_wolfssl_context_t *w_context) {
941 if (!w_context->dtls.ctx) {
942 uint8_t cookie_secret[32];
945 w_context->dtls.ctx = wolfSSL_CTX_new(wolfDTLS_method());
946 if (!w_context->dtls.ctx)
948 wolfSSL_CTX_set_min_proto_version(w_context->dtls.ctx,
950 wolfSSL_CTX_set_ex_data(w_context->dtls.ctx, 0, &w_context->dtls);
951 coap_set_user_prefs(w_context->dtls.ctx);
952 memset(cookie_secret, 0,
sizeof(cookie_secret));
953 if (!wolfSSL_RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
955 "Insufficient entropy for random cookie generation");
958 w_context->dtls.cookie_hmac = wolfSSL_HMAC_CTX_new();
959 if (!wolfSSL_HMAC_Init_ex(w_context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret),
960 wolfSSL_EVP_sha256(),
NULL))
963 wolfSSL_CTX_set_info_callback(w_context->dtls.ctx, coap_dtls_info_callback);
964 wolfSSL_CTX_set_options(w_context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
965 wolfSSL_SetIORecv(w_context->dtls.ctx, coap_dgram_read);
966 wolfSSL_SetIOSend(w_context->dtls.ctx, coap_dgram_write);
967#ifdef WOLFSSL_DTLS_MTU
970#ifdef WOLFSSL_SYS_CA_CERTS
971 if (w_context->trust_store_defined) {
972 if (!wolfSSL_CTX_load_system_CA_certs(w_context->dtls.ctx)) {
978 if (w_context->root_ca_file || w_context->root_ca_dir) {
979 if (!wolfSSL_CTX_load_verify_locations_ex(w_context->dtls.ctx,
980 w_context->root_ca_file,
981 w_context->root_ca_dir,
982 w_context->setup_data.allow_expired_certs ?
983 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
985 w_context->root_ca_file ? w_context->root_ca_file :
"NULL",
986 w_context->root_ca_dir ? w_context->root_ca_dir :
"NULL");
991 if (w_context->setup_data.verify_peer_cert)
992 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
993 WOLFSSL_VERIFY_PEER |
994 WOLFSSL_VERIFY_CLIENT_ONCE |
995 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
996 tls_verify_call_back);
998 wolfSSL_CTX_set_verify(w_context->dtls.ctx, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1007#if !COAP_DISABLE_TCP
1011setup_tls_context(coap_wolfssl_context_t *w_context) {
1012 if (!w_context->tls.ctx) {
1014 w_context->tls.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
1015 if (!w_context->tls.ctx)
1017 wolfSSL_CTX_set_ex_data(w_context->tls.ctx, 0, &w_context->tls);
1018 wolfSSL_CTX_set_min_proto_version(w_context->tls.ctx, TLS1_VERSION);
1019 coap_set_user_prefs(w_context->tls.ctx);
1020 wolfSSL_CTX_set_info_callback(w_context->tls.ctx, coap_dtls_info_callback);
1021 wolfSSL_SetIORecv(w_context->tls.ctx, coap_sock_read);
1022 wolfSSL_SetIOSend(w_context->tls.ctx, coap_sock_write);
1023#if COAP_CLIENT_SUPPORT
1024 if (w_context->psk_pki_enabled & IS_PSK) {
1026 wolfSSL_CTX_set_psk_client_tls13_callback(w_context->tls.ctx,
1027 coap_tls_psk_client_cs_callback);
1029 wolfSSL_CTX_set_psk_client_cs_callback(w_context->tls.ctx,
1030 coap_dtls_psk_client_cs_callback);
1034 if (w_context->root_ca_file || w_context->root_ca_dir) {
1035 if (!wolfSSL_CTX_load_verify_locations_ex(w_context->tls.ctx,
1036 w_context->root_ca_file,
1037 w_context->root_ca_dir,
1038 w_context->setup_data.allow_expired_certs ?
1039 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1041 w_context->root_ca_file ? w_context->root_ca_file :
"NULL",
1042 w_context->root_ca_dir ? w_context->root_ca_dir :
"NULL");
1047#ifdef WOLFSSL_SYS_CA_CERTS
1048 if (w_context->trust_store_defined) {
1049 if (!wolfSSL_CTX_load_system_CA_certs(w_context->tls.ctx)) {
1055 if (w_context->setup_data.verify_peer_cert)
1056 wolfSSL_CTX_set_verify(w_context->tls.ctx,
1057 WOLFSSL_VERIFY_PEER |
1058 WOLFSSL_VERIFY_CLIENT_ONCE |
1059 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1060 tls_verify_call_back);
1062 wolfSSL_CTX_set_verify(w_context->tls.ctx, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1074 coap_wolfssl_context_t *w_context;
1077 w_context = (coap_wolfssl_context_t *)wolfssl_malloc(
sizeof(coap_wolfssl_context_t));
1079 memset(w_context, 0,
sizeof(coap_wolfssl_context_t));
1085#if COAP_SERVER_SUPPORT
1090 coap_wolfssl_context_t *w_context =
1093 if (!setup_data || !w_context)
1096 if (!setup_dtls_context(w_context))
1098#if !COAP_DISABLE_TCP
1099 if (!setup_tls_context(w_context))
1103 wolfSSL_CTX_set_psk_server_callback(w_context->dtls.ctx,
1104 coap_dtls_psk_server_callback);
1106#if !COAP_DISABLE_TCP
1107 wolfSSL_CTX_set_psk_server_callback(w_context->tls.ctx,
1108 coap_dtls_psk_server_callback);
1114 wolfSSL_CTX_use_psk_identity_hint(w_context->dtls.ctx, hint);
1115 wolfSSL_CTX_set_max_proto_version(w_context->dtls.ctx,
1117#if !COAP_DISABLE_TCP
1118 wolfSSL_CTX_use_psk_identity_hint(w_context->tls.ctx, hint);
1119 wolfSSL_CTX_set_max_proto_version(w_context->tls.ctx,
1124 wolfSSL_CTX_set_servername_arg(w_context->dtls.ctx,
1125 &c_context->spsk_setup_data);
1126 wolfSSL_CTX_set_tlsext_servername_callback(w_context->dtls.ctx,
1127 psk_tls_server_name_call_back);
1128#if !COAP_DISABLE_TCP
1129 wolfSSL_CTX_set_servername_arg(w_context->tls.ctx,
1130 &c_context->spsk_setup_data);
1131 wolfSSL_CTX_set_tlsext_servername_callback(w_context->tls.ctx,
1132 psk_tls_server_name_call_back);
1138 w_context->psk_pki_enabled |= IS_PSK;
1143#if COAP_CLIENT_SUPPORT
1148 coap_wolfssl_context_t *w_context =
1151 if (!setup_data || !w_context)
1158#if ! defined(WOLFSSL_DTLS_CID)
1162 w_context->psk_pki_enabled |= IS_PSK;
1167#if !COAP_DISABLE_TCP
1168static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
1170#if COAP_SERVER_SUPPORT
1173 const unsigned char **out,
1174 unsigned char *outlen,
1175 const unsigned char *in,
1179 unsigned char *tout =
NULL;
1182 return SSL_TLSEXT_ERR_NOACK;
1183 ret = wolfSSL_select_next_proto(&tout,
1190 return (ret != OPENSSL_NPN_NEGOTIATED) ? noack_return : WOLFSSL_TLSEXT_ERR_OK;
1196setup_pki_ssl(WOLFSSL *ssl,
1199 WOLFSSL_CTX *ctx = wolfSSL_get_SSL_CTX(ssl);
1213 if (!(wolfSSL_use_PrivateKey_file(ssl,
1215 WOLFSSL_FILETYPE_PEM))) {
1222 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1225 WOLFSSL_FILETYPE_PEM))) {
1232#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1233 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1236 WOLFSSL_FILETYPE_PEM))) {
1248 if (!(wolfSSL_use_PrivateKey_file(ssl,
1250 WOLFSSL_FILETYPE_ASN1))) {
1257 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1260 WOLFSSL_FILETYPE_ASN1))) {
1289 if (!(wolfSSL_use_certificate_chain_file(ssl,
1297 if (!(wolfSSL_use_certificate_chain_buffer(ssl,
1306#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1308 unsigned char der_buff[512];
1310 char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
1311 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
1313 wolfSSL_set_client_cert_type(ssl, ctype,
sizeof(ctype)/
sizeof(ctype[0]));
1314 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
1318 der_buff, (
int)
sizeof(der_buff));
1322 der_buff, (
int)
sizeof(der_buff),
NULL);
1331 if (!wolfSSL_use_PrivateKey_buffer(ssl, der_buff, ret, WOLFSSL_FILETYPE_ASN1)) {
1336 if (!wolfSSL_use_certificate_buffer(ssl, spki->
s, spki->
length, WOLFSSL_FILETYPE_ASN1)) {
1351 if (!wolfSSL_use_certificate_buffer(ssl, der_buff, ret, WOLFSSL_FILETYPE_ASN1)) {
1364 if (!(wolfSSL_use_certificate_file(ssl,
1366 WOLFSSL_FILETYPE_ASN1))) {
1373 if (!(wolfSSL_use_certificate_buffer(ssl,
1376 WOLFSSL_FILETYPE_ASN1))) {
1397#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1399 char stype[] = {WOLFSSL_CERT_TYPE_X509, WOLFSSL_CERT_TYPE_RPK};
1400 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
1411 if (!wolfSSL_CTX_load_verify_locations_ex(ctx,
1415 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1422 if (!wolfSSL_CTX_load_verify_buffer_ex(ctx,
1428 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1438 if (!wolfSSL_CTX_load_verify_locations_ex(ctx,
1442 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1449 if (!wolfSSL_CTX_load_verify_buffer_ex(ctx,
1455 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1474get_san_or_cn_from_cert(
coap_session_t *session, WOLFSSL_X509 *x509,
const char *sni_match) {
1478 WOLF_STACK_OF(WOLFSSL_GENERAL_NAME) *san_list;
1483 san_list = wolfSSL_X509_get_ext_d2i(x509, NID_subject_alt_name,
NULL,
NULL);
1485 int san_count = wolfSSL_sk_GENERAL_NAME_num(san_list);
1487 for (n = 0; n < san_count; n++) {
1488 const WOLFSSL_GENERAL_NAME *name = wolfSSL_sk_GENERAL_NAME_value(san_list, n);
1490 if (name && name->type == GEN_DNS) {
1491 const char *dns_name = (
const char *)wolfSSL_ASN1_STRING_get0_data(name->d.dNSName);
1494 if (wolfSSL_ASN1_STRING_length(name->d.dNSName) != (
int)strlen(dns_name))
1497 if (strcmp(dns_name, sni_match)) {
1501 cn = wolfssl_strdup(dns_name);
1502 wolfSSL_sk_GENERAL_NAME_pop_free(san_list, wolfSSL_GENERAL_NAME_free);
1506 wolfSSL_sk_GENERAL_NAME_pop_free(san_list, wolfSSL_GENERAL_NAME_free);
1509 wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name((WOLFSSL_X509 *)(x509)), buffer,
1513 n = (int)strlen(buffer) - 3;
1516 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1517 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1526 char *ecn = strchr(cn,
'/');
1528 cn[ecn-cn] =
'\000';
1537 return wolfssl_strdup(cn);
1543 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name,
NULL,
NULL);
1545 int san_count = sk_GENERAL_NAME_num(san_list);
1547 for (n = 0; n < san_count; n++) {
1548 const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n);
1550 if (name && name->type == GEN_DNS) {
1551 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1554 if (ASN1_STRING_length(name->d.dNSName) != (
int)strlen(dns_name))
1560 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1567tls_verify_call_back(
int preverify_ok, WOLFSSL_X509_STORE_CTX *ctx) {
1568 int index = wolfSSL_get_ex_data_X509_STORE_CTX_idx();
1569 WOLFSSL *ssl = index >= 0 ? wolfSSL_X509_STORE_CTX_get_ex_data(ctx, index) :
NULL;
1571 coap_wolfssl_context_t *w_context = (session && session->
context) ?
1574 int depth = wolfSSL_X509_STORE_CTX_get_error_depth(ctx);
1575 int err = wolfSSL_X509_STORE_CTX_get_error(ctx);
1576 WOLFSSL_X509 *x509 = wolfSSL_X509_STORE_CTX_get_current_cert(ctx);
1579 if (!setup_data || !x509) {
1580 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
1585 cn = wolfssl_strdup(
"RPK");
1589 cn = get_san_or_cn_from_cert(session, x509, setup_data->
client_sni);
1592 coap_log_info(
" %s: SNI '%s' not returned in certificate\n",
1595 X509_STORE_CTX_set_error(ctx, X509_V_ERR_SUBJECT_ISSUER_MISMATCH);
1596 err = X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
1600 cn = get_san_or_cn_from_cert(session, x509,
NULL);
1603 depth, err, preverify_ok, cn ? cn :
"");
1606 int length = wolfSSL_i2d_X509(x509,
NULL);
1610 uint8_t *base_buf2 = base_buf = wolfssl_malloc(length);
1615 wolfSSL_i2d_X509(x509, &base_buf2);
1618 depth, preverify_ok,
1622 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1624 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1628 wolfssl_free(base_buf);
1630 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
1635 if (!preverify_ok) {
1637 case X509_V_ERR_CERT_NOT_YET_VALID:
1638 case X509_V_ERR_CERT_HAS_EXPIRED:
1639 case ASN_NO_SIGNER_E:
1640 case ASN_AFTER_DATE_E:
1644 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1648 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1652 case X509_V_ERR_UNABLE_TO_GET_CRL:
1656 case X509_V_ERR_CRL_NOT_YET_VALID:
1657 case X509_V_ERR_CRL_HAS_EXPIRED:
1661 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1662 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1663 case X509_V_ERR_AKID_SKID_MISMATCH:
1667 case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
1677 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1678 wolfSSL_X509_STORE_CTX_set_error(ctx, err);
1680 if (!preverify_ok) {
1681 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
1684 "Unknown CA", cn ? cn :
"?", depth);
1688 wolfSSL_X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1693 wolfSSL_X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1697 return preverify_ok;
1700#if COAP_SERVER_SUPPORT
1711tls_server_name_call_back(WOLFSSL *ssl,
1716 coap_wolfssl_context_t *w_context = (session && session->
context) ?
1720 return noack_return;
1725 const char *sni = wolfSSL_get_servername(ssl, WOLFSSL_SNI_HOST_NAME);
1729 if (!sni || !sni[0]) {
1736 return fatal_return;
1738 sni_setup_data = *setup_data;
1739 sni_setup_data.
pki_key = *new_entry;
1743 if (w_context->psk_pki_enabled & IS_PSK) {
1744 wolfSSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1746 return SSL_TLSEXT_ERR_OK;
1757psk_tls_server_name_call_back(WOLFSSL *ssl,
1763 coap_wolfssl_context_t *w_context = (c_session && c_session->
context) ?
1767 return noack_return;
1772 const char *sni = wolfSSL_get_servername(ssl, WOLFSSL_SNI_HOST_NAME);
1776 if (!sni || !sni[0]) {
1785 snprintf(lhint,
sizeof(lhint),
"%.*s",
1788 wolfSSL_use_psk_identity_hint(ssl, lhint);
1792 if (w_context->psk_pki_enabled & IS_PSK) {
1793 wolfSSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1795 return SSL_TLSEXT_ERR_OK;
1803 coap_wolfssl_context_t *w_context =
1809 w_context->setup_data = *setup_data;
1810 if (!w_context->setup_data.verify_peer_cert) {
1812 w_context->setup_data.check_common_ca = 0;
1813 if (w_context->setup_data.is_rpk_not_cert) {
1815 w_context->setup_data.allow_self_signed = 0;
1816 w_context->setup_data.allow_expired_certs = 0;
1817 w_context->setup_data.cert_chain_validation = 0;
1818 w_context->setup_data.cert_chain_verify_depth = 0;
1819 w_context->setup_data.check_cert_revocation = 0;
1820 w_context->setup_data.allow_no_crl = 0;
1821 w_context->setup_data.allow_expired_crl = 0;
1822 w_context->setup_data.allow_bad_md_hash = 0;
1823 w_context->setup_data.allow_short_rsa_length = 0;
1826 w_context->setup_data.allow_self_signed = 1;
1827 w_context->setup_data.allow_expired_certs = 1;
1828 w_context->setup_data.cert_chain_validation = 1;
1829 w_context->setup_data.cert_chain_verify_depth = 10;
1830 w_context->setup_data.check_cert_revocation = 1;
1831 w_context->setup_data.allow_no_crl = 1;
1832 w_context->setup_data.allow_expired_crl = 1;
1833 w_context->setup_data.allow_bad_md_hash = 1;
1834 w_context->setup_data.allow_short_rsa_length = 1;
1837#if COAP_SERVER_SUPPORT
1839 if (!setup_dtls_context(w_context))
1841 if (w_context->dtls.ctx) {
1842#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1843 char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
1844 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
1847 wolfSSL_CTX_set_servername_arg(w_context->dtls.ctx,
1848 &w_context->setup_data);
1849 wolfSSL_CTX_set_tlsext_servername_callback(w_context->dtls.ctx,
1850 tls_server_name_call_back);
1852#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1853 if (w_context->setup_data.is_rpk_not_cert) {
1854 wolfSSL_CTX_set_client_cert_type(w_context->dtls.ctx, ctype,
sizeof(ctype)/
sizeof(ctype[0]));
1855 wolfSSL_CTX_set_server_cert_type(w_context->dtls.ctx, stype,
sizeof(stype)/
sizeof(stype[0]));
1859#if !COAP_DISABLE_TCP
1860 if (!setup_tls_context(w_context))
1862 if (w_context->tls.ctx) {
1863 wolfSSL_CTX_set_servername_arg(w_context->tls.ctx,
1864 &w_context->setup_data);
1865 wolfSSL_CTX_set_tlsext_servername_callback(w_context->tls.ctx,
1866 tls_server_name_call_back);
1869 wolfSSL_CTX_set_alpn_select_cb(w_context->tls.ctx,
1870 server_alpn_callback,
NULL);
1874 if (w_context->setup_data.check_cert_revocation) {
1875 WOLFSSL_X509_VERIFY_PARAM *param;
1877 param = wolfSSL_X509_VERIFY_PARAM_new();
1878 wolfSSL_X509_VERIFY_PARAM_set_flags(param, WOLFSSL_CRL_CHECK);
1879 wolfSSL_CTX_set1_param(w_context->dtls.ctx, param);
1880#if !COAP_DISABLE_TCP
1881 wolfSSL_CTX_set1_param(w_context->tls.ctx, param);
1883 wolfSSL_X509_VERIFY_PARAM_free(param);
1886 if (w_context->setup_data.verify_peer_cert) {
1887 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
1888 WOLFSSL_VERIFY_PEER |
1889 WOLFSSL_VERIFY_CLIENT_ONCE |
1890 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1891 tls_verify_call_back);
1892#if !COAP_DISABLE_TCP
1893 wolfSSL_CTX_set_verify(w_context->tls.ctx,
1894 WOLFSSL_VERIFY_PEER |
1895 WOLFSSL_VERIFY_CLIENT_ONCE |
1896 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1897 tls_verify_call_back);
1900 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
1901 WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1902#if !COAP_DISABLE_TCP
1903 wolfSSL_CTX_set_verify(w_context->tls.ctx,
1904 WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1909 if (w_context->setup_data.cert_chain_validation) {
1910 wolfSSL_CTX_set_verify_depth(w_context->dtls.ctx,
1912#if !COAP_DISABLE_TCP
1913 wolfSSL_CTX_set_verify_depth(w_context->tls.ctx,
1922 w_context->psk_pki_enabled |= IS_PKI;
1924#if ! defined(WOLFSSL_DTLS_CID)
1933 const char *ca_file,
1934 const char *ca_dir) {
1935 coap_wolfssl_context_t *w_context =
1939 coap_log_warn(
"coap_context_set_pki_root_cas: (D)TLS environment "
1943 if (ca_file ==
NULL && ca_dir ==
NULL) {
1944 coap_log_warn(
"coap_context_set_pki_root_cas: ca_file and/or ca_dir "
1948 if (w_context->root_ca_file) {
1949 wolfssl_free(w_context->root_ca_file);
1950 w_context->root_ca_file =
NULL;
1953 w_context->root_ca_file = wolfssl_strdup(ca_file);
1955 if (w_context->root_ca_dir) {
1956 wolfssl_free(w_context->root_ca_dir);
1957 w_context->root_ca_dir =
NULL;
1960 w_context->root_ca_dir = wolfssl_strdup(ca_dir);
1967 coap_wolfssl_context_t *w_context =
1971 coap_log_warn(
"coap_context_set_pki_trust_store: (D)TLS environment "
1975#ifdef WOLFSSL_SYS_CA_CERTS
1976 w_context->trust_store_defined = 1;
1979 coap_log_warn(
"coap_context_set_pki_trust_store: (D)TLS environment "
1980 "not supported for wolfSSL < v5.5.2 or –enable-sys-ca-certs not defined\n");
1987 coap_wolfssl_context_t *w_context =
1989 return w_context->psk_pki_enabled ? 1 : 0;
1994 coap_wolfssl_context_t *w_context = (coap_wolfssl_context_t *)handle;
1998 wolfssl_free(w_context->root_ca_file);
1999 wolfssl_free(w_context->root_ca_dir);
2001 if (w_context->dtls.ctx)
2002 wolfSSL_CTX_free(w_context->dtls.ctx);
2003 if (w_context->dtls.cookie_hmac)
2004 wolfSSL_HMAC_CTX_free(w_context->dtls.cookie_hmac);
2006#if !COAP_DISABLE_TCP
2007 if (w_context->tls.ctx)
2008 wolfSSL_CTX_free(w_context->tls.ctx);
2010 wolfssl_free(w_context);
2013#if COAP_SERVER_SUPPORT
2016 coap_wolfssl_context_t *w_context = session && session->
context ?
2018 coap_dtls_context_t *dtls;
2019 WOLFSSL *ssl =
NULL;
2022 coap_wolfssl_env_t *w_env = session ? (coap_wolfssl_env_t *)session->
tls :
NULL;
2025 if (!w_env || !w_context)
2028 if (!setup_dtls_context(w_context))
2030 dtls = &w_context->dtls;
2032 ssl = wolfSSL_new(dtls->ctx);
2036 wolfSSL_set_app_data(ssl,
NULL);
2037 wolfSSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
2038#ifdef WOLFSSL_DTLS_MTU
2039 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
2042 wolfSSL_SetIOWriteCtx(ssl, w_env);
2043 wolfSSL_SetIOReadCtx(ssl, w_env);
2044 wolfSSL_set_app_data(ssl, session);
2045 w_env->data.session = session;
2047#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
2048 if (wolfSSL_send_hrr_cookie(ssl,
NULL, 0) != WOLFSSL_SUCCESS)
2049 coap_log_debug(
"Error: Unable to set cookie with Hello Retry Request\n");
2052#ifdef HAVE_SERVER_RENEGOTIATION_INFO
2053 if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
2054 coap_log_debug(
"Error: wolfSSL_UseSecureRenegotiation failed\n");
2058 if (w_context->psk_pki_enabled & IS_PSK) {
2062 char *hint = wolfssl_malloc(psk_hint->
length + 1);
2065 memcpy(hint, psk_hint->
s, psk_hint->
length);
2066 hint[psk_hint->
length] =
'\000';
2067 wolfSSL_use_psk_identity_hint(ssl, hint);
2074 if (w_context->psk_pki_enabled & IS_PKI) {
2079#if defined(WOLFSSL_DTLS_CH_FRAG) && defined(WOLFSSL_DTLS13)
2080 if (wolfSSL_dtls13_allow_ch_frag(ssl, 1) != WOLFSSL_SUCCESS) {
2085#if defined(WOLFSSL_DTLS_CID) && defined(WOLFSSL_DTLS13)
2087#if COAP_DTLS_CID_LENGTH > DTLS_CID_MAX_SIZE
2088#bad COAP_DTLS_CID_LENGTH > DTLS_CID_MAX_SIZE
2091 if (wolfSSL_dtls_cid_use(ssl) != WOLFSSL_SUCCESS)
2098 if (wolfSSL_dtls_cid_set(ssl, cid,
sizeof(cid)) != WOLFSSL_SUCCESS)
2104 w_env->last_timeout = now;
2107 r = wolfSSL_accept(ssl);
2109 int err = wolfSSL_get_error(ssl, r);
2110 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE)
2123 coap_dtls_free_wolfssl_env(w_env);
2129#if COAP_CLIENT_SUPPORT
2132 coap_wolfssl_context_t *w_context =
2135 if (w_context->psk_pki_enabled & IS_PSK) {
2140 wolfSSL_set_max_proto_version(ssl,
2143#if !COAP_DISABLE_TCP
2145 wolfSSL_set_max_proto_version(ssl,
2147 wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1_3);
2150 coap_log_debug(
"CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
2151 set_ciphersuites(ssl, COAP_ENC_PSK);
2153 set_ciphersuites(ssl, COAP_ENC_PSK);
2158 wolfSSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
2159 coap_log_warn(
"wolfSSL_set_tlsext_host_name: set '%s' failed",
2162 wolfSSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
2164#if defined(WOLFSSL_DTLS_CID) && defined(WOLFSSL_DTLS13)
2166 if (wolfSSL_dtls_cid_use(ssl) != WOLFSSL_SUCCESS)
2171 if (wolfSSL_dtls_cid_set(ssl,
NULL, 0) != WOLFSSL_SUCCESS)
2176 if ((w_context->psk_pki_enabled & IS_PKI) ||
2177 (w_context->psk_pki_enabled & (IS_PSK | IS_PKI)) == 0) {
2184 if (!(w_context->psk_pki_enabled & IS_PKI)) {
2198 set_ciphersuites(ssl, COAP_ENC_PKI);
2202#if !COAP_DISABLE_TCP
2204 wolfSSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
2209 wolfSSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
2210 coap_log_warn(
"wolfSSL_set_tlsext_host_name: set '%s' failed",
2215 WOLFSSL_X509_VERIFY_PARAM *param;
2217 param = wolfSSL_X509_VERIFY_PARAM_new();
2218 wolfSSL_X509_VERIFY_PARAM_set_flags(param, WOLFSSL_CRL_CHECK);
2219 WOLFSSL_CTX *ctx = wolfSSL_get_SSL_CTX(ssl);
2221 wolfSSL_CTX_set1_param(ctx, param);
2222 wolfSSL_X509_VERIFY_PARAM_free(param);
2226 wolfSSL_set_verify(ssl,
2227 WOLFSSL_VERIFY_PEER |
2228 WOLFSSL_VERIFY_CLIENT_ONCE |
2229 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2230 tls_verify_call_back);
2232 wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
2238#if defined(WOLFSSL_DTLS_CID) && defined(WOLFSSL_DTLS13)
2240 if (wolfSSL_dtls_cid_use(ssl) != WOLFSSL_SUCCESS)
2245 if (wolfSSL_dtls_cid_set(ssl,
NULL, 0) != WOLFSSL_SUCCESS)
2256 WOLFSSL *ssl =
NULL;
2258 coap_wolfssl_context_t *w_context = session && session->
context ?
2260 coap_dtls_context_t *dtls;
2261 coap_wolfssl_env_t *w_env = session ?
2265 if (!w_env || !w_context)
2268 if (!setup_dtls_context(w_context))
2270 dtls = &w_context->dtls;
2272 ssl = wolfSSL_new(dtls->ctx);
2277 w_env->data.session = session;
2278 wolfSSL_set_app_data(ssl, session);
2279 wolfSSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
2280 wolfSSL_SetIOWriteCtx(ssl, w_env);
2281 wolfSSL_SetIOReadCtx(ssl, w_env);
2282#ifdef WOLFSSL_DTLS_MTU
2283 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
2286 if (!setup_client_ssl_session(session, ssl))
2288#ifdef HAVE_SERVER_RENEGOTIATION_INFO
2289 if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
2290 coap_log_debug(
"Error: wolfSSL_UseSecureRenegotiation failed\n");
2296#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
2297 wolfSSL_NoKeyShares(ssl);
2299 r = wolfSSL_connect(ssl);
2301 int ret = wolfSSL_get_error(ssl, r);
2302 if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE)
2310 w_env->last_timeout = now;
2317 coap_dtls_free_wolfssl_env(w_env);
2324#ifdef WOLFSSL_DTLS_MTU
2325 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2326 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2329 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
2338 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2339 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2342 if (!wolfSSL_SSL_in_init(ssl) && !(wolfSSL_get_shutdown(ssl) & WOLFSSL_SENT_SHUTDOWN)) {
2343 int r = wolfSSL_shutdown(ssl);
2345 wolfSSL_shutdown(ssl);
2352 coap_dtls_free_wolfssl_env(w_env);
2358 const uint8_t *data,
size_t data_len) {
2359 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2360 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2371 r = wolfSSL_write(ssl, data, (
int)data_len);
2374 int err = wolfSSL_get_error(ssl, r);
2375 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2379 if (err == WOLFSSL_ERROR_ZERO_RETURN)
2381 else if (err == WOLFSSL_ERROR_SSL)
2411 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2412 unsigned int scalar;
2419 scalar = 1 << w_env->retry_scalar;
2433 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2434 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2437 w_env->retry_scalar++;
2443 wolfSSL_dtls_got_timeout(ssl);
2447#if COAP_SERVER_SUPPORT
2451 const uint8_t *data,
size_t data_len) {
2452 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2453 coap_ssl_data_t *ssl_data;
2458 session->
tls = w_env;
2465 ssl_data = w_env ? &w_env->data :
NULL;
2466 assert(ssl_data !=
NULL);
2471 if (ssl_data->pdu_len) {
2472 coap_log_err(
"** %s: Previous data not read %u bytes\n",
2476 ssl_data->session = session;
2477 ssl_data->pdu = data;
2478 ssl_data->pdu_len = (unsigned)data_len;
2487 coap_ssl_data_t *ssl_data;
2488 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2489 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2491 int in_init = wolfSSL_SSL_in_init(ssl);
2494 assert(ssl !=
NULL);
2496 ssl_data = &w_env->data;
2498 if (ssl_data->pdu_len) {
2499 coap_log_err(
"** %s: Previous data not read %u bytes\n",
2502 ssl_data->pdu = data;
2503 ssl_data->pdu_len = (unsigned)data_len;
2506 r = wolfSSL_read(ssl, pdu, (
int)
sizeof(pdu));
2513 int err = wolfSSL_get_error(ssl, r);
2514 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2515 if (in_init && wolfSSL_is_init_finished(ssl)) {
2518#if defined(WOLFSSL_DTLS_CID) && defined(WOLFSSL_DTLS13) && COAP_CLIENT_SUPPORT
2521 if (wolfSSL_dtls_cid_is_enabled(ssl)) {
2522 session->negotiated_cid = 1;
2525 session->negotiated_cid = 0;
2529 if (!strcmp(wolfSSL_get_version(ssl),
"DTLSv1.3")) {
2538 }
else if (err == APP_DATA_READY) {
2539 r = wolfSSL_read(ssl, pdu, (
int)
sizeof(pdu));
2547 if (err == WOLFSSL_ERROR_ZERO_RETURN) {
2552 if (err == FATAL_ERROR) {
2553 WOLFSSL_ALERT_HISTORY h;
2555 if (wolfSSL_get_alert_history(ssl, &h) == WOLFSSL_SUCCESS) {
2556 if (h.last_rx.code != close_notify && h.last_rx.code != -1) {
2559 wolfSSL_alert_desc_string_long(h.last_rx.code));
2578 if (ssl_data && ssl_data->pdu_len) {
2580 coap_log_debug(
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
2581 ssl_data->pdu_len = 0;
2582 ssl_data->pdu =
NULL;
2589 unsigned int overhead = 37;
2590 const WOLFSSL_CIPHER *s_ciph =
NULL;
2591 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2592 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2595 s_ciph = wolfSSL_get_current_cipher(ssl);
2597 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
2599 const WOLFSSL_EVP_CIPHER *e_ciph;
2600 const WOLFSSL_EVP_MD *e_md;
2603 e_ciph = wolfSSL_EVP_get_cipherbynid(wolfSSL_CIPHER_get_cipher_nid(s_ciph));
2605 switch (WOLFSSL_EVP_CIPHER_mode(e_ciph)) {
2607 case WOLFSSL_EVP_CIPH_GCM_MODE:
2608#ifndef WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN
2609#define WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN 8
2611#ifndef WOLFSSL_EVP_GCM_TLS_TAG_LEN
2612#define WOLFSSL_EVP_GCM_TLS_TAG_LEN 16
2614 ivlen = WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN;
2615 maclen = WOLFSSL_EVP_GCM_TLS_TAG_LEN;
2618 case WOLFSSL_EVP_CIPH_CCM_MODE:
2619#ifndef WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN
2620#define WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN 8
2622 ivlen = WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN;
2623 wolfSSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2624 if (strstr(cipher,
"CCM8"))
2630 case WOLFSSL_EVP_CIPH_CBC_MODE:
2631 e_md = wolfSSL_EVP_get_digestbynid(wolfSSL_CIPHER_get_digest_nid(s_ciph));
2632 blocksize = wolfSSL_EVP_CIPHER_block_size(e_ciph);
2633 ivlen = wolfSSL_EVP_CIPHER_iv_length(e_ciph);
2635 maclen = wolfSSL_EVP_MD_size(e_md);
2638 case WOLFSSL_EVP_CIPH_STREAM_CIPHER:
2645 wolfSSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2652#ifndef WOLFSSL_DTLS13_RT_HEADER_LENGTH
2653#define WOLFSSL_DTLS13_RT_HEADER_LENGTH 13
2655 overhead = WOLFSSL_DTLS13_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 +
2661#if !COAP_DISABLE_TCP
2662#if COAP_CLIENT_SUPPORT
2665 WOLFSSL *ssl =
NULL;
2667 coap_wolfssl_context_t *w_context =
2669 coap_tls_context_t *tls;
2670 coap_wolfssl_env_t *w_env =
2674 if (!w_env || !w_context)
2677 if (!setup_tls_context(w_context))
2679 tls = &w_context->tls;
2681 ssl = wolfSSL_new(tls->ctx);
2684 wolfSSL_SetIOWriteCtx(ssl, w_env);
2685 wolfSSL_SetIOReadCtx(ssl, w_env);
2686 wolfSSL_set_app_data(ssl, session);
2687 w_env->data.session = session;
2689 if (!setup_client_ssl_session(session, ssl))
2692 session->
tls = w_env;
2694 r = wolfSSL_connect(ssl);
2696 int ret = wolfSSL_get_error(ssl, r);
2697 if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE)
2699 if (ret == WOLFSSL_ERROR_WANT_READ)
2701 if (ret == WOLFSSL_ERROR_WANT_WRITE) {
2703#ifdef COAP_EPOLL_SUPPORT
2717 w_env->last_timeout = now;
2718 if (wolfSSL_is_init_finished(ssl)) {
2726 coap_dtls_free_wolfssl_env(w_env);
2733#if COAP_SERVER_SUPPORT
2736 WOLFSSL *ssl =
NULL;
2737 coap_wolfssl_context_t *w_context =
2739 coap_tls_context_t *tls;
2742 coap_wolfssl_env_t *w_env =
2749 if (!setup_tls_context(w_context))
2751 tls = &w_context->tls;
2753 ssl = wolfSSL_new(tls->ctx);
2756 wolfSSL_SetIOWriteCtx(ssl, w_env);
2757 wolfSSL_SetIOReadCtx(ssl, w_env);
2758 wolfSSL_set_app_data(ssl, session);
2760 wolfSSL_set_cipher_list(ssl,
"ALL");
2762 if (w_context->psk_pki_enabled & IS_PSK) {
2765 char *hint = wolfssl_malloc(psk_hint->
length + 1);
2768 memcpy(hint, psk_hint->
s, psk_hint->
length);
2769 hint[psk_hint->
length] =
'\000';
2770 wolfSSL_use_psk_identity_hint(ssl, hint);
2777 if (w_context->psk_pki_enabled & IS_PKI) {
2781#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
2782 if (w_context->setup_data.is_rpk_not_cert) {
2783 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
2785 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
2790 w_env->last_timeout = now;
2792 w_env->data.session = session;
2794 r = wolfSSL_accept(ssl);
2796 int err = wolfSSL_get_error(ssl, r);
2797 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
2800 if (err == WOLFSSL_ERROR_WANT_READ) {
2803 if (err == WOLFSSL_ERROR_WANT_WRITE) {
2805#ifdef COAP_EPOLL_SUPPORT
2818 session->
tls = w_env;
2819 if (wolfSSL_is_init_finished(ssl)) {
2829 coap_dtls_free_wolfssl_env(w_env);
2837 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2838 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2841 if (!wolfSSL_SSL_in_init(ssl) && !(wolfSSL_get_shutdown(ssl) & WOLFSSL_SENT_SHUTDOWN)) {
2842 int r = wolfSSL_shutdown(ssl);
2844 wolfSSL_shutdown(ssl);
2851 coap_dtls_free_wolfssl_env(w_env);
2862 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2863 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2869 in_init = !wolfSSL_is_init_finished(ssl);
2871 r = wolfSSL_write(ssl, data, (
int)data_len);
2874 int err = wolfSSL_get_error(ssl, r);
2875 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2876 if (in_init && wolfSSL_is_init_finished(ssl)) {
2882 if (err == WOLFSSL_ERROR_WANT_READ)
2884 else if (err == WOLFSSL_ERROR_WANT_WRITE) {
2886#ifdef COAP_EPOLL_SUPPORT
2898 if (err == WOLFSSL_ERROR_ZERO_RETURN)
2900 else if (err == WOLFSSL_ERROR_SSL)
2904 }
else if (in_init && wolfSSL_is_init_finished(ssl)) {
2920 if (r == (ssize_t)data_len)
2937 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2938 WOLFSSL *ssl = w_env ? w_env->ssl :
NULL;
2946 in_init = !wolfSSL_is_init_finished(ssl);
2948 r = wolfSSL_read(ssl, data, (
int)data_len);
2950 int err = wolfSSL_get_error(ssl, r);
2951 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2952 if (in_init && wolfSSL_is_init_finished(ssl)) {
2958 if (err == WOLFSSL_ERROR_WANT_READ)
2960 if (err == WOLFSSL_ERROR_WANT_WRITE) {
2962#ifdef COAP_EPOLL_SUPPORT
2972 if (err == WOLFSSL_ERROR_ZERO_RETURN) {
2975 }
else if (err == WOLFSSL_ERROR_SSL) {
2977 }
else if (err == FATAL_ERROR) {
2978 WOLFSSL_ALERT_HISTORY h;
2981 if (wolfSSL_get_alert_history(ssl, &h) == WOLFSSL_SUCCESS) {
2982 if (h.last_rx.code != close_notify && h.last_rx.code != -1) {
2985 wolfSSL_alert_desc_string_long(h.last_rx.code));
2991 }
else if (in_init && wolfSSL_is_init_finished(ssl)) {
3015#if COAP_SERVER_SUPPORT
3017coap_digest_setup(
void) {
3018 WOLFSSL_EVP_MD_CTX *digest_ctx = wolfSSL_EVP_MD_CTX_new();
3021 wolfSSL_EVP_DigestInit_ex(digest_ctx, wolfSSL_EVP_sha256(),
NULL);
3027coap_digest_free(coap_digest_ctx_t *digest_ctx) {
3029 wolfSSL_EVP_MD_CTX_free(digest_ctx);
3033coap_digest_update(coap_digest_ctx_t *digest_ctx,
3034 const uint8_t *data,
3036 return wolfSSL_EVP_DigestUpdate(digest_ctx, data, data_len);
3040coap_digest_final(coap_digest_ctx_t *digest_ctx,
3041 coap_digest_t *digest_buffer) {
3042 unsigned int size =
sizeof(coap_digest_t);
3043 int ret = wolfSSL_EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
3045 coap_digest_free(digest_ctx);
3050#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT
3052coap_crypto_output_errors(
const char *prefix) {
3053#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN
3058 while ((e = wolfSSL_ERR_get_error()))
3061 wolfSSL_ERR_reason_error_string(e),
3062 ssl_function_definition(e));
3072static struct hash_algs {
3074 const WOLFSSL_EVP_MD *(*get_hash)(void);
3083static const WOLFSSL_EVP_MD *
3084get_hash_alg(
cose_alg_t alg,
size_t *length) {
3087 for (idx = 0; idx <
sizeof(hashs) /
sizeof(
struct hash_algs); idx++) {
3088 if (hashs[idx].alg == alg) {
3089 *length = hashs[idx].length;
3090 return hashs[idx].get_hash();
3093 coap_log_debug(
"get_hash_alg: COSE hash %d not supported\n", alg);
3101 unsigned int length;
3102 const WOLFSSL_EVP_MD *evp_md;
3103 WOLFSSL_EVP_MD_CTX *evp_ctx =
NULL;
3107 if ((evp_md = get_hash_alg(alg, &hash_length)) ==
NULL) {
3108 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
3111 evp_ctx = wolfSSL_EVP_MD_CTX_new();
3112 if (evp_ctx ==
NULL)
3114 if (wolfSSL_EVP_DigestInit_ex(evp_ctx, evp_md,
NULL) == 0)
3117 if (wolfSSL_EVP_DigestUpdate(evp_ctx, data->
s, data->
length) == 0)
3123 if (wolfSSL_EVP_DigestFinal_ex(evp_ctx,
dummy->s, &length) == 0)
3125 dummy->length = length;
3126 if (hash_length < dummy->length)
3127 dummy->length = hash_length;
3129 wolfSSL_EVP_MD_CTX_free(evp_ctx);
3133 coap_crypto_output_errors(
"coap_crypto_hash");
3136 wolfSSL_EVP_MD_CTX_free(evp_ctx);
3141#if COAP_OSCORE_SUPPORT
3142#if LIBWOLFSSL_VERSION_HEX < 0x05006000
3143static const WOLFSSL_EVP_CIPHER *
3144EVP_aes_128_ccm(
void) {
3145 return "AES-128-CCM";
3148static const WOLFSSL_EVP_CIPHER *
3149EVP_aes_256_ccm(
void) {
3150 return "AES-256-CCM";
3164static struct cipher_algs {
3166 const WOLFSSL_EVP_CIPHER *(*get_cipher)(void);
3171static const WOLFSSL_EVP_CIPHER *
3175 for (idx = 0; idx <
sizeof(ciphers) /
sizeof(
struct cipher_algs); idx++) {
3176 if (ciphers[idx].alg == alg)
3177 return ciphers[idx].get_cipher();
3179 coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
3188static struct hmac_algs {
3190 const WOLFSSL_EVP_MD *(*get_hmac)(void);
3197static const WOLFSSL_EVP_MD *
3201 for (idx = 0; idx <
sizeof(hmacs) /
sizeof(
struct hmac_algs); idx++) {
3202 if (hmacs[idx].hmac_alg == hmac_alg)
3203 return hmacs[idx].get_hmac();
3205 coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
3211 return get_cipher_alg(alg) !=
NULL;
3220 return get_hmac_alg(hmac_alg) !=
NULL;
3224 if (1 != (Func)) { \
3233 size_t *max_result_len) {
3239 byte *authTag =
NULL;
3245 assert(params !=
NULL);
3254 result_len = data->
length;
3255 nonce_length = 15 - ccm->
l;
3257 memset(&aes, 0,
sizeof(aes));
3262 authTag = (
byte *)wolfssl_malloc(ccm->
tag_len);
3266 ret = wc_AesCcmEncrypt(&aes, result, data->
s, data->
length, ccm->
nonce,
3267 nonce_length, authTag, ccm->
tag_len,
3274 memcpy(result + result_len, authTag, ccm->
tag_len);
3276 *max_result_len = result_len;
3277 wolfssl_free(authTag);
3281 coap_crypto_output_errors(
"coap_crypto_aead_encrypt");
3282 wolfssl_free(authTag);
3292 size_t *max_result_len) {
3297 byte *authTag =
NULL;
3306 assert(params !=
NULL);
3314 authTag = (
byte *)wolfssl_malloc(ccm->
tag_len);
3325 memset(&aes, 0,
sizeof(aes));
3332 ret = wc_AesCcmDecrypt(&aes, result, data->
s, len, ccm->
nonce,
3333 15 - ccm->
l, authTag, ccm->
tag_len,
3339 *max_result_len = len;
3340 wolfssl_free(authTag);
3344 coap_crypto_output_errors(
"coap_crypto_aead_decrypt");
3345 wolfssl_free(authTag);
3354 unsigned int result_len;
3355 const WOLFSSL_EVP_MD *evp_md;
3362 if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
3363 coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
3369 result_len = (
unsigned int)
dummy->length;
3370 if (wolfSSL_HMAC(evp_md,
3377 dummy->length = result_len;
3382 coap_crypto_output_errors(
"coap_crypto_hmac");
3394#pragma GCC diagnostic ignored "-Wunused-function"
struct coap_session_t coap_session_t
#define COAP_SERVER_SUPPORT
#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.
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)
coap_binary_t * get_asn1_spki(const uint8_t *data, size_t size)
Abstract SPKI public key from the ASN1.
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.
void coap_ticks(coap_tick_t *t)
Returns the current value of an internal tick counter.
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.
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.
int coap_pki_name_match_sni(const char *name_entry, size_t name_length, const char *sni_match)
Check if the PKI name entry is a (wildcard) match for the requested SNI.
void coap_dtls_thread_shutdown(void)
Close down the underlying (D)TLS Library layer.
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.
#define COAP_DTLS_CID_LENGTH
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
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.
#define COAP_DTLS_RETRANSMIT_COAP_TICKS
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
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
struct coap_dtls_pki_t coap_dtls_pki_t
@ 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_TLS_LIBRARY_WOLFSSL
Using wolfSSL 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.
#define COAP_PROTO_NOT_RELIABLE(p)
@ COAP_SESSION_TYPE_CLIENT
client-side
@ COAP_SESSION_STATE_HANDSHAKE
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
coap_bin_const_t * coap_new_bin_const(const uint8_t *data, size_t size)
Take the specified byte array (text) and create a coap_bin_const_t * Returns a new const binary objec...
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
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.
size_t length
length of binary data
The CoAP stack's global state is stored in a coap_context_t object.
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.
coap_crypto_aes_ccm_t aes
Used if AES type encryption.
union coap_crypto_param_t::@127375133034013360062164022213074075037225051156 params
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::@206067364111071227257047077347013260174107036042 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 allow_sni_cn_mismatch
1 if SNI and returnd CN allowed to mismatch (Client only).
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
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_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_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
uint8_t is_dtls13
Set if session is DTLS1.3.
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_session_type_t type
client or server side socket
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