19#if COAP_WITH_LIBOPENHITLS || COAP_WITH_LIBOPENHITLS_OSCORE
28#ifdef COAP_EPOLL_SUPPORT
32#include <hitls/bsl/bsl_err.h>
33#include <hitls/bsl/bsl_errno.h>
34#include <hitls/bsl/bsl_sal.h>
35#include <hitls/bsl/bsl_uio.h>
36#include <hitls/bsl/bsl_version.h>
37#include <hitls/crypto/crypt_eal_cipher.h>
38#include <hitls/crypto/crypt_eal_init.h>
39#include <hitls/crypto/crypt_eal_mac.h>
40#include <hitls/crypto/crypt_eal_md.h>
41#include <hitls/crypto/crypt_eal_pkey.h>
42#include <hitls/crypto/crypt_errno.h>
43#if COAP_WITH_LIBOPENHITLS
45#pragma GCC diagnostic push
46#pragma GCC diagnostic ignored "-Wpedantic"
48#include <hitls/bsl/bsl_list.h>
49#include <hitls/pki/hitls_pki_cert.h>
50#include <hitls/pki/hitls_pki_errno.h>
51#include <hitls/pki/hitls_pki_types.h>
52#include <hitls/pki/hitls_pki_utils.h>
53#include <hitls/pki/hitls_pki_x509.h>
55#pragma GCC diagnostic pop
57#include <hitls/tls/hitls.h>
58#include <hitls/tls/hitls_alpn.h>
59#include <hitls/tls/hitls_cert.h>
60#include <hitls/tls/hitls_cert_init.h>
61#include <hitls/tls/hitls_config.h>
62#include <hitls/tls/hitls_cookie.h>
63#include <hitls/tls/hitls_crypt_init.h>
64#include <hitls/tls/hitls_debug.h>
65#include <hitls/tls/hitls_error.h>
66#include <hitls/tls/hitls_psk.h>
67#include <hitls/tls/hitls_sni.h>
70#if COAP_WITH_LIBOPENHITLS
73#define COAP_HITLS_DTLS_OVERHEAD 37
74#define COAP_HITLS_IPV4_UDP_OVERHEAD 28
75#define COAP_HITLS_IPV6_UDP_OVERHEAD 48
76#define COAP_HITLS_COOKIE_SECRET_LEN 32
77#define COAP_HITLS_COOKIE_LEN 32
81#define COAP_HITLS_VERIFY_DEPTH_TO_MAX_CHAIN_DEPTH(depth) \
84typedef struct coap_hitls_context_t {
90 int trust_store_defined;
91 int cookie_secret_set;
92 uint8_t cookie_secret[COAP_HITLS_COOKIE_SECRET_LEN];
93} coap_hitls_context_t;
95typedef struct coap_hitls_env_t {
98 BSL_UIO_Method *method;
105 int hello_verify_sent;
113static int coap_hitls_started = 0;
114#if COAP_WITH_LIBOPENHITLS
115static const uint8_t coap_hitls_alpn[] = { 4,
'c',
'o',
'a',
'p' };
116static const uint16_t coap_hitls_psk_cipher_suites[] = {
117 HITLS_PSK_WITH_AES_128_GCM_SHA256,
118 HITLS_PSK_WITH_AES_256_GCM_SHA384,
119 HITLS_PSK_WITH_AES_256_CCM,
120 HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256
122static const uint16_t coap_hitls_pki_cipher_suites[] = {
123 HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
124 HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
125 HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
126 HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
127 HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
128 HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384
130static const uint16_t coap_hitls_psk_pki_cipher_suites[] = {
131 HITLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
132 HITLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
133 HITLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
134 HITLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
135 HITLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
136 HITLS_DHE_RSA_WITH_AES_256_GCM_SHA384,
137 HITLS_PSK_WITH_AES_128_GCM_SHA256,
138 HITLS_PSK_WITH_AES_256_GCM_SHA384,
139 HITLS_PSK_WITH_AES_256_CCM,
140 HITLS_PSK_WITH_CHACHA20_POLY1305_SHA256
144coap_hitls_get_cipher_suites(
int enabled,
const uint16_t **cipher_suites,
145 uint32_t *cipher_suites_count) {
146 if ((enabled & IS_PSK) && (enabled & IS_PKI)) {
147 *cipher_suites = coap_hitls_psk_pki_cipher_suites;
148 *cipher_suites_count =
149 (uint32_t)(
sizeof(coap_hitls_psk_pki_cipher_suites) /
150 sizeof(coap_hitls_psk_pki_cipher_suites[0]));
151 }
else if (enabled & IS_PKI) {
152 *cipher_suites = coap_hitls_pki_cipher_suites;
153 *cipher_suites_count =
154 (uint32_t)(
sizeof(coap_hitls_pki_cipher_suites) /
155 sizeof(coap_hitls_pki_cipher_suites[0]));
157 *cipher_suites = coap_hitls_psk_cipher_suites;
158 *cipher_suites_count =
159 (uint32_t)(
sizeof(coap_hitls_psk_cipher_suites) /
160 sizeof(coap_hitls_psk_cipher_suites[0]));
166 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
176 while ((e = BSL_ERR_GetError()) != BSL_SUCCESS)
183 coap_hitls_mark_fatal(session);
184 coap_hitls_log_err_stack(session);
189 ALERT_LEVEL_WARNING = 1,
190 ALERT_LEVEL_FATAL = 2,
191 ALERT_CLOSE_NOTIFY = 0,
192 ALERT_UNEXPECTED_MESSAGE = 10,
193 ALERT_BAD_RECORD_MAC = 20,
194 ALERT_RECORD_OVERFLOW = 22,
195 ALERT_HANDSHAKE_FAILURE = 40,
196 ALERT_BAD_CERTIFICATE = 42,
197 ALERT_UNSUPPORTED_CERTIFICATE = 43,
198 ALERT_CERTIFICATE_REVOKED = 44,
199 ALERT_CERTIFICATE_EXPIRED = 45,
200 ALERT_ILLEGAL_PARAMETER = 47,
201 ALERT_UNKNOWN_CA = 48,
202 ALERT_DECODE_ERROR = 50,
203 ALERT_DECRYPT_ERROR = 51,
204 ALERT_PROTOCOL_VERSION = 70,
205 ALERT_INSUFFICIENT_SECURITY = 71,
206 ALERT_INTERNAL_ERROR = 80,
207 ALERT_INAPPROPRIATE_FALLBACK = 86,
208 ALERT_NO_RENEGOTIATION = 100,
209 ALERT_MISSING_EXTENSION = 109,
210 ALERT_UNSUPPORTED_EXTENSION = 110,
211 ALERT_UNRECOGNIZED_NAME = 112,
212 ALERT_CERTIFICATE_REQUIRED = 116,
213 ALERT_NO_APPLICATION_PROTOCOL = 120
217coap_hitls_alert_desc(
int desc) {
219 case ALERT_CLOSE_NOTIFY:
220 return "close_notify";
221 case ALERT_UNEXPECTED_MESSAGE:
222 return "unexpected_message";
223 case ALERT_BAD_RECORD_MAC:
224 return "bad_record_mac";
225 case ALERT_RECORD_OVERFLOW:
226 return "record_overflow";
227 case ALERT_HANDSHAKE_FAILURE:
228 return "handshake_failure";
229 case ALERT_BAD_CERTIFICATE:
230 return "bad_certificate";
231 case ALERT_UNSUPPORTED_CERTIFICATE:
232 return "unsupported_certificate";
233 case ALERT_CERTIFICATE_REVOKED:
234 return "certificate_revoked";
235 case ALERT_CERTIFICATE_EXPIRED:
236 return "certificate_expired";
237 case ALERT_ILLEGAL_PARAMETER:
238 return "illegal_parameter";
239 case ALERT_UNKNOWN_CA:
241 case ALERT_DECODE_ERROR:
242 return "decode_error";
243 case ALERT_DECRYPT_ERROR:
244 return "decrypt_error";
245 case ALERT_PROTOCOL_VERSION:
246 return "protocol_version";
247 case ALERT_INSUFFICIENT_SECURITY:
248 return "insufficient_security";
249 case ALERT_INTERNAL_ERROR:
250 return "internal_error";
251 case ALERT_INAPPROPRIATE_FALLBACK:
252 return "inappropriate_fallback";
253 case ALERT_NO_RENEGOTIATION:
254 return "no_renegotiation";
255 case ALERT_MISSING_EXTENSION:
256 return "missing_extension";
257 case ALERT_UNSUPPORTED_EXTENSION:
258 return "unsupported_extension";
259 case ALERT_UNRECOGNIZED_NAME:
260 return "unrecognized_name";
261 case ALERT_CERTIFICATE_REQUIRED:
262 return "certificate_required";
263 case ALERT_NO_APPLICATION_PROTOCOL:
264 return "no_application_protocol";
272coap_hitls_info_cb(
const HITLS_Ctx *ctx, int32_t event_type, int32_t value) {
274 int alert_level = (value >> 8) & 0xff;
275 int alert_desc = value & 0xff;
278 if ((event_type & INDICATE_EVENT_ALERT) == 0 || !session)
280 dir = (event_type & INDICATE_EVENT_READ) ?
"received" :
"sent";
281 if (alert_level == ALERT_LEVEL_FATAL && alert_desc != ALERT_CLOSE_NOTIFY)
284 coap_hitls_alert_desc(alert_desc), alert_desc);
288 coap_hitls_alert_desc(alert_desc), alert_desc);
292coap_hitls_verify_err_str(int32_t err) {
294 case HITLS_X509_ERR_TIME_EXPIRED:
295 case HITLS_X509_ERR_VFY_NOTAFTER_EXPIRED:
296 return "certificate expired";
297 case HITLS_X509_ERR_TIME_FUTURE:
298 case HITLS_X509_ERR_VFY_NOTBEFORE_IN_FUTURE:
299 return "certificate not yet valid";
300 case HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND:
301 return "issuer certificate not found";
302 case HITLS_X509_ERR_ROOT_CERT_NOT_FOUND:
303 return "self-signed or root CA not found";
304 case HITLS_X509_ERR_VFY_CRL_NOT_FOUND:
305 return "CRL not found";
306 case HITLS_X509_ERR_VFY_THISUPDATE_IN_FUTURE:
307 case HITLS_X509_ERR_VFY_NEXTUPDATE_EXPIRED:
308 return "CRL expired or not yet valid";
309 case HITLS_X509_ERR_VFY_CHECK_SECBITS:
310 return "certificate security strength too low";
311 case HITLS_X509_ERR_VFY_HOSTNAME_FAIL:
312 return "hostname mismatch";
313 case HITLS_X509_ERR_VFY_GET_NOTBEFORE_FAIL:
314 return "cannot read certificate validity start";
315 case HITLS_X509_ERR_VFY_GET_NOTAFTER_FAIL:
316 return "cannot read certificate validity end";
317 case BSL_SAL_TIME_SYS_ERROR:
318 return "system time unavailable";
320 return "certificate verification failed";
326coap_hitls_startup(
void) {
327 if (!coap_hitls_started) {
328 int32_t ret = CRYPT_EAL_Init(CRYPT_EAL_INIT_ALL);
330 if (ret != CRYPT_SUCCESS) {
331 coap_log_err(
"CRYPT_EAL_Init() returned 0x%x\n", (
unsigned int)ret);
334#if COAP_WITH_LIBOPENHITLS
335 ret = HITLS_CertMethodInit();
336 if (ret != HITLS_SUCCESS) {
339 CRYPT_EAL_Cleanup(CRYPT_EAL_INIT_ALL);
342 HITLS_CryptMethodInit();
344 coap_hitls_started = 1;
346 return coap_hitls_started;
349#if COAP_WITH_LIBOPENHITLS
351coap_hitls_strdup(
const char *s) {
361 memcpy(copy, s, len + 1);
366coap_hitls_read_file(
const char *file, uint32_t *buf_len) {
372 if (!file || !buf_len)
375 fp = fopen(file,
"rb");
379 if (fseek(fp, 0, SEEK_END) != 0)
381 file_len = ftell(fp);
382 if (file_len <= 0 || (uintmax_t)file_len > UINT32_MAX)
384 if (fseek(fp, 0, SEEK_SET) != 0)
390 read_len = fread(buf, 1, (
size_t)file_len, fp);
391 if (read_len != (
size_t)file_len) {
397 *buf_len = (uint32_t)read_len;
406coap_hitls_strnlen(
const uint8_t *s,
size_t max_len) {
411 while (len < max_len && s[len])
417coap_hitls_copy_bin(uint8_t *dst, uint32_t dst_len,
419 size_t extra = add_nul ? 1 : 0;
421 if (!dst || !src || !src->
s ||
422 extra > (
size_t)dst_len || src->
length > (
size_t)dst_len - extra)
424 memcpy(dst, src->
s, src->
length);
426 dst[src->
length] =
'\000';
427 return (uint32_t)src->
length;
430#if COAP_SERVER_SUPPORT
433 uint32_t *cookie_len) {
434 static const uint8_t cookie_label[] =
"libcoap openhitls dtls cookie";
435 coap_hitls_context_t *context;
436 CRYPT_EAL_MacCtx *ctx =
NULL;
440 if (!session || !session->
context || !cookie || !cookie_len ||
441 *cookie_len < COAP_HITLS_COOKIE_LEN ||
447 if (!context || !context->cookie_secret_set)
450 ctx = CRYPT_EAL_MacNewCtx(CRYPT_MAC_HMAC_SHA256);
454 out_len = *cookie_len;
455 if (CRYPT_EAL_MacInit(ctx, context->cookie_secret,
456 COAP_HITLS_COOKIE_SECRET_LEN) != CRYPT_SUCCESS)
458 if (CRYPT_EAL_MacUpdate(ctx, cookie_label,
459 (uint32_t)
sizeof(cookie_label) - 1) != CRYPT_SUCCESS)
461 if (CRYPT_EAL_MacUpdate(ctx,
465 if (CRYPT_EAL_MacUpdate(ctx,
469 if (CRYPT_EAL_MacFinal(ctx, cookie, &out_len) != CRYPT_SUCCESS ||
470 out_len != COAP_HITLS_COOKIE_LEN)
473 *cookie_len = out_len;
477 CRYPT_EAL_MacFreeCtx(ctx);
482coap_hitls_cookie_equal(
const uint8_t *a,
const uint8_t *b, uint32_t len) {
486 for (i = 0; i < len; i++)
487 diff |= (uint8_t)(a[i] ^ b[i]);
492coap_hitls_cookie_gen_cb(HITLS_Ctx *ctx, uint8_t *cookie,
493 uint32_t *cookie_len) {
496 return coap_hitls_cookie_mac(session, cookie, cookie_len) ?
497 HITLS_COOKIE_GENERATE_SUCCESS : HITLS_COOKIE_GENERATE_ERROR;
501coap_hitls_cookie_verify_cb(HITLS_Ctx *ctx,
const uint8_t *cookie,
502 uint32_t cookie_len) {
503 uint8_t expected[COAP_HITLS_COOKIE_LEN];
504 uint32_t expected_len =
sizeof(expected);
507 if (!cookie || cookie_len != COAP_HITLS_COOKIE_LEN ||
508 !coap_hitls_cookie_mac(session, expected, &expected_len) ||
509 expected_len != cookie_len ||
510 !coap_hitls_cookie_equal(cookie, expected, cookie_len))
511 return HITLS_COOKIE_VERIFY_ERROR;
512 return HITLS_COOKIE_VERIFY_SUCCESS;
516coap_hitls_u24(
const uint8_t *p) {
517 return ((uint32_t)p[0] << 16) | ((uint32_t)p[1] << 8) | p[2];
522 const uint8_t *data,
size_t data_len) {
523 uint8_t expected[COAP_HITLS_COOKIE_LEN];
524 uint32_t expected_len =
sizeof(expected);
525 size_t body_offset = 13 + 12;
530 uint32_t frag_offset;
532 uint8_t session_id_len;
535 if (!data || data_len < body_offset || data[0] != 22 || data[13] != 1)
538 record_len = ((uint32_t)data[11] << 8) | data[12];
539 hs_len = coap_hitls_u24(&data[14]);
540 frag_offset = coap_hitls_u24(&data[19]);
541 frag_len = coap_hitls_u24(&data[22]);
542 if (record_len > data_len - 13 || hs_len > record_len - 12 ||
543 frag_offset != 0 || frag_len != hs_len)
546 body_end = body_offset + hs_len;
547 if (body_end > data_len || body_end < body_offset + 35)
550 offset = body_offset + 34;
551 session_id_len = data[offset++];
552 if (offset + session_id_len + 1 > body_end)
554 offset += session_id_len;
556 cookie_len = data[offset++];
559 if (offset + cookie_len > body_end ||
560 cookie_len != COAP_HITLS_COOKIE_LEN ||
561 !coap_hitls_cookie_mac(session, expected, &expected_len) ||
562 expected_len != cookie_len)
565 return coap_hitls_cookie_equal(&data[offset], expected, cookie_len) ? 1 : -1;
570coap_hitls_pki_len(
const uint8_t *buf,
size_t len, HITLS_ParseFormat format,
574 if (format == TLS_PARSE_FORMAT_PEM && len && buf[len - 1] ==
'\000')
576 if (len > UINT32_MAX)
578 *out_len = (uint32_t)len;
603 if (coap_hitls_key_define_supported(define))
638 if (err_code == HITLS_PKI_SUCCESS)
644 case HITLS_X509_ERR_TIME_EXPIRED:
645 case HITLS_X509_ERR_TIME_FUTURE:
646 case HITLS_X509_ERR_VFY_NOTBEFORE_IN_FUTURE:
647 case HITLS_X509_ERR_VFY_NOTAFTER_EXPIRED:
649 case HITLS_X509_ERR_VFY_CRL_NOT_FOUND:
651 case HITLS_X509_ERR_VFY_THISUPDATE_IN_FUTURE:
652 case HITLS_X509_ERR_VFY_NEXTUPDATE_EXPIRED:
661coap_hitls_get_verify_session(HITLS_CERT_StoreCtx *store_ctx,
663 HITLS_Ctx *ctx =
NULL;
665 if (!store_ctx || !session)
668 if (HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
669 HITLS_X509_STORECTX_GET_USR_DATA,
670 &ctx,
sizeof(ctx)) != HITLS_PKI_SUCCESS ||
674 return *session !=
NULL;
678coap_hitls_get_verify_cert(HITLS_CERT_StoreCtx *store_ctx,
679 HITLS_X509_Cert **cert, int32_t *depth) {
680 if (!store_ctx || !cert || !depth)
685 (void)HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
686 HITLS_X509_STORECTX_GET_CUR_DEPTH,
687 depth,
sizeof(*depth));
688 return HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
689 HITLS_X509_STORECTX_GET_CUR_CERT,
690 cert,
sizeof(*cert)) == HITLS_PKI_SUCCESS &&
695coap_hitls_cert_is_self_signed(HITLS_X509_Cert *cert) {
696 bool self_signed =
false;
699 HITLS_X509_CertCtrl(cert, HITLS_X509_IS_SELF_SIGNED,
701 sizeof(self_signed)) == HITLS_PKI_SUCCESS &&
712coap_hitls_cert_time_valid(HITLS_X509_Cert *cert) {
717 int64_t now = BSL_SAL_CurrentSysTimeGet();
720 return BSL_SAL_TIME_SYS_ERROR;
721 if (HITLS_X509_CertCtrl(cert, HITLS_X509_GET_BEFORE_TIME, ¬_before,
722 sizeof(not_before)) != HITLS_PKI_SUCCESS ||
723 BSL_SAL_DateToUtcTimeConvert(¬_before, &start) != BSL_SUCCESS)
724 return HITLS_X509_ERR_VFY_GET_NOTBEFORE_FAIL;
726 return HITLS_X509_ERR_VFY_NOTBEFORE_IN_FUTURE;
727 if (HITLS_X509_CertCtrl(cert, HITLS_X509_GET_AFTER_TIME, ¬_after,
728 sizeof(not_after)) != HITLS_PKI_SUCCESS ||
729 BSL_SAL_DateToUtcTimeConvert(¬_after, &end) != BSL_SUCCESS)
730 return HITLS_X509_ERR_VFY_GET_NOTAFTER_FAIL;
732 return HITLS_X509_ERR_VFY_NOTAFTER_EXPIRED;
733 return HITLS_PKI_SUCCESS;
737coap_hitls_get_peer_leaf_cert(HITLS_CERT_StoreCtx *store_ctx,
738 HITLS_X509_Cert **cert,
739 int32_t *chain_count) {
740 HITLS_X509_List *peer_chain =
NULL;
742 if (!store_ctx || !cert || !chain_count)
747 if (HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
748 HITLS_X509_STORECTX_GET_PEER_CERT_CHAIN,
750 sizeof(peer_chain)) != HITLS_PKI_SUCCESS ||
754 *chain_count = BSL_LIST_COUNT(peer_chain);
755 *cert = (HITLS_X509_Cert *)BSL_LIST_FIRST_ELMT(peer_chain);
756 return *cert !=
NULL;
761 HITLS_CERT_StoreCtx *store_ctx,
762 HITLS_X509_Cert **leaf_cert) {
763 HITLS_X509_Cert *cert =
NULL;
764 int32_t chain_count = 0;
771 if (!coap_hitls_get_peer_leaf_cert(store_ctx, &cert, &chain_count) ||
772 chain_count != 1 || !coap_hitls_cert_is_self_signed(cert))
780coap_hitls_verify_cb_self_signed_allowed(
const coap_dtls_pki_t *setup_data,
781 HITLS_CERT_StoreCtx *store_ctx) {
782 HITLS_X509_Cert *cert =
NULL;
787 coap_hitls_get_verify_cert(store_ctx, &cert, &depth) &&
788 depth == 0 && coap_hitls_cert_is_self_signed(cert);
792coap_hitls_copy_name(
const uint8_t *data, uint32_t data_len) {
794 size_t len = (size_t)data_len;
796 if (data_len && !data)
802 memcpy(copy, data, len);
808coap_hitls_get_san_from_cert(
coap_session_t *session, HITLS_X509_Cert *cert,
809 const char *sni_match,
int report_san) {
810 HITLS_X509_ExtSan san = {0};
811 char *dns_name =
NULL;
813 if (HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_GET_SAN, &san,
814 sizeof(san)) == HITLS_PKI_SUCCESS &&
818 for (BslListNode *name_node = BSL_LIST_FirstNode(san.names);
820 name_node = BSL_LIST_GetNextNode(san.names, name_node)) {
821 const HITLS_X509_GeneralName *name =
822 (
const HITLS_X509_GeneralName *)BSL_LIST_GetData(name_node);
824 if (!name || name->type != HITLS_X509_GN_DNS)
826 if (name->value.dataLen &&
827 memchr(name->value.data,
'\000', name->value.dataLen))
831 coap_session_str(session), n + 1, (
int)name->value.dataLen, (
int)name->value.dataLen,
837 if (strlen(sni_match) != name->value.dataLen ||
838 memcmp(name->value.data, sni_match, name->value.dataLen)) {
842 dns_name = coap_hitls_copy_name(name->value.data, name->value.dataLen);
847 HITLS_X509_ClearSubjectAltName(&san);
852coap_hitls_get_cn_from_cert(
coap_session_t *session, HITLS_X509_Cert *cert,
const char *sni_match) {
854 char *cn_name =
NULL;
856 if (HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SUBJECT_CN_STR,
857 &cn,
sizeof(cn)) == HITLS_PKI_SUCCESS) {
859 cn_name = coap_hitls_copy_name(cn.data, cn.dataLen);
862 if (cn.data && !cn_name) {
867 BSL_SAL_Free(cn.data);
872coap_hitls_get_san_or_cn_from_cert(
coap_session_t *session, HITLS_X509_Cert *cert,
873 const char *sni_match) {
878 name = coap_hitls_get_san_from_cert(session, cert, sni_match, 0);
881 name = coap_hitls_get_cn_from_cert(session, cert, sni_match);
883 name = coap_hitls_get_san_from_cert(session, cert, sni_match, 1);
891 HITLS_X509_Cert *cert,
896 uint32_t der_len = 0;
899 (void)HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODELEN,
900 &der_len,
sizeof(der_len));
902 (void)HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODE,
905 *san_or_cn = coap_hitls_get_san_or_cn_from_cert(session, cert,
NULL);
910 *san_or_cn ? *san_or_cn :
"",
911 der, der_len, session, depth, validated,
918coap_hitls_verify_cb(int32_t err_code, HITLS_CERT_StoreCtx *store_ctx) {
920 coap_hitls_context_t *context;
922 HITLS_X509_Cert *cert;
925 char *san_or_cn =
NULL;
927 if (!coap_hitls_get_verify_session(store_ctx, &session) ||
932 setup_data = &context->setup_data;
934 if (!coap_hitls_get_verify_cert(store_ctx, &cert, &depth)) {
940 san_or_cn = coap_hitls_get_san_or_cn_from_cert(session, cert, setup_data->
client_sni);
943 coap_log_warn(
"* %s: SNI '%s' not returned in certificate\n",
946 return HITLS_X509_ERR_VFY_HOSTNAME_FAIL;
950 if (!coap_hitls_validate_cn_cert(session, setup_data, cert,
951 depth < 0 ? 0 : (
unsigned)depth,
952 err_code == HITLS_PKI_SUCCESS, &san_or_cn)) {
955 coap_hitls_verify_err_str(HITLS_X509_ERR_VFY_HOSTNAME_FAIL));
958 return HITLS_X509_ERR_VFY_HOSTNAME_FAIL;
964 if (err_code == HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND ||
965 err_code == HITLS_X509_ERR_ROOT_CERT_NOT_FOUND) {
966 allowed = coap_hitls_verify_cb_self_signed_allowed(setup_data,
969 allowed = coap_hitls_verify_error_allowed(setup_data, err_code);
972 coap_log_warn(
"* %s: certificate verification failed: %s (0x%x)\n",
974 coap_hitls_verify_err_str(err_code), (
unsigned int)err_code);
978 return HITLS_PKI_SUCCESS;
982coap_hitls_app_verify_cb(HITLS_CERT_StoreCtx *store_ctx,
985 coap_hitls_context_t *context;
987 HITLS_X509_List *peer_chain =
NULL;
988 HITLS_X509_Cert *leaf_cert =
NULL;
991 if (!coap_hitls_get_verify_session(store_ctx, &session) ||
993 return HITLS_X509_ERR_INVALID_PARAM;
995 if (HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
996 HITLS_X509_STORECTX_GET_PEER_CERT_CHAIN,
998 sizeof(peer_chain)) != HITLS_PKI_SUCCESS ||
1000 return HITLS_X509_ERR_INVALID_PARAM;
1002 ret = HITLS_X509_CertVerify((HITLS_X509_StoreCtx *)store_ctx, peer_chain);
1003 if (ret == HITLS_PKI_SUCCESS)
1004 return HITLS_APP_VERIFY_CALLBACK_SUCCESS;
1007 setup_data = &context->setup_data;
1008 if ((ret == HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND ||
1009 ret == HITLS_X509_ERR_ROOT_CERT_NOT_FOUND) &&
1010 coap_hitls_self_signed_leaf_allowed(setup_data, store_ctx,
1012 char *san_or_cn =
NULL;
1014 int32_t time_ret = coap_hitls_cert_time_valid(leaf_cert);
1016 if (time_ret != HITLS_PKI_SUCCESS) {
1017 coap_log_warn(
"* %s: certificate verification failed: %s\n",
1019 coap_hitls_verify_err_str(time_ret));
1023 coap_log_info(
" %s: %s: overridden: 'self-signed' depth=0\n",
1025 coap_hitls_verify_err_str(ret));
1026 if (!coap_hitls_validate_cn_cert(session, setup_data, leaf_cert, 0, 0, &san_or_cn)) {
1029 return HITLS_X509_ERR_VFY_HOSTNAME_FAIL;
1033 return HITLS_APP_VERIFY_CALLBACK_SUCCESS;
1040coap_hitls_is_retry(int32_t ret) {
1042 case HITLS_WANT_CONNECT:
1043 case HITLS_WANT_ACCEPT:
1044 case HITLS_WANT_READ:
1045 case HITLS_WANT_WRITE:
1046 case HITLS_WANT_BACKUP:
1047 case HITLS_WANT_CLIENT_HELLO_CB:
1048 case HITLS_WANT_X509_LOOKUP:
1049 case HITLS_REC_NORMAL_IO_BUSY:
1050 case HITLS_REC_NORMAL_RECV_BUF_EMPTY:
1058coap_hitls_is_closed(int32_t ret) {
1059 return ret == HITLS_CM_LINK_CLOSED;
1063coap_hitls_udp_overhead(
const coap_hitls_env_t *env) {
1064#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1065 if (env && env->session) {
1066 switch (env->session->addr_info.remote.addr.sa.sa_family) {
1069 return COAP_HITLS_IPV6_UDP_OVERHEAD;
1081 return COAP_HITLS_IPV4_UDP_OVERHEAD;
1085coap_hitls_set_connected(
coap_session_t *session, coap_hitls_env_t *env) {
1086 if (env->established)
1089 env->established = 1;
1099 coap_hitls_env_t *env) {
1102 if (HITLS_IsHandShakeDone(env->ctx, &done) == HITLS_SUCCESS && done) {
1103 coap_hitls_set_connected(session, env);
1110coap_hitls_handshake(
coap_session_t *session, coap_hitls_env_t *env) {
1113 BSL_ERR_ClearError();
1115 ret = HITLS_Connect(env->ctx);
1117 ret = HITLS_Accept(env->ctx);
1119 if (ret == HITLS_SUCCESS)
1120 return coap_hitls_check_handshake_done(session, env);
1121 if (coap_hitls_check_handshake_done(session, env))
1123 if (coap_hitls_is_retry(ret))
1126 coap_log_warn(
"coap_hitls_handshake: returned 0x%x\n", (
unsigned int)ret);
1127 coap_hitls_log_fatal_err_stack(session);
1133coap_hitls_uio_write(BSL_UIO *uio,
const void *buf, uint32_t len,
1134 uint32_t *write_len) {
1135 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1140 if (!env || !env->session || !buf || !write_len)
1141 return BSL_NULL_INPUT;
1144 && env->session->endpoint ==
NULL
1148 return BSL_UIO_IO_EXCEPTION;
1151 (void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
1152 ret = env->session->sock.lfunc[
COAP_LAYER_TLS].l_write(env->session,
1153 (
const uint8_t *)buf, len);
1156 if (errno == EMSGSIZE) {
1157 env->mtu_exceeded = 1;
1158 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY);
1162 if (errno == ENOTCONN || errno == ECONNREFUSED)
1164 return BSL_UIO_IO_EXCEPTION;
1167 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY);
1170 *write_len = (uint32_t)ret;
1175coap_hitls_uio_read(BSL_UIO *uio,
void *buf, uint32_t len,
1176 uint32_t *read_len) {
1177 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1182 if (!env || !buf || !read_len)
1183 return BSL_NULL_INPUT;
1187 (void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
1188 ret = env->session->sock.lfunc[
COAP_LAYER_TLS].l_read(env->session,
1189 (uint8_t *)buf, len);
1191 return errno == ECONNRESET ? BSL_UIO_IO_EOF : BSL_UIO_IO_EXCEPTION;
1193 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_SHOULD_RETRY);
1196 *read_len = (uint32_t)ret;
1199 if (!env->pdu || env->pdu_len == 0) {
1200 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_SHOULD_RETRY);
1204 copy_len = env->pdu_len < len ? env->pdu_len : len;
1205 memcpy(buf, env->pdu, copy_len);
1206 env->pdu += copy_len;
1207 env->pdu_len -= copy_len;
1208 *read_len = (uint32_t)copy_len;
1213coap_hitls_uio_ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg,
void *parg) {
1214 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1217 return BSL_NULL_INPUT;
1220 case BSL_UIO_GET_FD:
1223 *(int32_t *)parg = -1;
1224#elif COAP_SERVER_SUPPORT
1227 env->session->endpoint->sock.fd :
1228 env->session->sock.fd :
1229 env->session->sock.fd);
1231 *(int32_t *)parg = (int32_t)env->session->sock.fd;
1235 case BSL_UIO_SET_FD:
1236 case BSL_UIO_SET_PEER_IP_ADDR:
1237 case BSL_UIO_UDP_SET_CONNECTED:
1241 case BSL_UIO_GET_PEER_IP_ADDR:
1242 if (!parg || !env->session)
1243 return BSL_NULL_INPUT;
1244 if (larg == (int32_t)
sizeof(BSL_UIO_CtrlGetPeerIpAddrParam)) {
1245 BSL_UIO_CtrlGetPeerIpAddrParam *param =
1246 (BSL_UIO_CtrlGetPeerIpAddrParam *)parg;
1247 uint32_t addr_len = (uint32_t)env->session->addr_info.remote.size;
1249 if (!param->addr || param->size < addr_len)
1250 return BSL_INVALID_ARG;
1251 memcpy(param->addr, &env->session->addr_info.remote.addr.sa, addr_len);
1252 param->size = addr_len;
1255 if (env->session->addr_info.remote.size > (socklen_t)larg)
1256 return BSL_INVALID_ARG;
1257 memcpy(parg, &env->session->addr_info.remote.addr.sa,
1258 env->session->addr_info.remote.size);
1260 case BSL_UIO_PENDING:
1261 case BSL_UIO_WPENDING:
1263 *(uint64_t *)parg = cmd == BSL_UIO_PENDING ? env->pdu_len : 0;
1265 case BSL_UIO_UDP_GET_MTU_OVERHEAD:
1267 return BSL_NULL_INPUT;
1268 if (larg != (int32_t)
sizeof(uint8_t))
1269 return BSL_INVALID_ARG;
1270 *(uint8_t *)parg = coap_hitls_udp_overhead(env);
1272 case BSL_UIO_UDP_QUERY_MTU:
1274 return BSL_NULL_INPUT;
1275 if (larg != (int32_t)
sizeof(uint32_t))
1276 return BSL_INVALID_ARG;
1277 *(uint32_t *)parg = env->session->mtu > UINT32_MAX ?
1278 UINT32_MAX : (uint32_t)env->session->mtu;
1280 case BSL_UIO_UDP_MTU_EXCEEDED:
1282 return BSL_NULL_INPUT;
1283 if (larg != (int32_t)
sizeof(
bool))
1284 return BSL_INVALID_ARG;
1285 *(
bool *)parg = env->mtu_exceeded != 0;
1286 env->mtu_exceeded = 0;
1294coap_hitls_setup_uio(coap_hitls_env_t *env) {
1296 BSL_UIO_TransportType type =
1299 env->method = BSL_UIO_NewMethod();
1302#if defined(__GNUC__)
1303#pragma GCC diagnostic push
1304#pragma GCC diagnostic ignored "-Wpedantic"
1306 if (BSL_UIO_SetMethodType(env->method, type) != BSL_SUCCESS ||
1307 BSL_UIO_SetMethod(env->method, BSL_UIO_WRITE_CB,
1308 (
void *)coap_hitls_uio_write) != BSL_SUCCESS ||
1309 BSL_UIO_SetMethod(env->method, BSL_UIO_READ_CB,
1310 (
void *)coap_hitls_uio_read) != BSL_SUCCESS ||
1311 BSL_UIO_SetMethod(env->method, BSL_UIO_CTRL_CB,
1312 (
void *)coap_hitls_uio_ctrl) != BSL_SUCCESS) {
1313 BSL_UIO_FreeMethod(env->method);
1317#if defined(__GNUC__)
1318#pragma GCC diagnostic pop
1321 uio = BSL_UIO_New(env->method);
1324 if (BSL_UIO_SetUserData(uio, env) != BSL_SUCCESS) {
1328 BSL_UIO_SetInit(uio,
true);
1329 if (HITLS_SetUio(env->ctx, uio) != HITLS_SUCCESS) {
1330 BSL_UIO_SetUserData(uio,
NULL);
1334 env->uio = HITLS_GetUio(env->ctx);
1340coap_hitls_update_mtu(coap_hitls_env_t *env) {
1344 if (!env || !env->ctx || !env->session || env->proto !=
COAP_PROTO_DTLS)
1347 mtu = env->session->mtu > UINT16_MAX ? UINT16_MAX :
1348 (uint16_t)env->session->mtu;
1349 ret = HITLS_SetMtu(env->ctx, mtu);
1350 if (ret != HITLS_SUCCESS) {
1356#if COAP_CLIENT_SUPPORT
1358coap_hitls_psk_client_cb(HITLS_Ctx *ctx,
const uint8_t *hint,
1359 uint8_t *identity, uint32_t max_identity_len,
1360 uint8_t *psk, uint32_t max_psk_len) {
1367 if (!session || !session->
context)
1375 temp.
s = hint ? hint : (
const uint8_t *)
"";
1389 psk_identity = &cpsk_info->
identity;
1390 psk_key = &cpsk_info->
key;
1396 if (coap_hitls_copy_bin(identity, max_identity_len, psk_identity, 1) == 0 ||
1397 coap_hitls_copy_bin(psk, max_psk_len, psk_key, 0) == 0)
1399 return (uint32_t)psk_key->
length;
1403#if COAP_SERVER_SUPPORT
1408coap_hitls_sni_cb(HITLS_Ctx *ctx,
int *alert
COAP_UNUSED,
1411 coap_hitls_context_t *context =
1419 if (!session || !session->
context)
1420 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1421 sni = HITLS_GetServerName(ctx, HITLS_SNI_HOSTNAME_TYPE);
1427 HITLS_Config *new_config;
1433 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1434 new_config = coap_hitls_new_server_sni_config(session, session->
proto,
1437 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1438 if (!HITLS_SetNewConfig(ctx, new_config)) {
1439 HITLS_CFG_FreeConfig(new_config);
1440 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1442 HITLS_CFG_FreeConfig(new_config);
1446 psk_setup_data = &session->
context->spsk_setup_data;
1454 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1457 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1460 HITLS_SetPskIdentityHint(ctx, new_entry->
hint.
s,
1461 (uint32_t)new_entry->
hint.
length) != HITLS_SUCCESS)
1462 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1466 return accepted ? HITLS_ACCEPT_SNI_ERR_OK : HITLS_ACCEPT_SNI_ERR_NOACK;
1470coap_hitls_psk_server_cb(HITLS_Ctx *ctx,
const uint8_t *identity,
1471 uint8_t *psk, uint32_t max_psk_len) {
1477 if (!session || !session->
context)
1480 setup_data = &session->
context->spsk_setup_data;
1481 lidentity.
s = identity ? identity : (
const uint8_t *)
"";
1482 lidentity.
length = coap_hitls_strnlen(lidentity.
s,
1496 if (coap_hitls_copy_bin(psk, max_psk_len, psk_key, 0) == 0)
1498 return (uint32_t)psk_key->
length;
1503coap_hitls_alpn_select_cb(HITLS_Ctx *ctx
COAP_UNUSED,
1504 uint8_t **selected_proto,
1505 uint8_t *selected_proto_len,
1506 uint8_t *client_alpn_list,
1507 uint32_t client_alpn_list_size,
1509 if (HITLS_SelectAlpnProtocol(selected_proto, selected_proto_len,
1510 coap_hitls_alpn,
sizeof(coap_hitls_alpn),
1512 client_alpn_list_size) != HITLS_SUCCESS ||
1513 !selected_proto || !*selected_proto ||
1514 !selected_proto_len || *selected_proto_len != 4)
1515 return HITLS_ALPN_ERR_ALERT_FATAL;
1516 return HITLS_ALPN_ERR_OK;
1527 switch (define->
ca_def) {
1531 if (HITLS_CFG_LoadVerifyFile(config, define->
ca.
s_byte) == HITLS_SUCCESS)
1539 TLS_PARSE_FORMAT_PEM, &len))
1542 if (HITLS_CFG_LoadVerifyBuffer(config, define->
ca.
u_byte, len,
1543 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1551 TLS_PARSE_FORMAT_ASN1, &len))
1554 if (HITLS_CFG_LoadVerifyBuffer(config, define->
ca.
u_byte, len,
1555 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1562 buf = coap_hitls_read_file(define->
ca.
s_byte, &len);
1566 ret = HITLS_CFG_LoadVerifyBuffer(config, buf, len, TLS_PARSE_FORMAT_ASN1);
1568 if (ret == HITLS_SUCCESS)
1587coap_hitls_load_public_cert(HITLS_Config *config,
coap_dtls_key_t *key,
1597 if (HITLS_CFG_UseCertificateChainFile(config,
1606 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1620 len, TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1633 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1652coap_hitls_load_private_key(HITLS_Config *config,
coap_dtls_key_t *key,
1662 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1670 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1683 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1696 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1715coap_hitls_load_root_cas(HITLS_Config *config, coap_hitls_context_t *context) {
1716 if (context->root_ca_file &&
1717 HITLS_CFG_LoadVerifyFile(config, context->root_ca_file) != HITLS_SUCCESS) {
1719 context->root_ca_file);
1722 if (context->root_ca_dir &&
1723 HITLS_CFG_LoadVerifyDir(config, context->root_ca_dir) != HITLS_SUCCESS) {
1725 context->root_ca_dir);
1728 if (context->trust_store_defined &&
1729 HITLS_CFG_LoadDefaultCAPath(config) != HITLS_SUCCESS) {
1737coap_hitls_configure_pki(HITLS_Config *config,
coap_session_t *session,
1740 coap_hitls_context_t *context =
1747 if (pki_setup_data) {
1748 setup_data_copy = *pki_setup_data;
1749 setup_data = &setup_data_copy;
1751 if (!context || !setup_data)
1753 if (!coap_hitls_check_pki_key_supported(setup_data, role))
1760 if (!coap_hitls_load_root_cas(config, context) ||
1761 !coap_hitls_load_ca(config, &key, role) ||
1762 !coap_hitls_load_public_cert(config, &key, role) ||
1763 !coap_hitls_load_private_key(config, &key, role))
1767 HITLS_CFG_SetVerifyDepth(config,
1768 COAP_HITLS_VERIFY_DEPTH_TO_MAX_CHAIN_DEPTH(
1773 HITLS_CFG_SetVerifyFlags(config,
1774 HITLS_X509_VFY_FLAG_CRL_ALL) != HITLS_SUCCESS)
1776 if (HITLS_CFG_SetVerifyCb(config, coap_hitls_verify_cb) != HITLS_SUCCESS)
1778 if (HITLS_CFG_SetCertVerifyCb(config, coap_hitls_app_verify_cb,
1779 NULL) != HITLS_SUCCESS)
1784 HITLS_CFG_SetServerName(config,
1786 (uint32_t)strlen(setup_data->
client_sni)) != HITLS_SUCCESS)
1789 if (HITLS_CFG_SetClientVerifySupport(config,
1793 HITLS_CFG_SetNoClientCertSupport(config,
false) != HITLS_SUCCESS)
1797 if (HITLS_CFG_SetVerifyNoneSupport(config,
1803#if COAP_SERVER_SUPPORT
1804static HITLS_Config *
1807 coap_hitls_context_t *context =
1810 const uint16_t *cipher_suites;
1811 uint32_t cipher_suites_count;
1812 int enabled = context && context->psk_pki_enabled ?
1813 context->psk_pki_enabled : IS_PKI;
1815 HITLS_Config *config;
1817 if (!context || !new_key)
1821 HITLS_CFG_NewTLS12Config();
1825 coap_hitls_get_cipher_suites(enabled, &cipher_suites, &cipher_suites_count);
1826 if (HITLS_CFG_SetCipherSuites(config, cipher_suites,
1827 cipher_suites_count) != HITLS_SUCCESS) {
1828 HITLS_CFG_FreeConfig(config);
1832 (HITLS_CFG_SetFlightTransmitSwitch(config,
true) != HITLS_SUCCESS ||
1833 HITLS_CFG_SetDtlsCookieExchangeSupport(config,
true) != HITLS_SUCCESS ||
1834 HITLS_CFG_SetCookieGenCb(config,
1835 coap_hitls_cookie_gen_cb) != HITLS_SUCCESS ||
1836 HITLS_CFG_SetCookieVerifyCb(config,
1837 coap_hitls_cookie_verify_cb) != HITLS_SUCCESS)) {
1838 HITLS_CFG_FreeConfig(config);
1842 HITLS_CFG_SetAlpnProtosSelectCb(config, coap_hitls_alpn_select_cb,
1843 NULL) != HITLS_SUCCESS) {
1844 HITLS_CFG_FreeConfig(config);
1847 if (enabled & IS_PSK) {
1850 if (hint && hint->
s && hint->
length <= UINT32_MAX &&
1851 HITLS_CFG_SetPskIdentityHint(config, hint->
s,
1852 (uint32_t)hint->
length) != HITLS_SUCCESS) {
1853 HITLS_CFG_FreeConfig(config);
1856 if (HITLS_CFG_SetPskServerCallback(config,
1857 coap_hitls_psk_server_cb) != HITLS_SUCCESS) {
1858 HITLS_CFG_FreeConfig(config);
1863 pki_setup_data = context->setup_data;
1864 pki_setup_data.
pki_key = *new_key;
1867 HITLS_CFG_FreeConfig(config);
1871 (void)HITLS_CFG_SetInfoCb(config, coap_hitls_info_cb);
1876static HITLS_Config *
1879 coap_hitls_context_t *hitls_context =
1882 const uint16_t *cipher_suites;
1883 uint32_t cipher_suites_count;
1884 int enabled = hitls_context && hitls_context->psk_pki_enabled ?
1885 hitls_context->psk_pki_enabled : IS_PSK;
1887 HITLS_CFG_NewDTLS12Config() :
1888 HITLS_CFG_NewTLS12Config();
1893 coap_hitls_get_cipher_suites(enabled, &cipher_suites, &cipher_suites_count);
1895 if (HITLS_CFG_SetCipherSuites(config, cipher_suites,
1896 cipher_suites_count) != HITLS_SUCCESS) {
1897 HITLS_CFG_FreeConfig(config);
1901 (HITLS_CFG_SetFlightTransmitSwitch(config,
true) != HITLS_SUCCESS ||
1902 HITLS_CFG_SetDtlsCookieExchangeSupport(config,
1904 HITLS_CFG_FreeConfig(config);
1907#if COAP_SERVER_SUPPORT
1909 (HITLS_CFG_SetCookieGenCb(config,
1910 coap_hitls_cookie_gen_cb) != HITLS_SUCCESS ||
1911 HITLS_CFG_SetCookieVerifyCb(config,
1912 coap_hitls_cookie_verify_cb) != HITLS_SUCCESS)) {
1913 HITLS_CFG_FreeConfig(config);
1919 HITLS_CFG_SetAlpnProtos(config, coap_hitls_alpn,
1920 sizeof(coap_hitls_alpn)) != HITLS_SUCCESS) ||
1922 HITLS_CFG_SetAlpnProtosSelectCb(config,
1923 coap_hitls_alpn_select_cb,
1924 NULL) != HITLS_SUCCESS))) {
1925 HITLS_CFG_FreeConfig(config);
1930#if COAP_CLIENT_SUPPORT
1934 HITLS_CFG_SetServerName(config,
1936 (uint32_t)strlen(setup_data->
client_sni)) != HITLS_SUCCESS) {
1937 HITLS_CFG_FreeConfig(config);
1940 if (HITLS_CFG_SetPskClientCallback(config,
1941 coap_hitls_psk_client_cb) != HITLS_SUCCESS) {
1942 HITLS_CFG_FreeConfig(config);
1947 HITLS_CFG_FreeConfig(config);
1951#if COAP_SERVER_SUPPORT
1954 if (hint && hint->
s && hint->
length <= UINT32_MAX &&
1955 HITLS_CFG_SetPskIdentityHint(config, hint->
s,
1956 (uint32_t)hint->
length) != HITLS_SUCCESS) {
1957 HITLS_CFG_FreeConfig(config);
1960 if (HITLS_CFG_SetPskServerCallback(config,
1961 coap_hitls_psk_server_cb) != HITLS_SUCCESS) {
1962 HITLS_CFG_FreeConfig(config);
1967 HITLS_CFG_FreeConfig(config);
1972#if COAP_SERVER_SUPPORT
1976 if ((enabled & IS_PSK) && session && session->
context &&
1977 session->
context->spsk_setup_data.validate_sni_call_back)
1979 if ((enabled & IS_PKI) && hitls_context &&
1980 hitls_context->setup_data.validate_sni_call_back)
1983 (HITLS_CFG_SetServerNameCb(config,
1984 coap_hitls_sni_cb) != HITLS_SUCCESS ||
1985 HITLS_CFG_SetServerNameArg(config,
NULL) != HITLS_SUCCESS)) {
1986 HITLS_CFG_FreeConfig(config);
1992 if ((enabled & IS_PKI) &&
1993 !coap_hitls_configure_pki(config, session, role,
NULL)) {
1994 HITLS_CFG_FreeConfig(config);
1998 (void)HITLS_CFG_SetInfoCb(config, coap_hitls_info_cb);
2003coap_hitls_free_env(coap_hitls_env_t *env) {
2007 if (env->established && !env->had_fatal)
2008 (void)HITLS_Close(env->ctx);
2010 BSL_UIO_SetUserData(env->uio,
NULL);
2011 HITLS_Free(env->ctx);
2012 }
else if (env->uio) {
2013 BSL_UIO_SetUserData(env->uio,
NULL);
2016 BSL_UIO_FreeMethod(env->method);
2020static coap_hitls_env_t *
2021coap_hitls_live_env(
coap_session_t *session, coap_hitls_env_t *env) {
2022 return session && session->
tls == (
void *)env ? env :
NULL;
2026coap_hitls_clear_pdu(coap_hitls_env_t *env) {
2033static coap_hitls_env_t *
2036 coap_hitls_env_t *env =
2038 coap_hitls_context_t *hitls_context =
2041 HITLS_Config *config;
2045 memset(env, 0,
sizeof(*env));
2046 env->session = session;
2050 config = coap_hitls_new_config(session, role, proto);
2056 env->ctx = HITLS_New(config);
2057 HITLS_CFG_FreeConfig(config);
2062 if (HITLS_SetUserData(env->ctx, session) != HITLS_SUCCESS ||
2063 !coap_hitls_setup_uio(env)) {
2064 coap_hitls_free_env(env);
2067 coap_hitls_update_mtu(env);
2068 if (hitls_context && (hitls_context->psk_pki_enabled & IS_PKI) &&
2069 hitls_context->setup_data.additional_tls_setup_call_back &&
2070 !hitls_context->setup_data.additional_tls_setup_call_back(env->ctx,
2071 &hitls_context->setup_data)) {
2072 coap_hitls_free_env(env);
2086#if !COAP_DISABLE_TCP
2118#if COAP_CLIENT_SUPPORT
2141 version.
version = HITLS_VersionNum();
2149 (void)coap_hitls_startup();
2154 if (coap_hitls_started) {
2155#if COAP_WITH_LIBOPENHITLS
2156 HITLS_CertMethodDeinit();
2158 CRYPT_EAL_Cleanup(CRYPT_EAL_INIT_ALL);
2159 coap_hitls_started = 0;
2166 BSL_ERR_RemoveErrorStack(
false);
2169#if COAP_WITH_LIBOPENHITLS
2172 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2176 return env ? env->ctx :
NULL;
2181 coap_hitls_context_t *context =
2186 memset(context, 0,
sizeof(*context));
2187 context->coap_context = coap_context;
2189 sizeof(context->cookie_secret))) {
2193 context->cookie_secret_set = 1;
2199 coap_hitls_context_t *context = (coap_hitls_context_t *)dtls_context;
2202 if (context->root_ca_file)
2204 if (context->root_ca_dir)
2206 memset(context->cookie_secret, 0,
sizeof(context->cookie_secret));
2207 context->cookie_secret_set = 0;
2212#if COAP_SERVER_SUPPORT
2216 coap_hitls_context_t *context;
2218 if (!coap_context || !setup_data)
2220 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2223 context->psk_pki_enabled |= IS_PSK;
2228#if COAP_CLIENT_SUPPORT
2232 coap_hitls_context_t *context;
2234 if (!coap_context || !setup_data)
2236 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2239 context->psk_pki_enabled |= IS_PSK;
2248 coap_hitls_context_t *context;
2250 if (!coap_context || !setup_data)
2252 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2255 if (!coap_hitls_check_pki_key_supported(setup_data, role))
2257 context->setup_data = *setup_data;
2258 if (!context->setup_data.verify_peer_cert) {
2260 context->setup_data.check_common_ca = 0;
2262 context->setup_data.allow_self_signed = 1;
2263 context->setup_data.allow_expired_certs = 1;
2264 context->setup_data.cert_chain_validation = 1;
2265 context->setup_data.cert_chain_verify_depth = 10;
2266 context->setup_data.check_cert_revocation = 1;
2267 context->setup_data.allow_no_crl = 1;
2268 context->setup_data.allow_expired_crl = 1;
2269 context->setup_data.allow_bad_md_hash = 1;
2270 context->setup_data.allow_short_rsa_length = 1;
2272#if COAP_CLIENT_SUPPORT
2274 context->psk_pki_enabled &= ~IS_PSK;
2278 context->psk_pki_enabled |= IS_PKI;
2280 coap_log_warn(
"openHiTLS backend has no Connection-ID support\n");
2286 const char *ca_file,
2287 const char *ca_dir) {
2288 coap_hitls_context_t *context;
2289 char *new_ca_file =
NULL;
2290 char *new_ca_dir =
NULL;
2292 if (!coap_context || (!ca_file && !ca_dir))
2294 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2298 new_ca_file = coap_hitls_strdup(ca_file);
2303 new_ca_dir = coap_hitls_strdup(ca_dir);
2310 if (context->root_ca_file)
2312 if (context->root_ca_dir)
2314 context->root_ca_file = new_ca_file;
2315 context->root_ca_dir = new_ca_dir;
2321 coap_hitls_context_t *context =
2326 context->trust_store_defined = 1;
2332 coap_hitls_context_t *context =
2335 return context && context->psk_pki_enabled;
2339#if COAP_SERVER_SUPPORT
2341coap_digest_setup(
void) {
2342 CRYPT_EAL_MdCtx *digest_ctx;
2344 if (!coap_hitls_startup())
2346 digest_ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
2349 if (CRYPT_EAL_MdInit(digest_ctx) != CRYPT_SUCCESS) {
2350 CRYPT_EAL_MdFreeCtx(digest_ctx);
2357coap_digest_free(coap_digest_ctx_t *digest_ctx) {
2359 CRYPT_EAL_MdFreeCtx((CRYPT_EAL_MdCtx *)digest_ctx);
2363coap_digest_update(coap_digest_ctx_t *digest_ctx,
2364 const uint8_t *data,
2366 CRYPT_EAL_MdCtx *ctx = (CRYPT_EAL_MdCtx *)digest_ctx;
2368 if (!ctx || (!data && data_len))
2371 uint32_t chunk = data_len > UINT32_MAX ? UINT32_MAX : (uint32_t)data_len;
2373 if (CRYPT_EAL_MdUpdate(ctx, data, chunk) != CRYPT_SUCCESS)
2382coap_digest_final(coap_digest_ctx_t *digest_ctx,
2383 coap_digest_t *digest_buffer) {
2384 CRYPT_EAL_MdCtx *ctx = (CRYPT_EAL_MdCtx *)digest_ctx;
2385 uint32_t len =
sizeof(*digest_buffer);
2388 if (!ctx || !digest_buffer)
2390 ret = CRYPT_EAL_MdFinal(ctx, (uint8_t *)digest_buffer, &len) == CRYPT_SUCCESS &&
2391 len ==
sizeof(*digest_buffer);
2392 coap_digest_free(digest_ctx);
2398static const struct {
2402} coap_hitls_hashs[] = {
2416 CRYPT_MD_AlgId md = CRYPT_MD_SHA1;
2417 uint32_t out_len = 0;
2419 if (!data || !hash || data->
length > UINT32_MAX || !coap_hitls_startup())
2421 for (i = 0; i <
sizeof(coap_hitls_hashs) /
sizeof(coap_hitls_hashs[0]); i++) {
2422 if (coap_hitls_hashs[i].alg == alg) {
2423 md = coap_hitls_hashs[i].md;
2424 out_len = coap_hitls_hashs[i].length;
2429 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
2433 len = CRYPT_EAL_MdGetDigestSize(md);
2438 if (CRYPT_EAL_Md(md, data->
s, (uint32_t)data->
length,
2439 digest->
s, &len) != CRYPT_SUCCESS ||
2444 if (out_len < digest->length)
2445 digest->
length = out_len;
2452#if COAP_OSCORE_SUPPORT
2460coap_hitls_get_cipher_alg(
cose_alg_t alg, CRYPT_CIPHER_AlgId *cipher_alg,
2465 *cipher_alg = CRYPT_CIPHER_AES128_CCM;
2471 *cipher_alg = CRYPT_CIPHER_AES256_CCM;
2476 coap_log_debug(
"coap_hitls_get_cipher_alg: COSE cipher %d not supported\n",
2483coap_hitls_get_hmac_alg(
cose_hmac_alg_t hmac_alg, CRYPT_MAC_AlgId *mac_alg,
2485 switch ((
int)hmac_alg) {
2488 *mac_alg = CRYPT_MAC_HMAC_SHA256;
2494 *mac_alg = CRYPT_MAC_HMAC_SHA384;
2500 *mac_alg = CRYPT_MAC_HMAC_SHA512;
2505 coap_log_debug(
"coap_hitls_get_hmac_alg: COSE HMAC %d not supported\n",
2513 return coap_hitls_get_cipher_alg(alg,
NULL,
NULL);
2522 return coap_hitls_get_hmac_alg(hmac_alg,
NULL,
NULL);
2529 if (ccm->
l == 0 || ccm->
l > 8)
2537coap_hitls_aead_set_common(CRYPT_EAL_CipherCtx *ctx,
2540 uint32_t tag_len = (uint32_t)ccm->
tag_len;
2541 uint32_t aad_len = 0;
2543 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN,
2544 &tag_len,
sizeof(tag_len)) != CRYPT_SUCCESS)
2546 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN,
2547 &msg_len,
sizeof(msg_len)) != CRYPT_SUCCESS)
2549 if (aad && aad->length) {
2550 if (aad->length > UINT32_MAX)
2552 aad_len = (uint32_t)aad->length;
2554 return CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD,
2555 aad_len ? (
void *)(uintptr_t)aad->s :
NULL,
2556 aad_len) == CRYPT_SUCCESS;
2564 size_t *max_result_len) {
2565 CRYPT_CIPHER_AlgId cipher_alg;
2566 CRYPT_EAL_CipherCtx *ctx =
NULL;
2574 if (!params || !data || !result || !max_result_len)
2576 if (!coap_hitls_get_cipher_alg(params->
alg, &cipher_alg, &key_len))
2580 if (!coap_hitls_check_ccm_params(ccm, key_len) ||
2581 data->
length > UINT32_MAX ||
2582 ccm->
tag_len > *max_result_len ||
2584 !coap_hitls_startup())
2587 ctx = CRYPT_EAL_CipherNewCtx(cipher_alg);
2591 out_len = (uint32_t)data->
length;
2592 tag_len = (uint32_t)ccm->
tag_len;
2594 if (CRYPT_EAL_CipherInit(ctx, ccm->
key.
s, (uint32_t)ccm->
key.
length,
2595 ccm->
nonce, (uint32_t)(15 - ccm->
l),
2596 true) != CRYPT_SUCCESS)
2598 if (!coap_hitls_aead_set_common(ctx, ccm, aad, msg_len))
2600 if (CRYPT_EAL_CipherUpdate(ctx, data->
s, (uint32_t)data->
length,
2601 result, &out_len) != CRYPT_SUCCESS)
2603 if (out_len != data->
length)
2605 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG,
2606 result + out_len, tag_len) != CRYPT_SUCCESS)
2609 *max_result_len = (size_t)out_len + ccm->
tag_len;
2613 CRYPT_EAL_CipherFreeCtx(ctx);
2622 size_t *max_result_len) {
2623 CRYPT_CIPHER_AlgId cipher_alg;
2624 CRYPT_EAL_CipherCtx *ctx =
NULL;
2635 if (!params || !data || !result || !max_result_len)
2637 if (!coap_hitls_get_cipher_alg(params->
alg, &cipher_alg, &key_len))
2641 if (!coap_hitls_check_ccm_params(ccm, key_len) ||
2643 data->
length > UINT32_MAX ||
2644 !coap_hitls_startup())
2648 if (*max_result_len < cipher_len)
2651 ctx = CRYPT_EAL_CipherNewCtx(cipher_alg);
2655 tag = data->
s + cipher_len;
2656 out_len = (uint32_t)cipher_len;
2658 tag_len = (uint32_t)ccm->
tag_len;
2659 msg_len = cipher_len;
2660 if (CRYPT_EAL_CipherInit(ctx, ccm->
key.
s, (uint32_t)ccm->
key.
length,
2661 ccm->
nonce, (uint32_t)(15 - ccm->
l),
2662 false) != CRYPT_SUCCESS)
2664 if (!coap_hitls_aead_set_common(ctx, ccm, aad, msg_len))
2666 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAG,
2667 (
void *)(uintptr_t)tag, tag_len) != CRYPT_SUCCESS)
2669 if (CRYPT_EAL_CipherUpdate(ctx, data->
s, (uint32_t)cipher_len,
2670 result, &out_len) != CRYPT_SUCCESS)
2672 if (out_len != cipher_len)
2674 if (CRYPT_EAL_CipherFinal(ctx, result, &final_len) != CRYPT_SUCCESS)
2679 *max_result_len = out_len;
2683 CRYPT_EAL_CipherFreeCtx(ctx);
2692 CRYPT_MAC_AlgId mac_alg;
2693 CRYPT_EAL_MacCtx *ctx =
NULL;
2699 if (!key || !data || !hmac ||
2700 key->
length > UINT32_MAX || data->
length > UINT32_MAX ||
2701 !coap_hitls_get_hmac_alg(hmac_alg, &mac_alg, &mac_len) ||
2702 !coap_hitls_startup())
2709 ctx = CRYPT_EAL_MacNewCtx(mac_alg);
2713 out_len = (uint32_t)
dummy->length;
2714 if (CRYPT_EAL_MacInit(ctx, key->
s, (uint32_t)key->
length) != CRYPT_SUCCESS)
2716 if (CRYPT_EAL_MacUpdate(ctx, data->
s, (uint32_t)data->
length) != CRYPT_SUCCESS)
2718 if (CRYPT_EAL_MacFinal(ctx,
dummy->s, &out_len) != CRYPT_SUCCESS ||
2719 out_len !=
dummy->length)
2727 CRYPT_EAL_MacFreeCtx(ctx);
2734#if COAP_WITH_LIBOPENHITLS
2735#if COAP_CLIENT_SUPPORT
2738 coap_hitls_env_t *env =
2742 if (env && coap_hitls_handshake(session, env) < 0) {
2743 coap_hitls_free_env(env);
2751#if COAP_SERVER_SUPPORT
2754 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2758 if (coap_hitls_handshake(session, env) < 0) {
2759 coap_hitls_free_env(env);
2769 if (session && session->
context && session->
tls) {
2770 coap_hitls_free_env((coap_hitls_env_t *)session->
tls);
2779 coap_hitls_update_mtu((coap_hitls_env_t *)session->
tls);
2784 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2785 uint32_t written = 0;
2788 if (!env || data_len > UINT32_MAX)
2794 if (!env->established) {
2795 ret = coap_hitls_handshake(session, env);
2798 return ret == 0 ? 0 : -1;
2801 BSL_ERR_ClearError();
2802 ret = HITLS_Write(env->ctx, data, (uint32_t)data_len, &written);
2803 if (ret == HITLS_SUCCESS) {
2806 return (ssize_t)written;
2808 if (coap_hitls_is_retry(ret))
2811 session->
dtls_event = coap_hitls_is_closed(ret) ?
2814 coap_log_warn(
"coap_dtls_send: returned 0x%x\n", (
unsigned int)ret);
2815 coap_hitls_log_fatal_err_stack(session);
2833 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2834 uint64_t timeout_us = 0;
2839 ret = HITLS_DtlsGetTimeout(env->ctx, &timeout_us);
2840 if (ret == HITLS_MSG_HANDLE_ERR_WITHOUT_TIMEOUT_ACTION)
2842 if (ret != HITLS_SUCCESS) {
2847 if (timeout_us == 0) {
2854 env->last_timeout = now;
2863 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2873 BSL_ERR_ClearError();
2874 ret = HITLS_DtlsProcessTimeout(env->ctx);
2875 if (ret == HITLS_SUCCESS ||
2876 ret == HITLS_MSG_HANDLE_DTLS_RETRANSMIT_NOT_TIMEOUT ||
2877 coap_hitls_is_retry(ret))
2882 coap_hitls_log_fatal_err_stack(session);
2890 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2901 env->pdu_len = data_len;
2903 if (env->established) {
2904#if COAP_CONSTRAINED_STACK
2909 uint32_t read_len = 0;
2912 BSL_ERR_ClearError();
2913 hret = HITLS_Read(env->ctx, pdu,
sizeof(pdu), &read_len);
2915 if (hret == HITLS_SUCCESS && read_len > 0) {
2921 if (hret == HITLS_SUCCESS || coap_hitls_is_retry(hret)) {
2925 session->
dtls_event = coap_hitls_is_closed(hret) ?
2929 (
unsigned int)hret, data_len);
2930 coap_hitls_log_fatal_err_stack(session);
2938 (void)coap_hitls_handshake(session, env);
2952 coap_hitls_clear_pdu(coap_hitls_live_env(session, env));
2956#if COAP_SERVER_SUPPORT
2960 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2962 int cookie_valid = 0;
2972 env->pdu_len = data_len;
2974 if (!env->hello_verify_sent) {
2975 BSL_ERR_ClearError();
2979 (
unsigned int)ret, env->pdu_len);
2981 coap_hitls_clear_pdu(env);
2983 if (ret == HITLS_SUCCESS)
2985 if (coap_hitls_is_retry(ret)) {
2987 ret = coap_hitls_handshake(session, env);
2990 env = coap_hitls_live_env(session, env);
2993 env->hello_verify_sent = 1;
2997 coap_log_warn(
"coap_dtls_hello: returned 0x%x\n", (
unsigned int)ret);
2998 coap_hitls_log_fatal_err_stack(session);
3003 cookie_valid = coap_hitls_client_hello_cookie_valid(session, data, data_len);
3004 ret = coap_hitls_handshake(session, env);
3005 env = coap_hitls_live_env(session, env);
3006 coap_hitls_clear_pdu(env);
3008 if (ret < 0 || !env)
3010 return cookie_valid == 1 ? 1 : 0;
3016 return COAP_HITLS_DTLS_OVERHEAD;
3019#if !COAP_DISABLE_TCP
3020#if COAP_CLIENT_SUPPORT
3023 coap_hitls_env_t *env =
3027 if (env && coap_hitls_handshake(session, env) < 0) {
3028 coap_hitls_free_env(env);
3036#if COAP_SERVER_SUPPORT
3039 coap_hitls_env_t *env =
3043 if (env && coap_hitls_handshake(session, env) < 0) {
3044 coap_hitls_free_env(env);
3059 uint8_t rwstate = HITLS_NOTHING;
3061 (void)HITLS_GetRwstate(ctx, &rwstate);
3062 if (rwstate == HITLS_WRITING) {
3064#ifdef COAP_EPOLL_SUPPORT
3078 const uint8_t *data,
3080 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
3081 uint32_t written = 0;
3084 if (!env || data_len > UINT32_MAX) {
3090 if (!env->established) {
3091 ret = coap_hitls_handshake(session, env);
3095 coap_hitls_tcp_want(session, env->ctx);
3099 BSL_ERR_ClearError();
3100 ret = HITLS_Write(env->ctx, data, (uint32_t)data_len, &written);
3101 if (ret == HITLS_SUCCESS) {
3103 if (written == data_len)
3110 return (ssize_t)written;
3112 if (coap_hitls_is_retry(ret)) {
3113 coap_hitls_tcp_want(session, env->ctx);
3117 session->
dtls_event = coap_hitls_is_closed(ret) ?
3120 coap_log_warn(
"coap_tls_write: returned 0x%x\n", (
unsigned int)ret);
3121 coap_hitls_log_fatal_err_stack(session);
3131 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
3132 uint32_t read_len = 0;
3135 if (!env || data_len > UINT32_MAX) {
3141 if (!env->established) {
3142 ret = coap_hitls_handshake(session, env);
3146 coap_hitls_tcp_want(session, env->ctx);
3150 BSL_ERR_ClearError();
3151 ret = HITLS_Read(env->ctx, data, (uint32_t)data_len, &read_len);
3152 if (ret == HITLS_SUCCESS) {
3156 return (ssize_t)read_len;
3158 if (coap_hitls_is_retry(ret)) {
3159 coap_hitls_tcp_want(session, env->ctx);
3164 session->
dtls_event = coap_hitls_is_closed(ret) ?
3168 (
unsigned int)ret, data_len);
3169 coap_hitls_log_fatal_err_stack(session);
struct coap_context_t coap_context_t
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.
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
int coap_dtls_context_set_pki(coap_context_t *ctx COAP_UNUSED, const coap_dtls_pki_t *setup_data COAP_UNUSED, const coap_dtls_role_t role COAP_UNUSED)
coap_tick_t coap_dtls_get_timeout(coap_session_t *session COAP_UNUSED, coap_tick_t now COAP_UNUSED)
ssize_t coap_tls_read(coap_session_t *session COAP_UNUSED, uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context COAP_UNUSED)
int coap_dtls_receive(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
void * coap_dtls_get_tls(const coap_session_t *c_session COAP_UNUSED, coap_tls_library_t *tls_lib)
unsigned int coap_dtls_get_overhead(coap_session_t *session COAP_UNUSED)
int coap_dtls_context_load_pki_trust_store(coap_context_t *ctx COAP_UNUSED)
static coap_log_t dtls_log_level
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
ssize_t coap_dtls_send(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
ssize_t coap_tls_write(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
void coap_dtls_session_update_mtu(coap_session_t *session COAP_UNUSED)
int coap_dtls_context_set_pki_root_cas(coap_context_t *ctx COAP_UNUSED, const char *ca_file COAP_UNUSED, const char *ca_path COAP_UNUSED)
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
void coap_dtls_free_context(void *handle COAP_UNUSED)
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
void * coap_dtls_new_context(coap_context_t *coap_context COAP_UNUSED)
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
#define COAP_TICKS_PER_SECOND
Use ms resolution on POSIX systems.
int coap_prng_lkd(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
int coap_handle_event_lkd(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
int coap_handle_dgram(coap_context_t *ctx, coap_session_t *session, uint8_t *msg, size_t msg_len)
Parses and interprets a CoAP datagram with context ctx.
int coap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, coap_bin_const_t *data, coap_bin_const_t **hmac)
Create a HMAC hash of the provided data.
int coap_crypto_aead_decrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Decrypt the provided encrypted data into plaintext.
int coap_crypto_aead_encrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Encrypt the provided plaintext data.
int coap_crypto_hash(cose_alg_t alg, const coap_bin_const_t *data, coap_bin_const_t **hash)
Create a hash of the provided data.
int coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg)
Check whether the defined hkdf algorithm is supported by the underlying crypto library.
int coap_crypto_check_cipher_alg(cose_alg_t alg)
Check whether the defined cipher algorithm is supported by the underlying crypto library.
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.
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
coap_pki_define_t
The enum to define the format of the key parameter definition.
#define COAP_DTLS_MAX_PSK_IDENTITY
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_PKCS11
The PKI key type is PKCS11 (DER).
@ COAP_PKI_KEY_DEFINE
The individual PKI key types are Definable.
@ COAP_TLS_LIBRARY_OPENHITLS
Using openHiTLS library.
@ COAP_EVENT_DTLS_CLOSED
Triggerred when (D)TLS session closed.
@ COAP_EVENT_DTLS_CONNECTED
Triggered when (D)TLS session connected.
@ 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(...)
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
#define COSE_ALGORITHM_HMAC384_384_HASH_LEN
#define COSE_ALGORITHM_HMAC512_512_HASH_LEN
int cose_get_hmac_alg_for_hkdf(cose_hkdf_alg_t hkdf_alg, cose_hmac_alg_t *hmac_alg)
#define COSE_ALGORITHM_HMAC256_256_HASH_LEN
@ 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
coap_proto_t
CoAP protocol types Note: coap_layers_coap[] needs updating if extended.
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.
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_address_t remote
remote address and port
coap_address_t local
local address and port
socklen_t size
size of addr
union coap_address_t::@250171263277076317333044054015357360100234370325 addr
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.
union coap_crypto_param_t::@157113072004166322362146125210066265265052014356 params
coap_crypto_aes_ccm_t aes
Used if AES type encryption.
cose_alg_t alg
The COSE algorith to use.
The structure that holds the Client PSK information.
coap_bin_const_t identity
The structure used for defining the Client PSK setup data to be used.
void * ih_call_back_arg
Passed in to the Identity Hint callback function.
char * client_sni
If not NULL, SNI to use in client TLS setup.
coap_dtls_ih_callback_t validate_ih_call_back
Identity Hint check callback function.
The structure that holds the PKI key information.
coap_pki_key_define_t define
for definable type keys
union coap_dtls_key_t::@347061073371360224072225335172343174030036152126 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.
void * sni_call_back_arg
Passed in to the SNI callback function.
coap_layer_establish_t l_establish
The structure that holds the PKI Definable key type definitions.
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_addr_tuple_t addr_info
remote/local address info
coap_proto_t proto
protocol used
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
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