21#ifdef COAP_WITH_LIBWOLFSSL
73#include <wolfssl/options.h>
74#include <wolfssl/ssl.h>
75#include <wolfssl/wolfcrypt/settings.h>
76#include <wolfssl/openssl/ssl.h>
77#include <wolfssl/openssl/x509v3.h>
79#ifdef COAP_EPOLL_SUPPORT
80# include <sys/epoll.h>
83#if LIBWOLFSSL_VERSION_HEX < 0x05002000
84#error Must be compiled against wolfSSL 5.2.0 or later
88#define strcasecmp _stricmp
89#define strncasecmp _strnicmp
93#define WOLFSSL3_AL_FATAL 2
94#define WOLFSSL_TLSEXT_ERR_OK 0
97typedef struct coap_dtls_context_t {
99 WOLFSSL_HMAC_CTX *cookie_hmac;
100} coap_dtls_context_t;
102typedef struct coap_tls_context_t {
109typedef struct coap_wolfssl_context_t {
110 coap_dtls_context_t dtls;
112 coap_tls_context_t tls;
118} coap_wolfssl_context_t;
120typedef struct coap_ssl_data_t {
127typedef struct coap_wolfssl_env_t {
130 unsigned int retry_scalar;
131 coap_ssl_data_t data;
136typedef enum coap_enc_method_t {
142wolfssl_malloc(
size_t size) {
143 void *ret = XMALLOC(size, NULL, DYNAMIC_TYPE_TMP_BUFFER);
149wolfssl_free(
void *ptr) {
151 XFREE(ptr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
155wolfssl_strdup(
const char *str) {
156 char *ret = (
char *)wolfssl_malloc(strlen(str) + 1);
165wolfssl_strndup(
const char *str,
size_t n) {
167 char *ret = (
char *)wolfssl_malloc(len + 1);
170 strncpy(ret, str, len);
176static coap_wolfssl_env_t *
178 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)c_session->
tls;
180 assert(w_env == NULL);
181 w_env = (coap_wolfssl_env_t *)wolfssl_malloc(
sizeof(coap_wolfssl_env_t));
185 memset(w_env, 0,
sizeof(coap_wolfssl_env_t));
191coap_dtls_free_wolfssl_env(coap_wolfssl_env_t *w_env) {
197#if COAP_CLIENT_SUPPORT
198#ifndef WOLFSSL_CIPHER_LIST_MAX_SIZE
199#define WOLFSSL_CIPHER_LIST_MAX_SIZE 4096
202#ifdef COAP_WOLFSSL_PSK_CIPHERS
203static char psk_ciphers[] = COAP_WOLFSSL_PSK_CIPHERS;
205static char psk_ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
208#ifdef COAP_WOLFSSL_PKI_CIPHERS
209static char pki_ciphers[] = COAP_WOLFSSL_PKI_CIPHERS;
211static char pki_ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
215set_ciphersuites(WOLFSSL *ssl, coap_enc_method_t method) {
216#if ! defined(COAP_WOLFSSL_PSK_CIPHERS) || ! defined(COAP_WOLFSSL_PKI_CIPHERS)
217 static int processed_ciphers = 0;
219 if (!processed_ciphers) {
220 static char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
221 char *ciphers_ofs = ciphers;
223#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
224 char *psk_ofs = psk_ciphers;
226#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
227 char *pki_ofs = pki_ciphers;
230 if (wolfSSL_get_ciphers(ciphers, (
int)
sizeof(ciphers)) != WOLFSSL_SUCCESS) {
235 while (ciphers_ofs) {
236 cp = strchr(ciphers_ofs,
':');
239 if (strstr(ciphers_ofs,
"NULL")) {
243 if (strcmp(ciphers_ofs,
"RENEGOTIATION-INFO") == 0) {
246 }
else if (strstr(ciphers_ofs,
"PSK")) {
247#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
248 if (psk_ofs != psk_ciphers) {
252 strcpy(psk_ofs, ciphers_ofs);
253 psk_ofs += strlen(ciphers_ofs);
257#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
258 if (pki_ofs != pki_ciphers) {
262 strcpy(pki_ofs, ciphers_ofs);
263 pki_ofs += strlen(ciphers_ofs);
269 ciphers_ofs = cp + 1;
273#ifndef HAVE_SECURE_RENEGOTIATION
279#if ! defined(COAP_WOLFSSL_PSK_CIPHERS)
280 if (psk_ofs != psk_ciphers) {
284 strcpy(psk_ofs,
"RENEGOTIATION-INFO");
285 psk_ofs += strlen(
"RENEGOTIATION-INFO");
288#if ! defined(COAP_WOLFSSL_PKI_CIPHERS)
289 if (pki_ofs != pki_ciphers) {
293 strcpy(pki_ofs,
"RENEGOTIATION-INFO");
294 pki_ofs += strlen(
"RENEGOTIATION-INFO");
299 processed_ciphers = 1;
303 if (method == COAP_ENC_PSK) {
304 wolfSSL_set_cipher_list(ssl, psk_ciphers);
306 wolfSSL_set_cipher_list(ssl, pki_ciphers);
311#if COAP_SERVER_SUPPORT
312static int psk_tls_server_name_call_back(WOLFSSL *ssl,
int *sd,
void *arg);
314static int tls_verify_call_back(
int preverify_ok, WOLFSSL_X509_STORE_CTX *ctx);
318 if (wolfSSL_lib_version_hex() < 0x05002000) {
319 coap_log_warn(
"wolfSSL version 5.2.0 or later is required\n");
328 if (wolfSSL_lib_version_hex() < 0x05002000) {
329 coap_log_warn(
"wolfSSL version 5.2.0 or later is required\n");
371#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
381 version.
version = wolfSSL_lib_version_hex();
389coap_wolfssl_log_func(
int level,
const char *text) {
392 switch ((
int)level) {
417 if (wolfSSL_library_init() != WOLFSSL_SUCCESS) {
421 wolfSSL_load_error_strings();
422 wolfSSL_SetLoggingCb(coap_wolfssl_log_func);
423 wolfSSL_Debugging_ON();
428 wolfSSL_ERR_free_strings();
430 wolfSSL_Debugging_OFF();
439 coap_wolfssl_env_t *w_env;
442 memcpy(&w_env, &c_session->
tls,
sizeof(w_env));
444 return (
void *)&w_env->ssl;
465coap_dgram_read(WOLFSSL *ssl,
char *out,
int outl,
void *ctx) {
467 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
468 coap_ssl_data_t *data = w_env ? &w_env->data : NULL;
472 if (w_env && !w_env->done_psk_check && w_env->ssl) {
473 if (wolfSSL_SSL_in_init(w_env->ssl)) {
474 const char *name = wolfSSL_get_cipher_name(w_env->ssl);
480 wolfSSL_set_verify(w_env->ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
481 w_env->done_psk_check = 1;
487 if (data != NULL && data->pdu_len > 0) {
488 if (outl < (
int)data->pdu_len) {
489 memcpy(out, data->pdu, outl);
492 memcpy(out, data->pdu, data->pdu_len);
493 ret = (int)data->pdu_len;
495 if (!data->peekmode) {
500 w_env->last_timeout = now;
509coap_dgram_write(WOLFSSL *ssl,
char *in,
int inl,
void *ctx) {
511 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
512 coap_ssl_data_t *data = w_env ? &w_env->data : NULL;
520 && data->session->endpoint == NULL
527 ret = (int)data->session->sock.lfunc[
COAP_LAYER_TLS].l_write(data->session,
532 w_env->last_timeout = now;
540#if COAP_CLIENT_SUPPORT
542coap_dtls_psk_client_callback(WOLFSSL *ssl,
545 unsigned int max_identity_len,
547 unsigned int max_psk_len) {
549 coap_wolfssl_context_t *w_context;
556 if (c_session == NULL)
559 if (w_context == NULL)
567 temp.
s = hint ? (
const uint8_t *)hint : (const uint8_t *)
"";
568 temp.
length = strlen((
const char *)temp.
s);
572 (
const char *)temp.
s);
582 if (cpsk_info == NULL)
587 psk_identity = &cpsk_info->
identity;
588 psk_key = &cpsk_info->
key;
594 if (psk_identity == NULL || psk_key == NULL) {
600 if (!max_identity_len)
603 if (psk_identity->
length > max_identity_len) {
604 coap_log_warn(
"psk_identity too large, truncated to %d bytes\n",
608 max_identity_len = (
unsigned int)psk_identity->
length;
610 memcpy(identity, psk_identity->
s, max_identity_len);
611 identity[max_identity_len] =
'\000';
613 if (psk_key->
length > max_psk_len) {
618 max_psk_len = (
unsigned int)psk_key->
length;
620 memcpy(psk, psk_key->
s, max_psk_len);
625coap_dtls_psk_client_cs_callback(WOLFSSL *ssl,
const char *hint,
626 char *identity,
unsigned int max_identity_len,
627 unsigned char *psk,
unsigned int max_psk_len,
628 const char *ciphersuite) {
629 int key_len = coap_dtls_psk_client_callback(ssl,
642#if COAP_SERVER_SUPPORT
644coap_dtls_psk_server_callback(
646 const char *identity,
648 unsigned int max_psk_len) {
655 if (c_session == NULL)
661 lidentity.
s = identity ? (
const uint8_t *)identity : (const uint8_t *)
"";
662 lidentity.
length = strlen((
const char *)lidentity.
s);
666 (
int)lidentity.
length, (
const char *)lidentity.
s);
681 if (psk_key->
length > max_psk_len) {
686 max_psk_len = (
unsigned int)psk_key->
length;
688 memcpy(psk, psk_key->
s, max_psk_len);
694ssl_function_definition(
unsigned long e) {
695 static char buff[80];
697 snprintf(buff,
sizeof(buff),
" at %s:%s",
698 wolfSSL_ERR_lib_error_string(e), wolfSSL_ERR_func_error_string(e));
703coap_dtls_info_callback(
const WOLFSSL *ssl,
int where,
int ret) {
706 int w = where &~SSL_ST_MASK;
708 if (w & SSL_ST_CONNECT)
709 pstr =
"wolfSSL_connect";
710 else if (w & SSL_ST_ACCEPT)
711 pstr =
"wolfSSL_accept";
715 if (where & SSL_CB_LOOP) {
718 }
else if (where & SSL_CB_ALERT) {
720 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
721 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == WOLFSSL3_AL_FATAL) {
723 if ((ret & 0xff) != close_notify)
728 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
731 wolfSSL_alert_type_string_long(ret),
732 wolfSSL_alert_desc_string_long(ret));
733 }
else if (where & SSL_CB_EXIT) {
739 while ((e = wolfSSL_ERR_get_error()))
742 ssl_function_definition(e));
744 }
else if (ret < 0) {
749 memcpy(&rw_ssl, &ssl,
sizeof(rw_ssl));
750 int err = wolfSSL_get_error(rw_ssl, ret);
751 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE &&
752 err != WOLFSSL_ERROR_WANT_CONNECT && err != WOLFSSL_ERROR_WANT_ACCEPT &&
753 err != WOLFSSL_ERROR_WANT_X509_LOOKUP) {
757 while ((e = wolfSSL_ERR_get_error()))
760 ssl_function_definition(e));
766 if (where == SSL_CB_HANDSHAKE_START) {
770 memcpy(&rw_ssl, &ssl,
sizeof(rw_ssl));
771 if (wolfSSL_is_init_finished(rw_ssl))
783coap_sock_read(WOLFSSL *ssl,
char *out,
int outl,
void *ctx) {
784 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
790 if (w_env && !w_env->done_psk_check && w_env->ssl &&
792 if (wolfSSL_SSL_in_init(w_env->ssl)) {
793 const char *name = wolfSSL_get_cipher_name(w_env->ssl);
798 if (strstr(name,
"PSK")) {
799 wolfSSL_set_verify(w_env->ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
800 w_env->done_psk_check = 1;
822coap_sock_write(WOLFSSL *ssl,
char *in,
int inl,
void *ctx) {
823 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)ctx;
839 (errno == EPIPE || errno == ECONNRESET)) {
859coap_set_user_prefs(WOLFSSL_CTX *ctx) {
862#ifdef COAP_WOLFSSL_SIGALGS
863 wolfSSL_CTX_set1_sigalgs_list(ctx, COAP_WOLFSSL_SIGALGS);
865#ifdef COAP_WOLFSSL_GROUPS
867 ret = wolfSSL_CTX_set1_groups_list(ctx,
868 (
char *) COAP_WOLFSSL_GROUPS);
869 if (ret != WOLFSSL_SUCCESS) {
877setup_dtls_context(coap_wolfssl_context_t *w_context) {
878 if (!w_context->dtls.ctx) {
879 uint8_t cookie_secret[32];
882 w_context->dtls.ctx = wolfSSL_CTX_new(wolfDTLS_method());
883 if (!w_context->dtls.ctx)
885 wolfSSL_CTX_set_min_proto_version(w_context->dtls.ctx,
887 wolfSSL_CTX_set_ex_data(w_context->dtls.ctx, 0, &w_context->dtls);
888 coap_set_user_prefs(w_context->dtls.ctx);
889 memset(cookie_secret, 0,
sizeof(cookie_secret));
890 if (!wolfSSL_RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
892 "Insufficient entropy for random cookie generation");
893 coap_prng(cookie_secret,
sizeof(cookie_secret));
895 w_context->dtls.cookie_hmac = wolfSSL_HMAC_CTX_new();
896 if (!wolfSSL_HMAC_Init_ex(w_context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret),
897 wolfSSL_EVP_sha256(), NULL))
900 wolfSSL_CTX_set_info_callback(w_context->dtls.ctx, coap_dtls_info_callback);
901 wolfSSL_CTX_set_options(w_context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
902 wolfSSL_SetIORecv(w_context->dtls.ctx, coap_dgram_read);
903 wolfSSL_SetIOSend(w_context->dtls.ctx, coap_dgram_write);
904#ifdef WOLFSSL_DTLS_MTU
907 if (w_context->root_ca_file || w_context->root_ca_dir) {
908 if (!wolfSSL_CTX_load_verify_locations_ex(w_context->dtls.ctx,
909 w_context->root_ca_file,
910 w_context->root_ca_dir,
911 w_context->setup_data.allow_expired_certs ?
912 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
914 w_context->root_ca_file ? w_context->root_ca_file :
"NULL",
915 w_context->root_ca_dir ? w_context->root_ca_dir :
"NULL");
920 if (w_context->setup_data.verify_peer_cert)
921 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
922 WOLFSSL_VERIFY_PEER |
923 WOLFSSL_VERIFY_CLIENT_ONCE |
924 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
925 tls_verify_call_back);
927 wolfSSL_CTX_set_verify(w_context->dtls.ctx, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
940setup_tls_context(coap_wolfssl_context_t *w_context) {
941 if (!w_context->tls.ctx) {
943 w_context->tls.ctx = wolfSSL_CTX_new(wolfSSLv23_method());
944 if (!w_context->tls.ctx)
946 wolfSSL_CTX_set_ex_data(w_context->tls.ctx, 0, &w_context->tls);
947 wolfSSL_CTX_set_min_proto_version(w_context->tls.ctx, TLS1_VERSION);
948 coap_set_user_prefs(w_context->tls.ctx);
949 wolfSSL_CTX_set_info_callback(w_context->tls.ctx, coap_dtls_info_callback);
950 wolfSSL_SetIORecv(w_context->tls.ctx, coap_sock_read);
951 wolfSSL_SetIOSend(w_context->tls.ctx, coap_sock_write);
952#if COAP_CLIENT_SUPPORT
953 if (w_context->psk_pki_enabled & IS_PSK) {
954 wolfSSL_CTX_set_psk_client_cs_callback(w_context->tls.ctx,
955 coap_dtls_psk_client_cs_callback);
958 if (w_context->root_ca_file || w_context->root_ca_dir) {
959 if (!wolfSSL_CTX_load_verify_locations_ex(w_context->tls.ctx,
960 w_context->root_ca_file,
961 w_context->root_ca_dir,
962 w_context->setup_data.allow_expired_certs ?
963 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
965 w_context->root_ca_file ? w_context->root_ca_file :
"NULL",
966 w_context->root_ca_dir ? w_context->root_ca_dir :
"NULL");
971 if (w_context->setup_data.verify_peer_cert)
972 wolfSSL_CTX_set_verify(w_context->tls.ctx,
973 WOLFSSL_VERIFY_PEER |
974 WOLFSSL_VERIFY_CLIENT_ONCE |
975 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
976 tls_verify_call_back);
978 wolfSSL_CTX_set_verify(w_context->tls.ctx, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
990 coap_wolfssl_context_t *w_context;
993 w_context = (coap_wolfssl_context_t *)wolfssl_malloc(
sizeof(coap_wolfssl_context_t));
995 memset(w_context, 0,
sizeof(coap_wolfssl_context_t));
1001#if COAP_SERVER_SUPPORT
1006 coap_wolfssl_context_t *w_context =
1009 if (!setup_data || !w_context)
1012 if (!setup_dtls_context(w_context))
1014#if !COAP_DISABLE_TCP
1015 if (!setup_tls_context(w_context))
1019 wolfSSL_CTX_set_psk_server_callback(w_context->dtls.ctx,
1020 coap_dtls_psk_server_callback);
1022#if !COAP_DISABLE_TCP
1023 wolfSSL_CTX_set_psk_server_callback(w_context->tls.ctx,
1024 coap_dtls_psk_server_callback);
1030 wolfSSL_CTX_use_psk_identity_hint(w_context->dtls.ctx, hint);
1031#if !COAP_DISABLE_TCP
1032 wolfSSL_CTX_use_psk_identity_hint(w_context->tls.ctx, hint);
1036 wolfSSL_CTX_set_servername_arg(w_context->dtls.ctx,
1038 wolfSSL_CTX_set_tlsext_servername_callback(w_context->dtls.ctx,
1039 psk_tls_server_name_call_back);
1040#if !COAP_DISABLE_TCP
1041 wolfSSL_CTX_set_servername_arg(w_context->tls.ctx,
1043 wolfSSL_CTX_set_tlsext_servername_callback(w_context->tls.ctx,
1044 psk_tls_server_name_call_back);
1047 w_context->psk_pki_enabled |= IS_PSK;
1052#if COAP_CLIENT_SUPPORT
1057 coap_wolfssl_context_t *w_context =
1060 if (!setup_data || !w_context)
1063 w_context->psk_pki_enabled |= IS_PSK;
1068#if !COAP_DISABLE_TCP
1069static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
1071#if COAP_SERVER_SUPPORT
1074 const unsigned char **out,
1075 unsigned char *outlen,
1076 const unsigned char *in,
1080 unsigned char *tout = NULL;
1083 return SSL_TLSEXT_ERR_NOACK;
1084 ret = wolfSSL_select_next_proto(&tout,
1091 return (ret != OPENSSL_NPN_NEGOTIATED) ? noack_return : WOLFSSL_TLSEXT_ERR_OK;
1097setup_pki_ssl(WOLFSSL *ssl,
1100 WOLFSSL_CTX *ctx = wolfSSL_get_SSL_CTX(ssl);
1114 if (!(wolfSSL_use_PrivateKey_file(ssl,
1116 WOLFSSL_FILETYPE_PEM))) {
1123 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1126 WOLFSSL_FILETYPE_PEM))) {
1133#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1134 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1137 WOLFSSL_FILETYPE_PEM))) {
1149 if (!(wolfSSL_use_PrivateKey_file(ssl,
1151 WOLFSSL_FILETYPE_ASN1))) {
1158 if (!(wolfSSL_use_PrivateKey_buffer(ssl,
1161 WOLFSSL_FILETYPE_ASN1))) {
1190 if (!(wolfSSL_use_certificate_chain_file(ssl,
1198 if (!(wolfSSL_use_certificate_chain_buffer(ssl,
1207#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1209 unsigned char der_buff[512];
1211 char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
1212 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
1214 wolfSSL_set_client_cert_type(ssl, ctype,
sizeof(ctype)/
sizeof(ctype[0]));
1215 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
1219 der_buff, (
int)
sizeof(der_buff));
1223 der_buff, (
int)
sizeof(der_buff), NULL);
1232 if (!wolfSSL_use_PrivateKey_buffer(ssl, der_buff, ret, WOLFSSL_FILETYPE_ASN1)) {
1237 if (!wolfSSL_use_certificate_buffer(ssl, spki->
s, spki->
length, WOLFSSL_FILETYPE_ASN1)) {
1252 if (!wolfSSL_use_certificate_buffer(ssl, der_buff, ret, WOLFSSL_FILETYPE_ASN1)) {
1265 if (!(wolfSSL_use_certificate_file(ssl,
1267 WOLFSSL_FILETYPE_ASN1))) {
1274 if (!(wolfSSL_use_certificate_buffer(ssl,
1277 WOLFSSL_FILETYPE_ASN1))) {
1298#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1300 char stype[] = {WOLFSSL_CERT_TYPE_X509, WOLFSSL_CERT_TYPE_RPK};
1301 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
1312 if (!wolfSSL_CTX_load_verify_locations_ex(ctx,
1316 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1323 if (!wolfSSL_CTX_load_verify_buffer_ex(ctx,
1329 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1339 if (!wolfSSL_CTX_load_verify_locations_ex(ctx,
1343 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1350 if (!wolfSSL_CTX_load_verify_buffer_ex(ctx,
1356 WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY : 0)) {
1375get_san_or_cn_from_cert(WOLFSSL_X509 *x509) {
1379 WOLF_STACK_OF(WOLFSSL_GENERAL_NAME) *san_list;
1383 san_list = wolfSSL_X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1385 int san_count = wolfSSL_sk_GENERAL_NAME_num(san_list);
1387 for (n = 0; n < san_count; n++) {
1388 const WOLFSSL_GENERAL_NAME *name = wolfSSL_sk_GENERAL_NAME_value(san_list, n);
1390 if (name->type == GEN_DNS) {
1391 const char *dns_name = (
const char *)wolfSSL_ASN1_STRING_get0_data(name->d.dNSName);
1394 if (wolfSSL_ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name))
1396 cn = wolfssl_strdup(dns_name);
1397 wolfSSL_sk_GENERAL_NAME_pop_free(san_list, wolfSSL_GENERAL_NAME_free);
1401 wolfSSL_sk_GENERAL_NAME_pop_free(san_list, wolfSSL_GENERAL_NAME_free);
1404 wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name((WOLFSSL_X509 *)(x509)), buffer,
1408 n = (int)strlen(buffer) - 3;
1411 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1412 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1421 char *ecn = strchr(cn,
'/');
1423 return wolfssl_strndup(cn, ecn-cn);
1425 return wolfssl_strdup(cn);
1433tls_verify_call_back(
int preverify_ok, WOLFSSL_X509_STORE_CTX *ctx) {
1434 WOLFSSL *ssl = wolfSSL_X509_STORE_CTX_get_ex_data(ctx,
1435 wolfSSL_get_ex_data_X509_STORE_CTX_idx());
1437 coap_wolfssl_context_t *w_context =
1440 int depth = wolfSSL_X509_STORE_CTX_get_error_depth(ctx);
1441 int err = wolfSSL_X509_STORE_CTX_get_error(ctx);
1442 WOLFSSL_X509 *x509 = wolfSSL_X509_STORE_CTX_get_current_cert(ctx);
1444 int keep_preverify_ok = preverify_ok;
1447 cn = wolfssl_strdup(
"RPK");
1449 cn = get_san_or_cn_from_cert(x509);
1451 if (!preverify_ok) {
1453 case X509_V_ERR_CERT_NOT_YET_VALID:
1454 case X509_V_ERR_CERT_HAS_EXPIRED:
1455 case ASN_NO_SIGNER_E:
1456 case ASN_AFTER_DATE_E:
1460 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1464 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1468 case X509_V_ERR_UNABLE_TO_GET_CRL:
1472 case X509_V_ERR_CRL_NOT_YET_VALID:
1473 case X509_V_ERR_CRL_HAS_EXPIRED:
1477 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1478 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1479 case X509_V_ERR_AKID_SKID_MISMATCH:
1489 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1490 wolfSSL_X509_STORE_CTX_set_error(ctx, err);
1492 if (!preverify_ok) {
1493 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
1496 "Unknown CA", cn ? cn :
"?", depth);
1500 wolfSSL_X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1505 wolfSSL_X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1510 int length = wolfSSL_i2d_X509(x509, NULL);
1514 uint8_t *base_buf2 = base_buf = wolfssl_malloc(length);
1517 wolfSSL_i2d_X509(x509, &base_buf2);
1519 depth, preverify_ok,
1522 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1524 wolfSSL_X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1528 wolfssl_free(base_buf);
1532 return preverify_ok;
1535#if COAP_SERVER_SUPPORT
1546tls_server_name_call_back(WOLFSSL *ssl,
1551 coap_wolfssl_context_t *w_context =
1555 return noack_return;
1560 const char *sni = wolfSSL_get_servername(ssl, WOLFSSL_SNI_HOST_NAME);
1564 if (!sni || !sni[0]) {
1570 return fatal_return;
1572 sni_setup_data = *setup_data;
1573 sni_setup_data.
pki_key = *new_entry;
1577 if (w_context->psk_pki_enabled & IS_PSK) {
1578 wolfSSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1580 return SSL_TLSEXT_ERR_OK;
1591psk_tls_server_name_call_back(WOLFSSL *ssl,
1597 coap_wolfssl_context_t *w_context =
1601 return noack_return;
1606 const char *sni = wolfSSL_get_servername(ssl, WOLFSSL_SNI_HOST_NAME);
1610 if (!sni || !sni[0]) {
1618 snprintf(lhint,
sizeof(lhint),
"%.*s",
1621 wolfSSL_use_psk_identity_hint(ssl, lhint);
1624 if (w_context->psk_pki_enabled & IS_PSK) {
1625 wolfSSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1627 return SSL_TLSEXT_ERR_OK;
1635 coap_wolfssl_context_t *w_context =
1641 w_context->setup_data = *setup_data;
1642 if (!w_context->setup_data.verify_peer_cert) {
1644 w_context->setup_data.check_common_ca = 0;
1645 if (w_context->setup_data.is_rpk_not_cert) {
1647 w_context->setup_data.allow_self_signed = 0;
1648 w_context->setup_data.allow_expired_certs = 0;
1649 w_context->setup_data.cert_chain_validation = 0;
1650 w_context->setup_data.cert_chain_verify_depth = 0;
1651 w_context->setup_data.check_cert_revocation = 0;
1652 w_context->setup_data.allow_no_crl = 0;
1653 w_context->setup_data.allow_expired_crl = 0;
1654 w_context->setup_data.allow_bad_md_hash = 0;
1655 w_context->setup_data.allow_short_rsa_length = 0;
1658 w_context->setup_data.allow_self_signed = 1;
1659 w_context->setup_data.allow_expired_certs = 1;
1660 w_context->setup_data.cert_chain_validation = 1;
1661 w_context->setup_data.cert_chain_verify_depth = 10;
1662 w_context->setup_data.check_cert_revocation = 1;
1663 w_context->setup_data.allow_no_crl = 1;
1664 w_context->setup_data.allow_expired_crl = 1;
1665 w_context->setup_data.allow_bad_md_hash = 1;
1666 w_context->setup_data.allow_short_rsa_length = 1;
1669#if COAP_SERVER_SUPPORT
1671 if (!setup_dtls_context(w_context))
1673 if (w_context->dtls.ctx) {
1674#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1675 char ctype[] = {WOLFSSL_CERT_TYPE_RPK};
1676 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
1679 wolfSSL_CTX_set_servername_arg(w_context->dtls.ctx,
1680 &w_context->setup_data);
1681 wolfSSL_CTX_set_tlsext_servername_callback(w_context->dtls.ctx,
1682 tls_server_name_call_back);
1684#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
1685 if (w_context->setup_data.is_rpk_not_cert) {
1686 wolfSSL_CTX_set_client_cert_type(w_context->dtls.ctx, ctype,
sizeof(ctype)/
sizeof(ctype[0]));
1687 wolfSSL_CTX_set_server_cert_type(w_context->dtls.ctx, stype,
sizeof(stype)/
sizeof(stype[0]));
1691#if !COAP_DISABLE_TCP
1692 if (!setup_tls_context(w_context))
1694 if (w_context->tls.ctx) {
1695 wolfSSL_CTX_set_servername_arg(w_context->tls.ctx,
1696 &w_context->setup_data);
1697 wolfSSL_CTX_set_tlsext_servername_callback(w_context->tls.ctx,
1698 tls_server_name_call_back);
1701 wolfSSL_CTX_set_alpn_select_cb(w_context->tls.ctx,
1702 server_alpn_callback, NULL);
1706 if (w_context->setup_data.check_cert_revocation) {
1707 WOLFSSL_X509_VERIFY_PARAM *param;
1709 param = wolfSSL_X509_VERIFY_PARAM_new();
1710 wolfSSL_X509_VERIFY_PARAM_set_flags(param, WOLFSSL_CRL_CHECK);
1711 wolfSSL_CTX_set1_param(w_context->dtls.ctx, param);
1712#if !COAP_DISABLE_TCP
1713 wolfSSL_CTX_set1_param(w_context->tls.ctx, param);
1715 wolfSSL_X509_VERIFY_PARAM_free(param);
1718 if (w_context->setup_data.verify_peer_cert) {
1719 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
1720 WOLFSSL_VERIFY_PEER |
1721 WOLFSSL_VERIFY_CLIENT_ONCE |
1722 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1723 tls_verify_call_back);
1724#if !COAP_DISABLE_TCP
1725 wolfSSL_CTX_set_verify(w_context->tls.ctx,
1726 WOLFSSL_VERIFY_PEER |
1727 WOLFSSL_VERIFY_CLIENT_ONCE |
1728 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1729 tls_verify_call_back);
1732 wolfSSL_CTX_set_verify(w_context->dtls.ctx,
1733 WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1734#if !COAP_DISABLE_TCP
1735 wolfSSL_CTX_set_verify(w_context->tls.ctx,
1736 WOLFSSL_VERIFY_NONE, tls_verify_call_back);
1741 if (w_context->setup_data.cert_chain_validation) {
1742 wolfSSL_CTX_set_verify_depth(w_context->dtls.ctx,
1744#if !COAP_DISABLE_TCP
1745 wolfSSL_CTX_set_verify_depth(w_context->tls.ctx,
1754 w_context->psk_pki_enabled |= IS_PKI;
1760 const char *ca_file,
1761 const char *ca_dir) {
1762 coap_wolfssl_context_t *w_context =
1766 coap_log_warn(
"coap_context_set_pki_root_cas: (D)TLS environment "
1770 if (ca_file == NULL && ca_dir == NULL) {
1771 coap_log_warn(
"coap_context_set_pki_root_cas: ca_file and/or ca_dir "
1775 if (w_context->root_ca_file) {
1776 wolfssl_free(w_context->root_ca_file);
1777 w_context->root_ca_file = NULL;
1780 w_context->root_ca_file = wolfssl_strdup(ca_file);
1782 if (w_context->root_ca_dir) {
1783 wolfssl_free(w_context->root_ca_dir);
1784 w_context->root_ca_dir = NULL;
1787 w_context->root_ca_dir = wolfssl_strdup(ca_dir);
1794 coap_wolfssl_context_t *w_context =
1796 return w_context->psk_pki_enabled ? 1 : 0;
1802 coap_wolfssl_context_t *w_context = (coap_wolfssl_context_t *)handle;
1806 wolfssl_free(w_context->root_ca_file);
1807 wolfssl_free(w_context->root_ca_dir);
1809 if (w_context->dtls.ctx)
1810 wolfSSL_CTX_free(w_context->dtls.ctx);
1811 if (w_context->dtls.cookie_hmac)
1812 wolfSSL_HMAC_CTX_free(w_context->dtls.cookie_hmac);
1814#if !COAP_DISABLE_TCP
1815 if (w_context->tls.ctx)
1816 wolfSSL_CTX_free(w_context->tls.ctx);
1818 wolfssl_free(w_context);
1821#if COAP_SERVER_SUPPORT
1824 coap_wolfssl_context_t *w_context =
1826 coap_dtls_context_t *dtls;
1827 WOLFSSL *ssl = NULL;
1830 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
1836 if (!setup_dtls_context(w_context))
1838 dtls = &w_context->dtls;
1840 ssl = wolfSSL_new(dtls->ctx);
1844 wolfSSL_set_app_data(ssl, NULL);
1845 wolfSSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1846#ifdef WOLFSSL_DTLS_MTU
1847 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
1850 wolfSSL_SetIOWriteCtx(ssl, w_env);
1851 wolfSSL_SetIOReadCtx(ssl, w_env);
1852 wolfSSL_set_app_data(ssl, session);
1853 w_env->data.session = session;
1855#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
1856 if (wolfSSL_send_hrr_cookie(ssl, NULL, 0) != WOLFSSL_SUCCESS)
1857 coap_log_debug(
"Error: Unable to set cookie with Hello Retry Request\n");
1860#ifdef HAVE_SERVER_RENEGOTIATION_INFO
1861 if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
1862 coap_log_debug(
"Error: wolfSSL_UseSecureRenegotiation failed\n");
1866 if (w_context->psk_pki_enabled & IS_PSK) {
1869 if (psk_hint != NULL && psk_hint->length) {
1870 char *hint = wolfssl_malloc(psk_hint->length + 1);
1873 memcpy(hint, psk_hint->s, psk_hint->length);
1874 hint[psk_hint->length] =
'\000';
1875 wolfSSL_use_psk_identity_hint(ssl, hint);
1882 if (w_context->psk_pki_enabled & IS_PKI) {
1887#if defined(WOLFSSL_DTLS_CH_FRAG) && defined(WOLFSSL_DTLS13)
1888 if (wolfSSL_dtls13_allow_ch_frag(ssl, 1) != WOLFSSL_SUCCESS) {
1894 w_env->last_timeout = now;
1897 r = wolfSSL_accept(ssl);
1899 int err = wolfSSL_get_error(ssl, r);
1900 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE)
1913 coap_dtls_free_wolfssl_env(w_env);
1918#if COAP_CLIENT_SUPPORT
1921 coap_wolfssl_context_t *w_context =
1924 if (w_context->psk_pki_enabled & IS_PSK) {
1929 wolfSSL_set_max_proto_version(ssl,
1932#if !COAP_DISABLE_TCP
1934 wolfSSL_set_max_proto_version(ssl,
1936 wolfSSL_set_options(ssl, WOLFSSL_OP_NO_TLSv1_3);
1939 coap_log_debug(
"CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
1941 set_ciphersuites(ssl, COAP_ENC_PSK);
1945 wolfSSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
1946 coap_log_warn(
"wolfSSL_set_tlsext_host_name: set '%s' failed",
1949 wolfSSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1951 if (w_context->psk_pki_enabled & IS_PKI) {
1954 set_ciphersuites(ssl, COAP_ENC_PKI);
1958#if !COAP_DISABLE_TCP
1960 wolfSSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1965 wolfSSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
1966 coap_log_warn(
"wolfSSL_set_tlsext_host_name: set '%s' failed",
1971 WOLFSSL_X509_VERIFY_PARAM *param;
1973 param = wolfSSL_X509_VERIFY_PARAM_new();
1974 wolfSSL_X509_VERIFY_PARAM_set_flags(param, WOLFSSL_CRL_CHECK);
1975 WOLFSSL_CTX *ctx = wolfSSL_get_SSL_CTX(ssl);
1977 wolfSSL_CTX_set1_param(ctx, param);
1978 wolfSSL_X509_VERIFY_PARAM_free(param);
1982 wolfSSL_set_verify(ssl,
1983 WOLFSSL_VERIFY_PEER |
1984 WOLFSSL_VERIFY_CLIENT_ONCE |
1985 WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1986 tls_verify_call_back);
1988 wolfSSL_set_verify(ssl, WOLFSSL_VERIFY_NONE, tls_verify_call_back);
2000 WOLFSSL *ssl = NULL;
2002 coap_wolfssl_context_t *w_context =
2004 coap_dtls_context_t *dtls;
2005 coap_wolfssl_env_t *w_env =
2012 if (!setup_dtls_context(w_context))
2014 dtls = &w_context->dtls;
2016 ssl = wolfSSL_new(dtls->ctx);
2020 w_env->data.session = session;
2021 wolfSSL_set_app_data(ssl, session);
2022 wolfSSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
2023 wolfSSL_SetIOWriteCtx(ssl, w_env);
2024 wolfSSL_SetIOReadCtx(ssl, w_env);
2025#ifdef WOLFSSL_DTLS_MTU
2026 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
2029 if (!setup_client_ssl_session(session, ssl))
2031#ifdef HAVE_SERVER_RENEGOTIATION_INFO
2032 if (wolfSSL_UseSecureRenegotiation(ssl) != WOLFSSL_SUCCESS) {
2033 coap_log_debug(
"Error: wolfSSL_UseSecureRenegotiation failed\n");
2039#if defined(WOLFSSL_DTLS13) && defined(WOLFSSL_SEND_HRR_COOKIE)
2040 wolfSSL_NoKeyShares(ssl);
2042 r = wolfSSL_connect(ssl);
2044 int ret = wolfSSL_get_error(ssl, r);
2045 if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE)
2053 w_env->last_timeout = now;
2065#ifdef WOLFSSL_DTLS_MTU
2066 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2067 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2070 wolfSSL_dtls_set_mtu(ssl, (
long)session->
mtu);
2079 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2080 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2083 if (!wolfSSL_SSL_in_init(ssl) && !(wolfSSL_get_shutdown(ssl) & WOLFSSL_SENT_SHUTDOWN)) {
2084 int r = wolfSSL_shutdown(ssl);
2086 wolfSSL_shutdown(ssl);
2093 coap_dtls_free_wolfssl_env(w_env);
2098 const uint8_t *data,
size_t data_len) {
2099 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2100 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2103 assert(ssl != NULL);
2108 r = wolfSSL_write(ssl, data, (
int)data_len);
2111 int err = wolfSSL_get_error(ssl, r);
2112 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2116 if (err == WOLFSSL_ERROR_ZERO_RETURN)
2118 else if (err == WOLFSSL_ERROR_SSL)
2151 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2152 unsigned int scalar;
2159 scalar = 1 << w_env->retry_scalar;
2173 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2174 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2177 w_env->retry_scalar++;
2183 wolfSSL_dtls_retransmit(ssl);
2187#if COAP_SERVER_SUPPORT
2191 const uint8_t *data,
size_t data_len) {
2192 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2193 coap_ssl_data_t *ssl_data;
2198 session->
tls = w_env;
2205 ssl_data = w_env ? &w_env->data : NULL;
2206 assert(ssl_data != NULL);
2208 if (ssl_data->pdu_len) {
2209 coap_log_err(
"** %s: Previous data not read %u bytes\n",
2213 ssl_data->session = session;
2214 ssl_data->pdu = data;
2215 ssl_data->pdu_len = (unsigned)data_len;
2224 coap_ssl_data_t *ssl_data;
2225 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2226 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2228 int in_init = wolfSSL_SSL_in_init(ssl);
2231 assert(ssl != NULL);
2233 ssl_data = &w_env->data;
2235 if (ssl_data->pdu_len) {
2236 coap_log_err(
"** %s: Previous data not read %u bytes\n",
2239 ssl_data->pdu = data;
2240 ssl_data->pdu_len = (unsigned)data_len;
2243 r = wolfSSL_read(ssl, pdu, (
int)
sizeof(pdu));
2250 int err = wolfSSL_get_error(ssl, r);
2251 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2252 if (in_init && wolfSSL_is_init_finished(ssl)) {
2259 }
else if (err == APP_DATA_READY) {
2260 r = wolfSSL_read(ssl, pdu, (
int)
sizeof(pdu));
2268 if (err == WOLFSSL_ERROR_ZERO_RETURN) {
2273 if (err == FATAL_ERROR) {
2274 WOLFSSL_ALERT_HISTORY h;
2276 if (wolfSSL_get_alert_history(ssl, &h) == WOLFSSL_SUCCESS) {
2277 if (h.last_rx.code != close_notify && h.last_rx.code != -1) {
2280 wolfSSL_alert_desc_string_long(h.last_rx.code));
2301 if (ssl_data && ssl_data->pdu_len) {
2303 coap_log_debug(
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
2304 ssl_data->pdu_len = 0;
2305 ssl_data->pdu = NULL;
2312 unsigned int overhead = 37;
2313 const WOLFSSL_CIPHER *s_ciph = NULL;
2314 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2315 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2318 s_ciph = wolfSSL_get_current_cipher(ssl);
2320 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
2322 const WOLFSSL_EVP_CIPHER *e_ciph;
2323 const WOLFSSL_EVP_MD *e_md;
2326 e_ciph = wolfSSL_EVP_get_cipherbynid(wolfSSL_CIPHER_get_cipher_nid(s_ciph));
2328 switch (WOLFSSL_EVP_CIPHER_mode(e_ciph)) {
2330 case WOLFSSL_EVP_CIPH_GCM_MODE:
2331#ifndef WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN
2332#define WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN 8
2334#ifndef WOLFSSL_EVP_GCM_TLS_TAG_LEN
2335#define WOLFSSL_EVP_GCM_TLS_TAG_LEN 16
2337 ivlen = WOLFSSL_EVP_GCM_TLS_EXPLICIT_IV_LEN;
2338 maclen = WOLFSSL_EVP_GCM_TLS_TAG_LEN;
2341 case WOLFSSL_EVP_CIPH_CCM_MODE:
2342#ifndef WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN
2343#define WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN 8
2345 ivlen = WOLFSSL_EVP_CCM_TLS_EXPLICIT_IV_LEN;
2346 wolfSSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2347 if (strstr(cipher,
"CCM8"))
2353 case WOLFSSL_EVP_CIPH_CBC_MODE:
2354 e_md = wolfSSL_EVP_get_digestbynid(wolfSSL_CIPHER_get_digest_nid(s_ciph));
2355 blocksize = wolfSSL_EVP_CIPHER_block_size(e_ciph);
2356 ivlen = wolfSSL_EVP_CIPHER_iv_length(e_ciph);
2358 maclen = wolfSSL_EVP_MD_size(e_md);
2361 case WOLFSSL_EVP_CIPH_STREAM_CIPHER:
2368 wolfSSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2375#ifndef WOLFSSL_DTLS13_RT_HEADER_LENGTH
2376#define WOLFSSL_DTLS13_RT_HEADER_LENGTH 13
2378 overhead = WOLFSSL_DTLS13_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 +
2384#if !COAP_DISABLE_TCP
2385#if COAP_CLIENT_SUPPORT
2388 WOLFSSL *ssl = NULL;
2390 coap_wolfssl_context_t *w_context =
2392 coap_tls_context_t *tls;
2393 coap_wolfssl_env_t *w_env =
2400 if (!setup_tls_context(w_context))
2402 tls = &w_context->tls;
2404 ssl = wolfSSL_new(tls->ctx);
2407 wolfSSL_SetIOWriteCtx(ssl, w_env);
2408 wolfSSL_SetIOReadCtx(ssl, w_env);
2409 wolfSSL_set_app_data(ssl, session);
2410 w_env->data.session = session;
2412 if (!setup_client_ssl_session(session, ssl))
2415 session->
tls = w_env;
2417 r = wolfSSL_connect(ssl);
2419 int ret = wolfSSL_get_error(ssl, r);
2420 if (ret != WOLFSSL_ERROR_WANT_READ && ret != WOLFSSL_ERROR_WANT_WRITE)
2422 if (ret == WOLFSSL_ERROR_WANT_READ)
2424 if (ret == WOLFSSL_ERROR_WANT_WRITE) {
2426#ifdef COAP_EPOLL_SUPPORT
2440 w_env->last_timeout = now;
2441 if (wolfSSL_is_init_finished(ssl)) {
2449 coap_dtls_free_wolfssl_env(w_env);
2456#if COAP_SERVER_SUPPORT
2459 WOLFSSL *ssl = NULL;
2460 coap_wolfssl_context_t *w_context =
2462 coap_tls_context_t *tls;
2465 coap_wolfssl_env_t *w_env =
2472 if (!setup_tls_context(w_context))
2474 tls = &w_context->tls;
2476 ssl = wolfSSL_new(tls->ctx);
2479 wolfSSL_SetIOWriteCtx(ssl, w_env);
2480 wolfSSL_SetIOReadCtx(ssl, w_env);
2481 wolfSSL_set_app_data(ssl, session);
2483 wolfSSL_set_cipher_list(ssl,
"ALL");
2485 if (w_context->psk_pki_enabled & IS_PSK) {
2487 if (psk_hint != NULL && psk_hint->
length) {
2488 char *hint = wolfssl_malloc(psk_hint->
length + 1);
2491 memcpy(hint, psk_hint->
s, psk_hint->
length);
2492 hint[psk_hint->
length] =
'\000';
2493 wolfSSL_use_psk_identity_hint(ssl, hint);
2500 if (w_context->psk_pki_enabled & IS_PKI) {
2504#if defined(HAVE_RPK) && LIBWOLFSSL_VERSION_HEX >= 0x05006004
2505 if (w_context->setup_data.is_rpk_not_cert) {
2506 char stype[] = {WOLFSSL_CERT_TYPE_RPK};
2508 wolfSSL_set_server_cert_type(ssl, stype,
sizeof(stype)/
sizeof(stype[0]));
2513 w_env->last_timeout = now;
2515 w_env->data.session = session;
2517 r = wolfSSL_accept(ssl);
2519 int err = wolfSSL_get_error(ssl, r);
2520 if (err != WOLFSSL_ERROR_WANT_READ && err != WOLFSSL_ERROR_WANT_WRITE) {
2523 if (err == WOLFSSL_ERROR_WANT_READ) {
2526 if (err == WOLFSSL_ERROR_WANT_WRITE) {
2528#ifdef COAP_EPOLL_SUPPORT
2541 session->
tls = w_env;
2542 if (wolfSSL_is_init_finished(ssl)) {
2552 coap_dtls_free_wolfssl_env(w_env);
2559 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2560 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2563 if (!wolfSSL_SSL_in_init(ssl) && !(wolfSSL_get_shutdown(ssl) & WOLFSSL_SENT_SHUTDOWN)) {
2564 int r = wolfSSL_shutdown(ssl);
2566 wolfSSL_shutdown(ssl);
2573 coap_dtls_free_wolfssl_env(w_env);
2583 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2584 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2590 in_init = !wolfSSL_is_init_finished(ssl);
2592 r = wolfSSL_write(ssl, data, (
int)data_len);
2595 int err = wolfSSL_get_error(ssl, r);
2596 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2597 if (in_init && wolfSSL_is_init_finished(ssl)) {
2603 if (err == WOLFSSL_ERROR_WANT_READ)
2605 else if (err == WOLFSSL_ERROR_WANT_WRITE) {
2607#ifdef COAP_EPOLL_SUPPORT
2619 if (err == WOLFSSL_ERROR_ZERO_RETURN)
2621 else if (err == WOLFSSL_ERROR_SSL)
2625 }
else if (in_init && wolfSSL_is_init_finished(ssl)) {
2644 if (r == (ssize_t)data_len)
2661 coap_wolfssl_env_t *w_env = (coap_wolfssl_env_t *)session->
tls;
2662 WOLFSSL *ssl = w_env ? w_env->ssl : NULL;
2670 in_init = !wolfSSL_is_init_finished(ssl);
2672 r = wolfSSL_read(ssl, data, (
int)data_len);
2674 int err = wolfSSL_get_error(ssl, r);
2675 if (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE) {
2676 if (in_init && wolfSSL_is_init_finished(ssl)) {
2682 if (err == WOLFSSL_ERROR_WANT_READ)
2684 if (err == WOLFSSL_ERROR_WANT_WRITE) {
2686#ifdef COAP_EPOLL_SUPPORT
2696 if (err == WOLFSSL_ERROR_ZERO_RETURN) {
2699 }
else if (err == WOLFSSL_ERROR_SSL) {
2701 }
else if (err == FATAL_ERROR) {
2702 WOLFSSL_ALERT_HISTORY h;
2705 if (wolfSSL_get_alert_history(ssl, &h) == WOLFSSL_SUCCESS) {
2706 if (h.last_rx.code != close_notify && h.last_rx.code != -1) {
2709 wolfSSL_alert_desc_string_long(h.last_rx.code));
2715 }
else if (in_init && wolfSSL_is_init_finished(ssl)) {
2741#if COAP_SERVER_SUPPORT
2744 WOLFSSL_EVP_MD_CTX *digest_ctx = wolfSSL_EVP_MD_CTX_new();
2747 wolfSSL_EVP_DigestInit_ex(digest_ctx, wolfSSL_EVP_sha256(), NULL);
2754 wolfSSL_EVP_MD_CTX_free(digest_ctx);
2759 const uint8_t *data,
2761 return wolfSSL_EVP_DigestUpdate(digest_ctx, data, data_len);
2768 int ret = wolfSSL_EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
2775#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT
2777coap_crypto_output_errors(
const char *prefix) {
2778#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN
2783 while ((e = wolfSSL_ERR_get_error()))
2786 wolfSSL_ERR_reason_error_string(e),
2787 ssl_function_definition(e));
2797static struct hash_algs {
2799 const WOLFSSL_EVP_MD *(*get_hash)(void);
2808static const WOLFSSL_EVP_MD *
2809get_hash_alg(
cose_alg_t alg,
size_t *length) {
2812 for (idx = 0; idx <
sizeof(hashs) /
sizeof(
struct hash_algs); idx++) {
2813 if (hashs[idx].alg == alg) {
2814 *length = hashs[idx].length;
2815 return hashs[idx].get_hash();
2818 coap_log_debug(
"get_hash_alg: COSE hash %d not supported\n", alg);
2826 unsigned int length;
2827 const WOLFSSL_EVP_MD *evp_md;
2828 WOLFSSL_EVP_MD_CTX *evp_ctx = NULL;
2832 if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) {
2833 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
2836 evp_ctx = wolfSSL_EVP_MD_CTX_new();
2837 if (evp_ctx == NULL)
2839 if (wolfSSL_EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0)
2842 if (wolfSSL_EVP_DigestUpdate(evp_ctx, data->
s, data->
length) == 0)
2848 if (wolfSSL_EVP_DigestFinal_ex(evp_ctx,
dummy->s, &length) == 0)
2850 dummy->length = length;
2851 if (hash_length < dummy->length)
2852 dummy->length = hash_length;
2854 wolfSSL_EVP_MD_CTX_free(evp_ctx);
2858 coap_crypto_output_errors(
"coap_crypto_hash");
2861 wolfSSL_EVP_MD_CTX_free(evp_ctx);
2866#if COAP_OSCORE_SUPPORT
2867#if LIBWOLFSSL_VERSION_HEX < 0x05006000
2868static const WOLFSSL_EVP_CIPHER *
2869EVP_aes_128_ccm(
void) {
2870 return "AES-128-CCM";
2873static const WOLFSSL_EVP_CIPHER *
2874EVP_aes_256_ccm(
void) {
2875 return "AES-256-CCM";
2889static struct cipher_algs {
2891 const WOLFSSL_EVP_CIPHER *(*get_cipher)(void);
2896static const WOLFSSL_EVP_CIPHER *
2900 for (idx = 0; idx <
sizeof(ciphers) /
sizeof(
struct cipher_algs); idx++) {
2901 if (ciphers[idx].alg == alg)
2902 return ciphers[idx].get_cipher();
2904 coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
2913static struct hmac_algs {
2915 const WOLFSSL_EVP_MD *(*get_hmac)(void);
2922static const WOLFSSL_EVP_MD *
2926 for (idx = 0; idx <
sizeof(hmacs) /
sizeof(
struct hmac_algs); idx++) {
2927 if (hmacs[idx].hmac_alg == hmac_alg)
2928 return hmacs[idx].get_hmac();
2930 coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
2936 return get_cipher_alg(alg) != NULL;
2945 return get_hmac_alg(hmac_alg) != NULL;
2949 if (1 != (Func)) { \
2958 size_t *max_result_len) {
2964 byte *authTag = NULL;
2970 assert(params != NULL);
2976 if (ccm->
key.
s == NULL || ccm->
nonce == NULL)
2979 result_len = data->
length;
2980 nonce_length = 15 - ccm->
l;
2982 memset(&aes, 0,
sizeof(aes));
2987 authTag = (
byte *)malloc(ccm->
tag_len *
sizeof(
byte));
2991 ret = wc_AesCcmEncrypt(&aes, result, data->
s, data->
length, ccm->
nonce,
2992 nonce_length, authTag, ccm->
tag_len,
2996 wolfssl_free(authTag);
3000 memcpy(result + result_len, authTag, ccm->
tag_len);
3001 result_len +=
sizeof(authTag);
3002 *max_result_len = result_len;
3003 wolfssl_free(authTag);
3007 coap_crypto_output_errors(
"coap_crypto_aead_encrypt");
3017 size_t *max_result_len) {
3030 assert(params != NULL);
3040 memcpy(authTag, data->
s + data->
length - ccm->
tag_len,
sizeof(authTag));
3044 if (ccm->
key.
s == NULL || ccm->
nonce == NULL)
3047 memset(&aes, 0,
sizeof(aes));
3054 ret = wc_AesCcmDecrypt(&aes, result, data->
s, len, ccm->
nonce,
3055 15 - ccm->
l, authTag,
sizeof(authTag),
3061 *max_result_len = len;
3065 coap_crypto_output_errors(
"coap_crypto_aead_decrypt");
3074 unsigned int result_len;
3075 const WOLFSSL_EVP_MD *evp_md;
3082 if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
3083 coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
3089 result_len = (
unsigned int)
dummy->length;
3090 if (wolfSSL_HMAC(evp_md,
3097 dummy->length = result_len;
3102 coap_crypto_output_errors(
"coap_crypto_hmac");
3114#pragma GCC diagnostic ignored "-Wunused-function"
static size_t strnlen(const char *s, size_t maxlen)
A length-safe strlen() fake.
#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)
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.
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.
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.
void coap_ticks(coap_tick_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.
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.
#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.
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_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_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_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
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 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.
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.
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
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.
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
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