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(HITLS_X509_Cert *cert) {
809 HITLS_X509_ExtSan san = {0};
810 char *dns_name =
NULL;
812 if (HITLS_X509_CertCtrl(cert, HITLS_X509_EXT_GET_SAN, &san,
813 sizeof(san)) == HITLS_PKI_SUCCESS &&
815 for (BslListNode *name_node = BSL_LIST_FirstNode(san.names);
817 name_node = BSL_LIST_GetNextNode(san.names, name_node)) {
818 const HITLS_X509_GeneralName *name =
819 (
const HITLS_X509_GeneralName *)BSL_LIST_GetData(name_node);
821 if (!name || name->type != HITLS_X509_GN_DNS)
823 if (name->value.dataLen &&
824 memchr(name->value.data,
'\000', name->value.dataLen))
826 dns_name = coap_hitls_copy_name(name->value.data, name->value.dataLen);
831 HITLS_X509_ClearSubjectAltName(&san);
836coap_hitls_get_cn_from_cert(HITLS_X509_Cert *cert) {
838 char *cn_name =
NULL;
840 if (HITLS_X509_CertCtrl(cert, HITLS_X509_GET_SUBJECT_CN_STR,
841 &cn,
sizeof(cn)) == HITLS_PKI_SUCCESS) {
842 cn_name = coap_hitls_copy_name(cn.data, cn.dataLen);
845 BSL_SAL_Free(cn.data);
850coap_hitls_get_san_or_cn_from_cert(HITLS_X509_Cert *cert) {
855 name = coap_hitls_get_san_from_cert(cert);
858 return coap_hitls_get_cn_from_cert(cert);
864 HITLS_X509_Cert *cert,
868 uint32_t der_len = 0;
872 (void)HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODELEN,
873 &der_len,
sizeof(der_len));
875 (void)HITLS_X509_CertCtrl(cert, HITLS_X509_GET_ENCODE,
877 san_or_cn = coap_hitls_get_san_or_cn_from_cert(cert);
882 san_or_cn ? san_or_cn :
"",
883 der, der_len, session, depth, validated,
888 san_or_cn && strcmp(san_or_cn, setup_data->
client_sni)) {
897coap_hitls_verify_cb(int32_t err_code, HITLS_CERT_StoreCtx *store_ctx) {
899 coap_hitls_context_t *context;
901 HITLS_X509_Cert *cert;
905 if (!coap_hitls_get_verify_session(store_ctx, &session) ||
910 setup_data = &context->setup_data;
911 if (err_code == HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND ||
912 err_code == HITLS_X509_ERR_ROOT_CERT_NOT_FOUND) {
913 allowed = coap_hitls_verify_cb_self_signed_allowed(setup_data,
916 allowed = coap_hitls_verify_error_allowed(setup_data, err_code);
919 coap_log_warn(
"* %s: certificate verification failed: %s (0x%x)\n",
921 coap_hitls_verify_err_str(err_code), (
unsigned int)err_code);
926 coap_hitls_get_verify_cert(store_ctx, &cert, &depth)) {
927 if (!coap_hitls_validate_cn_cert(session, setup_data, cert,
928 depth < 0 ? 0 : (
unsigned)depth,
929 err_code == HITLS_PKI_SUCCESS)) {
932 coap_hitls_verify_err_str(HITLS_X509_ERR_VFY_HOSTNAME_FAIL));
933 return HITLS_X509_ERR_VFY_HOSTNAME_FAIL;
937 return HITLS_PKI_SUCCESS;
941coap_hitls_app_verify_cb(HITLS_CERT_StoreCtx *store_ctx,
944 coap_hitls_context_t *context;
946 HITLS_X509_List *peer_chain =
NULL;
947 HITLS_X509_Cert *leaf_cert =
NULL;
950 if (!coap_hitls_get_verify_session(store_ctx, &session) ||
952 return HITLS_X509_ERR_INVALID_PARAM;
954 if (HITLS_X509_StoreCtxCtrl((HITLS_X509_StoreCtx *)store_ctx,
955 HITLS_X509_STORECTX_GET_PEER_CERT_CHAIN,
957 sizeof(peer_chain)) != HITLS_PKI_SUCCESS ||
959 return HITLS_X509_ERR_INVALID_PARAM;
961 ret = HITLS_X509_CertVerify((HITLS_X509_StoreCtx *)store_ctx, peer_chain);
962 if (ret == HITLS_PKI_SUCCESS)
963 return HITLS_APP_VERIFY_CALLBACK_SUCCESS;
966 setup_data = &context->setup_data;
967 if ((ret == HITLS_X509_ERR_ISSUE_CERT_NOT_FOUND ||
968 ret == HITLS_X509_ERR_ROOT_CERT_NOT_FOUND) &&
969 coap_hitls_self_signed_leaf_allowed(setup_data, store_ctx,
972 int32_t time_ret = coap_hitls_cert_time_valid(leaf_cert);
974 if (time_ret != HITLS_PKI_SUCCESS) {
977 coap_hitls_verify_err_str(time_ret));
981 coap_log_info(
" %s: %s: overridden: 'self-signed' depth=0\n",
983 coap_hitls_verify_err_str(ret));
984 if (!coap_hitls_validate_cn_cert(session, setup_data, leaf_cert, 0, 0))
985 return HITLS_X509_ERR_VFY_HOSTNAME_FAIL;
986 return HITLS_APP_VERIFY_CALLBACK_SUCCESS;
993coap_hitls_is_retry(int32_t ret) {
995 case HITLS_WANT_CONNECT:
996 case HITLS_WANT_ACCEPT:
997 case HITLS_WANT_READ:
998 case HITLS_WANT_WRITE:
999 case HITLS_WANT_BACKUP:
1000 case HITLS_WANT_CLIENT_HELLO_CB:
1001 case HITLS_WANT_X509_LOOKUP:
1002 case HITLS_REC_NORMAL_IO_BUSY:
1003 case HITLS_REC_NORMAL_RECV_BUF_EMPTY:
1011coap_hitls_is_closed(int32_t ret) {
1012 return ret == HITLS_CM_LINK_CLOSED;
1016coap_hitls_udp_overhead(
const coap_hitls_env_t *env) {
1017#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI) && !defined(RIOT_VERSION)
1018 if (env && env->session) {
1019 switch (env->session->addr_info.remote.addr.sa.sa_family) {
1022 return COAP_HITLS_IPV6_UDP_OVERHEAD;
1034 return COAP_HITLS_IPV4_UDP_OVERHEAD;
1038coap_hitls_set_connected(
coap_session_t *session, coap_hitls_env_t *env) {
1039 if (env->established)
1042 env->established = 1;
1052 coap_hitls_env_t *env) {
1055 if (HITLS_IsHandShakeDone(env->ctx, &done) == HITLS_SUCCESS && done) {
1056 coap_hitls_set_connected(session, env);
1063coap_hitls_handshake(
coap_session_t *session, coap_hitls_env_t *env) {
1066 BSL_ERR_ClearError();
1068 ret = HITLS_Connect(env->ctx);
1070 ret = HITLS_Accept(env->ctx);
1072 if (ret == HITLS_SUCCESS)
1073 return coap_hitls_check_handshake_done(session, env);
1074 if (coap_hitls_check_handshake_done(session, env))
1076 if (coap_hitls_is_retry(ret))
1079 coap_log_warn(
"coap_hitls_handshake: returned 0x%x\n", (
unsigned int)ret);
1080 coap_hitls_log_fatal_err_stack(session);
1086coap_hitls_uio_write(BSL_UIO *uio,
const void *buf, uint32_t len,
1087 uint32_t *write_len) {
1088 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1093 if (!env || !env->session || !buf || !write_len)
1094 return BSL_NULL_INPUT;
1097 && env->session->endpoint ==
NULL
1101 return BSL_UIO_IO_EXCEPTION;
1104 (void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
1105 ret = env->session->sock.lfunc[
COAP_LAYER_TLS].l_write(env->session,
1106 (
const uint8_t *)buf, len);
1109 if (errno == EMSGSIZE) {
1110 env->mtu_exceeded = 1;
1111 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY);
1115 if (errno == ENOTCONN || errno == ECONNREFUSED)
1117 return BSL_UIO_IO_EXCEPTION;
1120 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_WRITE | BSL_UIO_FLAGS_SHOULD_RETRY);
1123 *write_len = (uint32_t)ret;
1128coap_hitls_uio_read(BSL_UIO *uio,
void *buf, uint32_t len,
1129 uint32_t *read_len) {
1130 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1135 if (!env || !buf || !read_len)
1136 return BSL_NULL_INPUT;
1140 (void)BSL_UIO_ClearFlags(uio, BSL_UIO_FLAGS_RWS | BSL_UIO_FLAGS_SHOULD_RETRY);
1141 ret = env->session->sock.lfunc[
COAP_LAYER_TLS].l_read(env->session,
1142 (uint8_t *)buf, len);
1144 return errno == ECONNRESET ? BSL_UIO_IO_EOF : BSL_UIO_IO_EXCEPTION;
1146 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_SHOULD_RETRY);
1149 *read_len = (uint32_t)ret;
1152 if (!env->pdu || env->pdu_len == 0) {
1153 (void)BSL_UIO_SetFlags(uio, BSL_UIO_FLAGS_READ | BSL_UIO_FLAGS_SHOULD_RETRY);
1157 copy_len = env->pdu_len < len ? env->pdu_len : len;
1158 memcpy(buf, env->pdu, copy_len);
1159 env->pdu += copy_len;
1160 env->pdu_len -= copy_len;
1161 *read_len = (uint32_t)copy_len;
1166coap_hitls_uio_ctrl(BSL_UIO *uio, int32_t cmd, int32_t larg,
void *parg) {
1167 coap_hitls_env_t *env = (coap_hitls_env_t *)BSL_UIO_GetUserData(uio);
1170 return BSL_NULL_INPUT;
1173 case BSL_UIO_GET_FD:
1176 *(int32_t *)parg = -1;
1177#elif COAP_SERVER_SUPPORT
1180 env->session->endpoint->sock.fd :
1181 env->session->sock.fd :
1182 env->session->sock.fd);
1184 *(int32_t *)parg = (int32_t)env->session->sock.fd;
1188 case BSL_UIO_SET_FD:
1189 case BSL_UIO_SET_PEER_IP_ADDR:
1190 case BSL_UIO_UDP_SET_CONNECTED:
1194 case BSL_UIO_GET_PEER_IP_ADDR:
1195 if (!parg || !env->session)
1196 return BSL_NULL_INPUT;
1197 if (larg == (int32_t)
sizeof(BSL_UIO_CtrlGetPeerIpAddrParam)) {
1198 BSL_UIO_CtrlGetPeerIpAddrParam *param =
1199 (BSL_UIO_CtrlGetPeerIpAddrParam *)parg;
1200 uint32_t addr_len = (uint32_t)env->session->addr_info.remote.size;
1202 if (!param->addr || param->size < addr_len)
1203 return BSL_INVALID_ARG;
1204 memcpy(param->addr, &env->session->addr_info.remote.addr.sa, addr_len);
1205 param->size = addr_len;
1208 if (env->session->addr_info.remote.size > (socklen_t)larg)
1209 return BSL_INVALID_ARG;
1210 memcpy(parg, &env->session->addr_info.remote.addr.sa,
1211 env->session->addr_info.remote.size);
1213 case BSL_UIO_PENDING:
1214 case BSL_UIO_WPENDING:
1216 *(uint64_t *)parg = cmd == BSL_UIO_PENDING ? env->pdu_len : 0;
1218 case BSL_UIO_UDP_GET_MTU_OVERHEAD:
1220 return BSL_NULL_INPUT;
1221 if (larg != (int32_t)
sizeof(uint8_t))
1222 return BSL_INVALID_ARG;
1223 *(uint8_t *)parg = coap_hitls_udp_overhead(env);
1225 case BSL_UIO_UDP_QUERY_MTU:
1227 return BSL_NULL_INPUT;
1228 if (larg != (int32_t)
sizeof(uint32_t))
1229 return BSL_INVALID_ARG;
1230 *(uint32_t *)parg = env->session->mtu > UINT32_MAX ?
1231 UINT32_MAX : (uint32_t)env->session->mtu;
1233 case BSL_UIO_UDP_MTU_EXCEEDED:
1235 return BSL_NULL_INPUT;
1236 if (larg != (int32_t)
sizeof(
bool))
1237 return BSL_INVALID_ARG;
1238 *(
bool *)parg = env->mtu_exceeded != 0;
1239 env->mtu_exceeded = 0;
1247coap_hitls_setup_uio(coap_hitls_env_t *env) {
1249 BSL_UIO_TransportType type =
1252 env->method = BSL_UIO_NewMethod();
1255#if defined(__GNUC__)
1256#pragma GCC diagnostic push
1257#pragma GCC diagnostic ignored "-Wpedantic"
1259 if (BSL_UIO_SetMethodType(env->method, type) != BSL_SUCCESS ||
1260 BSL_UIO_SetMethod(env->method, BSL_UIO_WRITE_CB,
1261 (
void *)coap_hitls_uio_write) != BSL_SUCCESS ||
1262 BSL_UIO_SetMethod(env->method, BSL_UIO_READ_CB,
1263 (
void *)coap_hitls_uio_read) != BSL_SUCCESS ||
1264 BSL_UIO_SetMethod(env->method, BSL_UIO_CTRL_CB,
1265 (
void *)coap_hitls_uio_ctrl) != BSL_SUCCESS) {
1266 BSL_UIO_FreeMethod(env->method);
1270#if defined(__GNUC__)
1271#pragma GCC diagnostic pop
1274 uio = BSL_UIO_New(env->method);
1277 if (BSL_UIO_SetUserData(uio, env) != BSL_SUCCESS) {
1281 BSL_UIO_SetInit(uio,
true);
1282 if (HITLS_SetUio(env->ctx, uio) != HITLS_SUCCESS) {
1283 BSL_UIO_SetUserData(uio,
NULL);
1287 env->uio = HITLS_GetUio(env->ctx);
1293coap_hitls_update_mtu(coap_hitls_env_t *env) {
1297 if (!env || !env->ctx || !env->session || env->proto !=
COAP_PROTO_DTLS)
1300 mtu = env->session->mtu > UINT16_MAX ? UINT16_MAX :
1301 (uint16_t)env->session->mtu;
1302 ret = HITLS_SetMtu(env->ctx, mtu);
1303 if (ret != HITLS_SUCCESS) {
1309#if COAP_CLIENT_SUPPORT
1311coap_hitls_psk_client_cb(HITLS_Ctx *ctx,
const uint8_t *hint,
1312 uint8_t *identity, uint32_t max_identity_len,
1313 uint8_t *psk, uint32_t max_psk_len) {
1320 if (!session || !session->
context)
1328 temp.
s = hint ? hint : (
const uint8_t *)
"";
1342 psk_identity = &cpsk_info->
identity;
1343 psk_key = &cpsk_info->
key;
1349 if (coap_hitls_copy_bin(identity, max_identity_len, psk_identity, 1) == 0 ||
1350 coap_hitls_copy_bin(psk, max_psk_len, psk_key, 0) == 0)
1352 return (uint32_t)psk_key->
length;
1356#if COAP_SERVER_SUPPORT
1361coap_hitls_sni_cb(HITLS_Ctx *ctx,
int *alert
COAP_UNUSED,
1364 coap_hitls_context_t *context =
1372 if (!session || !session->
context)
1373 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1374 sni = HITLS_GetServerName(ctx, HITLS_SNI_HOSTNAME_TYPE);
1380 HITLS_Config *new_config;
1386 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1387 new_config = coap_hitls_new_server_sni_config(session, session->
proto,
1390 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1391 if (!HITLS_SetNewConfig(ctx, new_config)) {
1392 HITLS_CFG_FreeConfig(new_config);
1393 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1395 HITLS_CFG_FreeConfig(new_config);
1399 psk_setup_data = &session->
context->spsk_setup_data;
1407 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1410 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1413 HITLS_SetPskIdentityHint(ctx, new_entry->
hint.
s,
1414 (uint32_t)new_entry->
hint.
length) != HITLS_SUCCESS)
1415 return HITLS_ACCEPT_SNI_ERR_ALERT_FATAL;
1419 return accepted ? HITLS_ACCEPT_SNI_ERR_OK : HITLS_ACCEPT_SNI_ERR_NOACK;
1423coap_hitls_psk_server_cb(HITLS_Ctx *ctx,
const uint8_t *identity,
1424 uint8_t *psk, uint32_t max_psk_len) {
1430 if (!session || !session->
context)
1433 setup_data = &session->
context->spsk_setup_data;
1434 lidentity.
s = identity ? identity : (
const uint8_t *)
"";
1435 lidentity.
length = coap_hitls_strnlen(lidentity.
s,
1449 if (coap_hitls_copy_bin(psk, max_psk_len, psk_key, 0) == 0)
1451 return (uint32_t)psk_key->
length;
1456coap_hitls_alpn_select_cb(HITLS_Ctx *ctx
COAP_UNUSED,
1457 uint8_t **selected_proto,
1458 uint8_t *selected_proto_len,
1459 uint8_t *client_alpn_list,
1460 uint32_t client_alpn_list_size,
1462 if (HITLS_SelectAlpnProtocol(selected_proto, selected_proto_len,
1463 coap_hitls_alpn,
sizeof(coap_hitls_alpn),
1465 client_alpn_list_size) != HITLS_SUCCESS ||
1466 !selected_proto || !*selected_proto ||
1467 !selected_proto_len || *selected_proto_len != 4)
1468 return HITLS_ALPN_ERR_ALERT_FATAL;
1469 return HITLS_ALPN_ERR_OK;
1480 switch (define->
ca_def) {
1484 if (HITLS_CFG_LoadVerifyFile(config, define->
ca.
s_byte) == HITLS_SUCCESS)
1492 TLS_PARSE_FORMAT_PEM, &len))
1495 if (HITLS_CFG_LoadVerifyBuffer(config, define->
ca.
u_byte, len,
1496 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1504 TLS_PARSE_FORMAT_ASN1, &len))
1507 if (HITLS_CFG_LoadVerifyBuffer(config, define->
ca.
u_byte, len,
1508 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1515 buf = coap_hitls_read_file(define->
ca.
s_byte, &len);
1519 ret = HITLS_CFG_LoadVerifyBuffer(config, buf, len, TLS_PARSE_FORMAT_ASN1);
1521 if (ret == HITLS_SUCCESS)
1540coap_hitls_load_public_cert(HITLS_Config *config,
coap_dtls_key_t *key,
1550 if (HITLS_CFG_UseCertificateChainFile(config,
1559 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1573 len, TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1586 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1605coap_hitls_load_private_key(HITLS_Config *config,
coap_dtls_key_t *key,
1615 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1623 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1636 TLS_PARSE_FORMAT_PEM) == HITLS_SUCCESS)
1649 TLS_PARSE_FORMAT_ASN1) == HITLS_SUCCESS)
1668coap_hitls_load_root_cas(HITLS_Config *config, coap_hitls_context_t *context) {
1669 if (context->root_ca_file &&
1670 HITLS_CFG_LoadVerifyFile(config, context->root_ca_file) != HITLS_SUCCESS) {
1672 context->root_ca_file);
1675 if (context->root_ca_dir &&
1676 HITLS_CFG_LoadVerifyDir(config, context->root_ca_dir) != HITLS_SUCCESS) {
1678 context->root_ca_dir);
1681 if (context->trust_store_defined &&
1682 HITLS_CFG_LoadDefaultCAPath(config) != HITLS_SUCCESS) {
1690coap_hitls_configure_pki(HITLS_Config *config,
coap_session_t *session,
1693 coap_hitls_context_t *context =
1700 if (pki_setup_data) {
1701 setup_data_copy = *pki_setup_data;
1702 setup_data = &setup_data_copy;
1704 if (!context || !setup_data)
1706 if (!coap_hitls_check_pki_key_supported(setup_data, role))
1713 if (!coap_hitls_load_root_cas(config, context) ||
1714 !coap_hitls_load_ca(config, &key, role) ||
1715 !coap_hitls_load_public_cert(config, &key, role) ||
1716 !coap_hitls_load_private_key(config, &key, role))
1720 HITLS_CFG_SetVerifyDepth(config,
1721 COAP_HITLS_VERIFY_DEPTH_TO_MAX_CHAIN_DEPTH(
1726 HITLS_CFG_SetVerifyFlags(config,
1727 HITLS_X509_VFY_FLAG_CRL_ALL) != HITLS_SUCCESS)
1729 if (HITLS_CFG_SetVerifyCb(config, coap_hitls_verify_cb) != HITLS_SUCCESS)
1731 if (HITLS_CFG_SetCertVerifyCb(config, coap_hitls_app_verify_cb,
1732 NULL) != HITLS_SUCCESS)
1737 HITLS_CFG_SetServerName(config,
1739 (uint32_t)strlen(setup_data->
client_sni)) != HITLS_SUCCESS)
1742 if (HITLS_CFG_SetClientVerifySupport(config,
1746 HITLS_CFG_SetNoClientCertSupport(config,
false) != HITLS_SUCCESS)
1750 if (HITLS_CFG_SetVerifyNoneSupport(config,
1756#if COAP_SERVER_SUPPORT
1757static HITLS_Config *
1760 coap_hitls_context_t *context =
1763 const uint16_t *cipher_suites;
1764 uint32_t cipher_suites_count;
1765 int enabled = context && context->psk_pki_enabled ?
1766 context->psk_pki_enabled : IS_PKI;
1768 HITLS_Config *config;
1770 if (!context || !new_key)
1774 HITLS_CFG_NewTLS12Config();
1778 coap_hitls_get_cipher_suites(enabled, &cipher_suites, &cipher_suites_count);
1779 if (HITLS_CFG_SetCipherSuites(config, cipher_suites,
1780 cipher_suites_count) != HITLS_SUCCESS) {
1781 HITLS_CFG_FreeConfig(config);
1785 (HITLS_CFG_SetFlightTransmitSwitch(config,
true) != HITLS_SUCCESS ||
1786 HITLS_CFG_SetDtlsCookieExchangeSupport(config,
true) != HITLS_SUCCESS ||
1787 HITLS_CFG_SetCookieGenCb(config,
1788 coap_hitls_cookie_gen_cb) != HITLS_SUCCESS ||
1789 HITLS_CFG_SetCookieVerifyCb(config,
1790 coap_hitls_cookie_verify_cb) != HITLS_SUCCESS)) {
1791 HITLS_CFG_FreeConfig(config);
1795 HITLS_CFG_SetAlpnProtosSelectCb(config, coap_hitls_alpn_select_cb,
1796 NULL) != HITLS_SUCCESS) {
1797 HITLS_CFG_FreeConfig(config);
1800 if (enabled & IS_PSK) {
1803 if (hint && hint->
s && hint->
length <= UINT32_MAX &&
1804 HITLS_CFG_SetPskIdentityHint(config, hint->
s,
1805 (uint32_t)hint->
length) != HITLS_SUCCESS) {
1806 HITLS_CFG_FreeConfig(config);
1809 if (HITLS_CFG_SetPskServerCallback(config,
1810 coap_hitls_psk_server_cb) != HITLS_SUCCESS) {
1811 HITLS_CFG_FreeConfig(config);
1816 pki_setup_data = context->setup_data;
1817 pki_setup_data.
pki_key = *new_key;
1820 HITLS_CFG_FreeConfig(config);
1824 (void)HITLS_CFG_SetInfoCb(config, coap_hitls_info_cb);
1829static HITLS_Config *
1832 coap_hitls_context_t *hitls_context =
1835 const uint16_t *cipher_suites;
1836 uint32_t cipher_suites_count;
1837 int enabled = hitls_context && hitls_context->psk_pki_enabled ?
1838 hitls_context->psk_pki_enabled : IS_PSK;
1840 HITLS_CFG_NewDTLS12Config() :
1841 HITLS_CFG_NewTLS12Config();
1846 coap_hitls_get_cipher_suites(enabled, &cipher_suites, &cipher_suites_count);
1848 if (HITLS_CFG_SetCipherSuites(config, cipher_suites,
1849 cipher_suites_count) != HITLS_SUCCESS) {
1850 HITLS_CFG_FreeConfig(config);
1854 (HITLS_CFG_SetFlightTransmitSwitch(config,
true) != HITLS_SUCCESS ||
1855 HITLS_CFG_SetDtlsCookieExchangeSupport(config,
1857 HITLS_CFG_FreeConfig(config);
1860#if COAP_SERVER_SUPPORT
1862 (HITLS_CFG_SetCookieGenCb(config,
1863 coap_hitls_cookie_gen_cb) != HITLS_SUCCESS ||
1864 HITLS_CFG_SetCookieVerifyCb(config,
1865 coap_hitls_cookie_verify_cb) != HITLS_SUCCESS)) {
1866 HITLS_CFG_FreeConfig(config);
1872 HITLS_CFG_SetAlpnProtos(config, coap_hitls_alpn,
1873 sizeof(coap_hitls_alpn)) != HITLS_SUCCESS) ||
1875 HITLS_CFG_SetAlpnProtosSelectCb(config,
1876 coap_hitls_alpn_select_cb,
1877 NULL) != HITLS_SUCCESS))) {
1878 HITLS_CFG_FreeConfig(config);
1883#if COAP_CLIENT_SUPPORT
1887 HITLS_CFG_SetServerName(config,
1889 (uint32_t)strlen(setup_data->
client_sni)) != HITLS_SUCCESS) {
1890 HITLS_CFG_FreeConfig(config);
1893 if (HITLS_CFG_SetPskClientCallback(config,
1894 coap_hitls_psk_client_cb) != HITLS_SUCCESS) {
1895 HITLS_CFG_FreeConfig(config);
1900 HITLS_CFG_FreeConfig(config);
1904#if COAP_SERVER_SUPPORT
1907 if (hint && hint->
s && hint->
length <= UINT32_MAX &&
1908 HITLS_CFG_SetPskIdentityHint(config, hint->
s,
1909 (uint32_t)hint->
length) != HITLS_SUCCESS) {
1910 HITLS_CFG_FreeConfig(config);
1913 if (HITLS_CFG_SetPskServerCallback(config,
1914 coap_hitls_psk_server_cb) != HITLS_SUCCESS) {
1915 HITLS_CFG_FreeConfig(config);
1920 HITLS_CFG_FreeConfig(config);
1925#if COAP_SERVER_SUPPORT
1929 if ((enabled & IS_PSK) && session && session->
context &&
1930 session->
context->spsk_setup_data.validate_sni_call_back)
1932 if ((enabled & IS_PKI) && hitls_context &&
1933 hitls_context->setup_data.validate_sni_call_back)
1936 (HITLS_CFG_SetServerNameCb(config,
1937 coap_hitls_sni_cb) != HITLS_SUCCESS ||
1938 HITLS_CFG_SetServerNameArg(config,
NULL) != HITLS_SUCCESS)) {
1939 HITLS_CFG_FreeConfig(config);
1945 if ((enabled & IS_PKI) &&
1946 !coap_hitls_configure_pki(config, session, role,
NULL)) {
1947 HITLS_CFG_FreeConfig(config);
1951 (void)HITLS_CFG_SetInfoCb(config, coap_hitls_info_cb);
1956coap_hitls_free_env(coap_hitls_env_t *env) {
1960 if (env->established && !env->had_fatal)
1961 (void)HITLS_Close(env->ctx);
1963 BSL_UIO_SetUserData(env->uio,
NULL);
1964 HITLS_Free(env->ctx);
1965 }
else if (env->uio) {
1966 BSL_UIO_SetUserData(env->uio,
NULL);
1969 BSL_UIO_FreeMethod(env->method);
1973static coap_hitls_env_t *
1974coap_hitls_live_env(
coap_session_t *session, coap_hitls_env_t *env) {
1975 return session && session->
tls == (
void *)env ? env :
NULL;
1979coap_hitls_clear_pdu(coap_hitls_env_t *env) {
1986static coap_hitls_env_t *
1989 coap_hitls_env_t *env =
1991 coap_hitls_context_t *hitls_context =
1994 HITLS_Config *config;
1998 memset(env, 0,
sizeof(*env));
1999 env->session = session;
2003 config = coap_hitls_new_config(session, role, proto);
2009 env->ctx = HITLS_New(config);
2010 HITLS_CFG_FreeConfig(config);
2015 if (HITLS_SetUserData(env->ctx, session) != HITLS_SUCCESS ||
2016 !coap_hitls_setup_uio(env)) {
2017 coap_hitls_free_env(env);
2020 coap_hitls_update_mtu(env);
2021 if (hitls_context && (hitls_context->psk_pki_enabled & IS_PKI) &&
2022 hitls_context->setup_data.additional_tls_setup_call_back &&
2023 !hitls_context->setup_data.additional_tls_setup_call_back(env->ctx,
2024 &hitls_context->setup_data)) {
2025 coap_hitls_free_env(env);
2039#if !COAP_DISABLE_TCP
2071#if COAP_CLIENT_SUPPORT
2094 version.
version = HITLS_VersionNum();
2102 (void)coap_hitls_startup();
2107 if (coap_hitls_started) {
2108#if COAP_WITH_LIBOPENHITLS
2109 HITLS_CertMethodDeinit();
2111 CRYPT_EAL_Cleanup(CRYPT_EAL_INIT_ALL);
2112 coap_hitls_started = 0;
2119 BSL_ERR_RemoveErrorStack(
false);
2122#if COAP_WITH_LIBOPENHITLS
2125 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2129 return env ? env->ctx :
NULL;
2134 coap_hitls_context_t *context =
2139 memset(context, 0,
sizeof(*context));
2140 context->coap_context = coap_context;
2142 sizeof(context->cookie_secret))) {
2146 context->cookie_secret_set = 1;
2152 coap_hitls_context_t *context = (coap_hitls_context_t *)dtls_context;
2155 if (context->root_ca_file)
2157 if (context->root_ca_dir)
2159 memset(context->cookie_secret, 0,
sizeof(context->cookie_secret));
2160 context->cookie_secret_set = 0;
2165#if COAP_SERVER_SUPPORT
2169 coap_hitls_context_t *context;
2171 if (!coap_context || !setup_data)
2173 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2176 context->psk_pki_enabled |= IS_PSK;
2181#if COAP_CLIENT_SUPPORT
2185 coap_hitls_context_t *context;
2187 if (!coap_context || !setup_data)
2189 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2192 context->psk_pki_enabled |= IS_PSK;
2201 coap_hitls_context_t *context;
2203 if (!coap_context || !setup_data)
2205 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2208 if (!coap_hitls_check_pki_key_supported(setup_data, role))
2210 context->setup_data = *setup_data;
2211 if (!context->setup_data.verify_peer_cert) {
2213 context->setup_data.check_common_ca = 0;
2215 context->setup_data.allow_self_signed = 1;
2216 context->setup_data.allow_expired_certs = 1;
2217 context->setup_data.cert_chain_validation = 1;
2218 context->setup_data.cert_chain_verify_depth = 10;
2219 context->setup_data.check_cert_revocation = 1;
2220 context->setup_data.allow_no_crl = 1;
2221 context->setup_data.allow_expired_crl = 1;
2222 context->setup_data.allow_bad_md_hash = 1;
2223 context->setup_data.allow_short_rsa_length = 1;
2225#if COAP_CLIENT_SUPPORT
2227 context->psk_pki_enabled &= ~IS_PSK;
2231 context->psk_pki_enabled |= IS_PKI;
2233 coap_log_warn(
"openHiTLS backend has no Connection-ID support\n");
2239 const char *ca_file,
2240 const char *ca_dir) {
2241 coap_hitls_context_t *context;
2242 char *new_ca_file =
NULL;
2243 char *new_ca_dir =
NULL;
2245 if (!coap_context || (!ca_file && !ca_dir))
2247 context = (coap_hitls_context_t *)coap_context->
dtls_context;
2251 new_ca_file = coap_hitls_strdup(ca_file);
2256 new_ca_dir = coap_hitls_strdup(ca_dir);
2263 if (context->root_ca_file)
2265 if (context->root_ca_dir)
2267 context->root_ca_file = new_ca_file;
2268 context->root_ca_dir = new_ca_dir;
2274 coap_hitls_context_t *context =
2279 context->trust_store_defined = 1;
2285 coap_hitls_context_t *context =
2288 return context && context->psk_pki_enabled;
2292#if COAP_SERVER_SUPPORT
2294coap_digest_setup(
void) {
2295 CRYPT_EAL_MdCtx *digest_ctx;
2297 if (!coap_hitls_startup())
2299 digest_ctx = CRYPT_EAL_MdNewCtx(CRYPT_MD_SHA256);
2302 if (CRYPT_EAL_MdInit(digest_ctx) != CRYPT_SUCCESS) {
2303 CRYPT_EAL_MdFreeCtx(digest_ctx);
2310coap_digest_free(coap_digest_ctx_t *digest_ctx) {
2312 CRYPT_EAL_MdFreeCtx((CRYPT_EAL_MdCtx *)digest_ctx);
2316coap_digest_update(coap_digest_ctx_t *digest_ctx,
2317 const uint8_t *data,
2319 CRYPT_EAL_MdCtx *ctx = (CRYPT_EAL_MdCtx *)digest_ctx;
2321 if (!ctx || (!data && data_len))
2324 uint32_t chunk = data_len > UINT32_MAX ? UINT32_MAX : (uint32_t)data_len;
2326 if (CRYPT_EAL_MdUpdate(ctx, data, chunk) != CRYPT_SUCCESS)
2335coap_digest_final(coap_digest_ctx_t *digest_ctx,
2336 coap_digest_t *digest_buffer) {
2337 CRYPT_EAL_MdCtx *ctx = (CRYPT_EAL_MdCtx *)digest_ctx;
2338 uint32_t len =
sizeof(*digest_buffer);
2341 if (!ctx || !digest_buffer)
2343 ret = CRYPT_EAL_MdFinal(ctx, (uint8_t *)digest_buffer, &len) == CRYPT_SUCCESS &&
2344 len ==
sizeof(*digest_buffer);
2345 coap_digest_free(digest_ctx);
2351static const struct {
2355} coap_hitls_hashs[] = {
2369 CRYPT_MD_AlgId md = CRYPT_MD_SHA1;
2370 uint32_t out_len = 0;
2372 if (!data || !hash || data->
length > UINT32_MAX || !coap_hitls_startup())
2374 for (i = 0; i <
sizeof(coap_hitls_hashs) /
sizeof(coap_hitls_hashs[0]); i++) {
2375 if (coap_hitls_hashs[i].alg == alg) {
2376 md = coap_hitls_hashs[i].md;
2377 out_len = coap_hitls_hashs[i].length;
2382 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
2386 len = CRYPT_EAL_MdGetDigestSize(md);
2391 if (CRYPT_EAL_Md(md, data->
s, (uint32_t)data->
length,
2392 digest->
s, &len) != CRYPT_SUCCESS ||
2397 if (out_len < digest->length)
2398 digest->
length = out_len;
2405#if COAP_OSCORE_SUPPORT
2413coap_hitls_get_cipher_alg(
cose_alg_t alg, CRYPT_CIPHER_AlgId *cipher_alg,
2418 *cipher_alg = CRYPT_CIPHER_AES128_CCM;
2424 *cipher_alg = CRYPT_CIPHER_AES256_CCM;
2429 coap_log_debug(
"coap_hitls_get_cipher_alg: COSE cipher %d not supported\n",
2436coap_hitls_get_hmac_alg(
cose_hmac_alg_t hmac_alg, CRYPT_MAC_AlgId *mac_alg,
2438 switch ((
int)hmac_alg) {
2441 *mac_alg = CRYPT_MAC_HMAC_SHA256;
2447 *mac_alg = CRYPT_MAC_HMAC_SHA384;
2453 *mac_alg = CRYPT_MAC_HMAC_SHA512;
2458 coap_log_debug(
"coap_hitls_get_hmac_alg: COSE HMAC %d not supported\n",
2466 return coap_hitls_get_cipher_alg(alg,
NULL,
NULL);
2475 return coap_hitls_get_hmac_alg(hmac_alg,
NULL,
NULL);
2482 if (ccm->
l == 0 || ccm->
l > 8)
2490coap_hitls_aead_set_common(CRYPT_EAL_CipherCtx *ctx,
2493 uint32_t tag_len = (uint32_t)ccm->
tag_len;
2494 uint32_t aad_len = 0;
2496 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAGLEN,
2497 &tag_len,
sizeof(tag_len)) != CRYPT_SUCCESS)
2499 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_MSGLEN,
2500 &msg_len,
sizeof(msg_len)) != CRYPT_SUCCESS)
2502 if (aad && aad->length) {
2503 if (aad->length > UINT32_MAX)
2505 aad_len = (uint32_t)aad->length;
2507 return CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_AAD,
2508 aad_len ? (
void *)(uintptr_t)aad->s :
NULL,
2509 aad_len) == CRYPT_SUCCESS;
2517 size_t *max_result_len) {
2518 CRYPT_CIPHER_AlgId cipher_alg;
2519 CRYPT_EAL_CipherCtx *ctx =
NULL;
2527 if (!params || !data || !result || !max_result_len)
2529 if (!coap_hitls_get_cipher_alg(params->
alg, &cipher_alg, &key_len))
2533 if (!coap_hitls_check_ccm_params(ccm, key_len) ||
2534 data->
length > UINT32_MAX ||
2535 ccm->
tag_len > *max_result_len ||
2537 !coap_hitls_startup())
2540 ctx = CRYPT_EAL_CipherNewCtx(cipher_alg);
2544 out_len = (uint32_t)data->
length;
2545 tag_len = (uint32_t)ccm->
tag_len;
2547 if (CRYPT_EAL_CipherInit(ctx, ccm->
key.
s, (uint32_t)ccm->
key.
length,
2548 ccm->
nonce, (uint32_t)(15 - ccm->
l),
2549 true) != CRYPT_SUCCESS)
2551 if (!coap_hitls_aead_set_common(ctx, ccm, aad, msg_len))
2553 if (CRYPT_EAL_CipherUpdate(ctx, data->
s, (uint32_t)data->
length,
2554 result, &out_len) != CRYPT_SUCCESS)
2556 if (out_len != data->
length)
2558 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_GET_TAG,
2559 result + out_len, tag_len) != CRYPT_SUCCESS)
2562 *max_result_len = (size_t)out_len + ccm->
tag_len;
2566 CRYPT_EAL_CipherFreeCtx(ctx);
2575 size_t *max_result_len) {
2576 CRYPT_CIPHER_AlgId cipher_alg;
2577 CRYPT_EAL_CipherCtx *ctx =
NULL;
2588 if (!params || !data || !result || !max_result_len)
2590 if (!coap_hitls_get_cipher_alg(params->
alg, &cipher_alg, &key_len))
2594 if (!coap_hitls_check_ccm_params(ccm, key_len) ||
2596 data->
length > UINT32_MAX ||
2597 !coap_hitls_startup())
2601 if (*max_result_len < cipher_len)
2604 ctx = CRYPT_EAL_CipherNewCtx(cipher_alg);
2608 tag = data->
s + cipher_len;
2609 out_len = (uint32_t)cipher_len;
2611 tag_len = (uint32_t)ccm->
tag_len;
2612 msg_len = cipher_len;
2613 if (CRYPT_EAL_CipherInit(ctx, ccm->
key.
s, (uint32_t)ccm->
key.
length,
2614 ccm->
nonce, (uint32_t)(15 - ccm->
l),
2615 false) != CRYPT_SUCCESS)
2617 if (!coap_hitls_aead_set_common(ctx, ccm, aad, msg_len))
2619 if (CRYPT_EAL_CipherCtrl(ctx, CRYPT_CTRL_SET_TAG,
2620 (
void *)(uintptr_t)tag, tag_len) != CRYPT_SUCCESS)
2622 if (CRYPT_EAL_CipherUpdate(ctx, data->
s, (uint32_t)cipher_len,
2623 result, &out_len) != CRYPT_SUCCESS)
2625 if (out_len != cipher_len)
2627 if (CRYPT_EAL_CipherFinal(ctx, result, &final_len) != CRYPT_SUCCESS)
2632 *max_result_len = out_len;
2636 CRYPT_EAL_CipherFreeCtx(ctx);
2645 CRYPT_MAC_AlgId mac_alg;
2646 CRYPT_EAL_MacCtx *ctx =
NULL;
2652 if (!key || !data || !hmac ||
2653 key->
length > UINT32_MAX || data->
length > UINT32_MAX ||
2654 !coap_hitls_get_hmac_alg(hmac_alg, &mac_alg, &mac_len) ||
2655 !coap_hitls_startup())
2662 ctx = CRYPT_EAL_MacNewCtx(mac_alg);
2666 out_len = (uint32_t)
dummy->length;
2667 if (CRYPT_EAL_MacInit(ctx, key->
s, (uint32_t)key->
length) != CRYPT_SUCCESS)
2669 if (CRYPT_EAL_MacUpdate(ctx, data->
s, (uint32_t)data->
length) != CRYPT_SUCCESS)
2671 if (CRYPT_EAL_MacFinal(ctx,
dummy->s, &out_len) != CRYPT_SUCCESS ||
2672 out_len !=
dummy->length)
2680 CRYPT_EAL_MacFreeCtx(ctx);
2687#if COAP_WITH_LIBOPENHITLS
2688#if COAP_CLIENT_SUPPORT
2691 coap_hitls_env_t *env =
2695 if (env && coap_hitls_handshake(session, env) < 0) {
2696 coap_hitls_free_env(env);
2704#if COAP_SERVER_SUPPORT
2707 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2711 if (coap_hitls_handshake(session, env) < 0) {
2712 coap_hitls_free_env(env);
2722 if (session && session->
context && session->
tls) {
2723 coap_hitls_free_env((coap_hitls_env_t *)session->
tls);
2732 coap_hitls_update_mtu((coap_hitls_env_t *)session->
tls);
2737 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2738 uint32_t written = 0;
2741 if (!env || data_len > UINT32_MAX)
2747 if (!env->established) {
2748 ret = coap_hitls_handshake(session, env);
2751 return ret == 0 ? 0 : -1;
2754 BSL_ERR_ClearError();
2755 ret = HITLS_Write(env->ctx, data, (uint32_t)data_len, &written);
2756 if (ret == HITLS_SUCCESS) {
2759 return (ssize_t)written;
2761 if (coap_hitls_is_retry(ret))
2764 session->
dtls_event = coap_hitls_is_closed(ret) ?
2767 coap_log_warn(
"coap_dtls_send: returned 0x%x\n", (
unsigned int)ret);
2768 coap_hitls_log_fatal_err_stack(session);
2786 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
2787 uint64_t timeout_us = 0;
2792 ret = HITLS_DtlsGetTimeout(env->ctx, &timeout_us);
2793 if (ret == HITLS_MSG_HANDLE_ERR_WITHOUT_TIMEOUT_ACTION)
2795 if (ret != HITLS_SUCCESS) {
2800 if (timeout_us == 0) {
2807 env->last_timeout = now;
2816 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2826 BSL_ERR_ClearError();
2827 ret = HITLS_DtlsProcessTimeout(env->ctx);
2828 if (ret == HITLS_SUCCESS ||
2829 ret == HITLS_MSG_HANDLE_DTLS_RETRANSMIT_NOT_TIMEOUT ||
2830 coap_hitls_is_retry(ret))
2835 coap_hitls_log_fatal_err_stack(session);
2843 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2854 env->pdu_len = data_len;
2856 if (env->established) {
2857#if COAP_CONSTRAINED_STACK
2862 uint32_t read_len = 0;
2865 BSL_ERR_ClearError();
2866 hret = HITLS_Read(env->ctx, pdu,
sizeof(pdu), &read_len);
2868 if (hret == HITLS_SUCCESS && read_len > 0) {
2874 if (hret == HITLS_SUCCESS || coap_hitls_is_retry(hret)) {
2878 session->
dtls_event = coap_hitls_is_closed(hret) ?
2882 (
unsigned int)hret, data_len);
2883 coap_hitls_log_fatal_err_stack(session);
2891 (void)coap_hitls_handshake(session, env);
2905 coap_hitls_clear_pdu(coap_hitls_live_env(session, env));
2909#if COAP_SERVER_SUPPORT
2913 coap_hitls_env_t *env = (coap_hitls_env_t *)session->
tls;
2915 int cookie_valid = 0;
2925 env->pdu_len = data_len;
2927 if (!env->hello_verify_sent) {
2928 BSL_ERR_ClearError();
2932 (
unsigned int)ret, env->pdu_len);
2934 coap_hitls_clear_pdu(env);
2936 if (ret == HITLS_SUCCESS)
2938 if (coap_hitls_is_retry(ret)) {
2940 ret = coap_hitls_handshake(session, env);
2943 env = coap_hitls_live_env(session, env);
2946 env->hello_verify_sent = 1;
2950 coap_log_warn(
"coap_dtls_hello: returned 0x%x\n", (
unsigned int)ret);
2951 coap_hitls_log_fatal_err_stack(session);
2956 cookie_valid = coap_hitls_client_hello_cookie_valid(session, data, data_len);
2957 ret = coap_hitls_handshake(session, env);
2958 env = coap_hitls_live_env(session, env);
2959 coap_hitls_clear_pdu(env);
2961 if (ret < 0 || !env)
2963 return cookie_valid == 1 ? 1 : 0;
2969 return COAP_HITLS_DTLS_OVERHEAD;
2972#if !COAP_DISABLE_TCP
2973#if COAP_CLIENT_SUPPORT
2976 coap_hitls_env_t *env =
2980 if (env && coap_hitls_handshake(session, env) < 0) {
2981 coap_hitls_free_env(env);
2989#if COAP_SERVER_SUPPORT
2992 coap_hitls_env_t *env =
2996 if (env && coap_hitls_handshake(session, env) < 0) {
2997 coap_hitls_free_env(env);
3012 uint8_t rwstate = HITLS_NOTHING;
3014 (void)HITLS_GetRwstate(ctx, &rwstate);
3015 if (rwstate == HITLS_WRITING) {
3017#ifdef COAP_EPOLL_SUPPORT
3031 const uint8_t *data,
3033 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
3034 uint32_t written = 0;
3037 if (!env || data_len > UINT32_MAX) {
3043 if (!env->established) {
3044 ret = coap_hitls_handshake(session, env);
3048 coap_hitls_tcp_want(session, env->ctx);
3052 BSL_ERR_ClearError();
3053 ret = HITLS_Write(env->ctx, data, (uint32_t)data_len, &written);
3054 if (ret == HITLS_SUCCESS) {
3056 if (written == data_len)
3063 return (ssize_t)written;
3065 if (coap_hitls_is_retry(ret)) {
3066 coap_hitls_tcp_want(session, env->ctx);
3070 session->
dtls_event = coap_hitls_is_closed(ret) ?
3073 coap_log_warn(
"coap_tls_write: returned 0x%x\n", (
unsigned int)ret);
3074 coap_hitls_log_fatal_err_stack(session);
3084 coap_hitls_env_t *env = session ? (coap_hitls_env_t *)session->
tls :
NULL;
3085 uint32_t read_len = 0;
3088 if (!env || data_len > UINT32_MAX) {
3094 if (!env->established) {
3095 ret = coap_hitls_handshake(session, env);
3099 coap_hitls_tcp_want(session, env->ctx);
3103 BSL_ERR_ClearError();
3104 ret = HITLS_Read(env->ctx, data, (uint32_t)data_len, &read_len);
3105 if (ret == HITLS_SUCCESS) {
3109 return (ssize_t)read_len;
3111 if (coap_hitls_is_retry(ret)) {
3112 coap_hitls_tcp_want(session, env->ctx);
3117 session->
dtls_event = coap_hitls_is_closed(ret) ?
3121 (
unsigned int)ret, data_len);
3122 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.
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
union coap_address_t::@241131003127110116114041001244025354034075356365 addr
socklen_t size
size of 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::@376202006114157036213053136012210003017006234156 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
coap_pki_key_t key_type
key format type
union coap_dtls_key_t::@003017313271040156213200302176016051164315363211 key
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