66#include <openssl/ssl.h>
67#include <openssl/engine.h>
68#include <openssl/err.h>
69#include <openssl/rand.h>
70#include <openssl/hmac.h>
71#include <openssl/x509v3.h>
73#ifdef COAP_EPOLL_SUPPORT
74# include <sys/epoll.h>
77#if OPENSSL_VERSION_NUMBER < 0x10100000L
78#error Must be compiled against OpenSSL 1.1.0 or later
82#define strcasecmp _stricmp
83#define strncasecmp _strnicmp
87#ifndef TLSEXT_TYPE_client_certificate_type
88#define TLSEXT_TYPE_client_certificate_type 19
90#ifndef TLSEXT_TYPE_server_certificate_type
91#define TLSEXT_TYPE_server_certificate_type 20
94#ifndef COAP_OPENSSL_CIPHERS
95#if OPENSSL_VERSION_NUMBER >= 0x10101000L
96#define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL"
98#define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL"
102#ifndef COAP_OPENSSL_PSK_CIPHERS
103#define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL"
107typedef struct coap_dtls_context_t {
110 HMAC_CTX *cookie_hmac;
113} coap_dtls_context_t;
115typedef struct coap_tls_context_t {
123typedef struct sni_entry {
125#if OPENSSL_VERSION_NUMBER < 0x10101000L
132typedef struct psk_sni_entry {
134#if OPENSSL_VERSION_NUMBER < 0x10101000L
140typedef struct coap_openssl_context_t {
141 coap_dtls_context_t dtls;
143 coap_tls_context_t tls;
148 sni_entry *sni_entry_list;
149 size_t psk_sni_count;
150 psk_sni_entry *psk_sni_entry_list;
151} coap_openssl_context_t;
153#if COAP_SERVER_SUPPORT
154#if OPENSSL_VERSION_NUMBER < 0x10101000L
155static int psk_tls_server_name_call_back(SSL *ssl,
int *sd,
void *arg);
157static int psk_tls_client_hello_call_back(SSL *ssl,
int *al,
void *arg);
162 if (SSLeay() < 0x10100000L) {
166#if OPENSSL_VERSION_NUMBER >= 0x10101000L
174 if (SSLeay() < 0x10101000L) {
184 if (SSLeay() < 0x10100000L) {
188#if OPENSSL_VERSION_NUMBER >= 0x10101000L
189 if (SSLeay() < 0x10101000L) {
209static ENGINE* ssl_engine = NULL;
212 SSL_load_error_strings();
214 ENGINE_load_dynamic();
220 ENGINE_finish(ssl_engine);
222 ENGINE_free(ssl_engine);
233 return c_session->
tls;
248typedef struct coap_ssl_st {
256static int coap_dgram_create(BIO *a) {
257 coap_ssl_data *data = NULL;
258 data = malloc(
sizeof(coap_ssl_data));
262 BIO_set_data(a, data);
263 memset(data, 0x00,
sizeof(coap_ssl_data));
267static int coap_dgram_destroy(BIO *a) {
271 data = (coap_ssl_data *)BIO_get_data(a);
277static int coap_dgram_read(BIO *a,
char *out,
int outl) {
279 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
282 if (data != NULL && data->pdu_len > 0) {
283 if (outl < (
int)data->pdu_len) {
284 memcpy(out, data->pdu, outl);
287 memcpy(out, data->pdu, data->pdu_len);
288 ret = (int)data->pdu_len;
290 if (!data->peekmode) {
297 BIO_clear_retry_flags(a);
299 BIO_set_retry_read(a);
304static int coap_dgram_write(BIO *a,
const char *in,
int inl) {
306 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
309#if COAP_SERVER_SUPPORT
310 if (data->session->sock.flags ==
COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
312 BIO_clear_retry_flags(a);
317 BIO_clear_retry_flags(a);
319 BIO_set_retry_write(a);
321 BIO_clear_retry_flags(a);
327static int coap_dgram_puts(BIO *a,
const char *pstr) {
328 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
331static long coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
333 coap_ssl_data *data = BIO_get_data(a);
338 case BIO_CTRL_GET_CLOSE:
339 ret = BIO_get_shutdown(a);
341 case BIO_CTRL_SET_CLOSE:
342 BIO_set_shutdown(a, (
int)num);
345 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
346 data->peekmode = (unsigned)num;
348 case BIO_CTRL_DGRAM_CONNECT:
351 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
352 case BIO_CTRL_DGRAM_GET_MTU:
353 case BIO_CTRL_DGRAM_SET_MTU:
354 case BIO_CTRL_DGRAM_QUERY_MTU:
355 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
360 case BIO_CTRL_DGRAM_MTU_DISCOVER:
361 case BIO_CTRL_DGRAM_SET_CONNECTED:
364 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
365 data->timeout =
coap_ticks_from_rt_us((uint64_t)((
struct timeval*)ptr)->tv_sec * 1000000 + ((
struct timeval*)ptr)->tv_usec);
369 case BIO_C_FILE_SEEK:
370 case BIO_C_FILE_TELL:
372 case BIO_CTRL_PENDING:
373 case BIO_CTRL_WPENDING:
374 case BIO_CTRL_DGRAM_GET_PEER:
375 case BIO_CTRL_DGRAM_SET_PEER:
376 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
377 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
378 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
379 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
380 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
381 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
382 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
383 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
392coap_dtls_generate_cookie(SSL *ssl,
393 unsigned char *cookie,
394 unsigned int *cookie_len) {
395 coap_dtls_context_t *dtls =
396 (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl));
397 coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
398 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
399 r &= HMAC_Update(dtls->cookie_hmac,
400 (
const uint8_t*)&data->session->addr_info.local.addr,
401 (
size_t)data->session->addr_info.local.size);
402 r &= HMAC_Update(dtls->cookie_hmac,
403 (
const uint8_t*)&data->session->addr_info.remote.addr,
404 (
size_t)data->session->addr_info.remote.size);
405 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
410coap_dtls_verify_cookie(SSL *ssl,
411 const uint8_t *cookie,
412 unsigned int cookie_len) {
415 if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
416 cookie_len == len && memcmp(cookie, hmac, len) == 0)
422#if COAP_CLIENT_SUPPORT
424coap_dtls_psk_client_callback(SSL *ssl,
427 unsigned int max_identity_len,
429 unsigned int max_psk_len) {
431 coap_openssl_context_t *o_context;
439 if (c_session == NULL)
442 if (o_context == NULL)
446 temp.
s = hint ? (
const uint8_t*)hint : (
const uint8_t*)
"";
447 temp.
length = strlen((
const char*)temp.
s);
451 (
const char *)temp.
s);
463 if (cpsk_info == NULL)
468 psk_identity = &cpsk_info->
identity;
469 psk_key = &cpsk_info->
key;
476 if (psk_identity == NULL || psk_key == NULL) {
482 if (!max_identity_len)
485 if (psk_identity->
length > max_identity_len) {
487 "psk_identity too large, truncated to %d bytes\n",
492 max_identity_len = (
unsigned int)psk_identity->
length;
494 memcpy(identity, psk_identity->
s, max_identity_len);
495 identity[max_identity_len] =
'\000';
497 if (psk_key->
length > max_psk_len) {
499 "psk_key too large, truncated to %d bytes\n",
504 max_psk_len = (
unsigned int)psk_key->
length;
506 memcpy(psk, psk_key->
s, max_psk_len);
511#if COAP_SERVER_SUPPORT
513coap_dtls_psk_server_callback(
515 const char *identity,
517 unsigned int max_psk_len
525 if (c_session == NULL)
531 lidentity.
s = identity ? (
const uint8_t*)identity : (
const uint8_t*)
"";
532 lidentity.
length = strlen((
const char*)lidentity.
s);
536 (
int)lidentity.
length, (
const char *)lidentity.
s);
552 if (psk_key->
length > max_psk_len) {
554 "psk_key too large, truncated to %d bytes\n",
559 max_psk_len = (
unsigned int)psk_key->
length;
561 memcpy(psk, psk_key->
s, max_psk_len);
566static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
569 int w = where &~SSL_ST_MASK;
571 if (w & SSL_ST_CONNECT)
572 pstr =
"SSL_connect";
573 else if (w & SSL_ST_ACCEPT)
578 if (where & SSL_CB_LOOP) {
582 }
else if (where & SSL_CB_ALERT) {
584 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
585 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
587 if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
591 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
594 SSL_alert_type_string_long(ret),
595 SSL_alert_desc_string_long(ret));
596 }
else if (where & SSL_CB_EXIT) {
602 while ((e = ERR_get_error()))
605 ERR_lib_error_string(e), ERR_func_error_string(e));
607 }
else if (ret < 0) {
609 int err = SSL_get_error(ssl, ret);
610 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE && err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT && err != SSL_ERROR_WANT_X509_LOOKUP) {
614 while ((e = ERR_get_error()))
617 ERR_lib_error_string(e), ERR_func_error_string(e));
623 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
628static int coap_sock_create(BIO *a) {
633static int coap_sock_destroy(BIO *a) {
638static int coap_sock_read(BIO *a,
char *out,
int outl) {
645 BIO_set_retry_read(a);
648 BIO_clear_retry_flags(a);
654static int coap_sock_write(BIO *a,
const char *in,
int inl) {
659 BIO_clear_retry_flags(a);
661 BIO_set_retry_read(a);
664 BIO_clear_retry_flags(a);
668 (errno == EPIPE || errno == ECONNRESET)) {
692static int coap_sock_puts(BIO *a,
const char *pstr) {
693 return coap_sock_write(a, pstr, (
int)strlen(pstr));
696static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
707 case BIO_CTRL_SET_CLOSE:
713 case BIO_CTRL_GET_CLOSE:
721static void coap_set_user_prefs(SSL_CTX *ctx) {
722 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
724#ifdef COAP_OPENSSL_SIGALGS
725 SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
726 SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
729#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS)
730 SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
735 coap_openssl_context_t *context;
738 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
740 uint8_t cookie_secret[32];
742 memset(context, 0,
sizeof(coap_openssl_context_t));
745 context->dtls.ctx = SSL_CTX_new(DTLS_method());
746 if (!context->dtls.ctx)
748 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
749 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
750 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
751 coap_set_user_prefs(context->dtls.ctx);
752 memset(cookie_secret, 0,
sizeof(cookie_secret));
753 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
756 "Insufficient entropy for random cookie generation");
757 coap_prng(cookie_secret,
sizeof(cookie_secret));
759 context->dtls.cookie_hmac = HMAC_CTX_new();
760 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
762 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
763 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
764 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
765 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
766 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
767 if (!context->dtls.meth)
769 context->dtls.bio_addr = BIO_ADDR_new();
770 if (!context->dtls.bio_addr)
772 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
773 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
774 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
775 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
776 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
777 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
781 context->tls.ctx = SSL_CTX_new(TLS_method());
782 if (!context->tls.ctx)
784 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
785 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
786 coap_set_user_prefs(context->tls.ctx);
787 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
788 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
789 if (!context->tls.meth)
791 BIO_meth_set_write(context->tls.meth, coap_sock_write);
792 BIO_meth_set_read(context->tls.meth, coap_sock_read);
793 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
794 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
795 BIO_meth_set_create(context->tls.meth, coap_sock_create);
796 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
807#if COAP_SERVER_SUPPORT
812 coap_openssl_context_t *o_context =
816 if (!setup_data || !o_context)
819 SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
820 coap_dtls_psk_server_callback);
822 SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
823 coap_dtls_psk_server_callback);
829 SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
831 SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
835#if OPENSSL_VERSION_NUMBER < 0x10101000L
836 SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
838 SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
839 psk_tls_server_name_call_back);
841 SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
843 SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
844 psk_tls_server_name_call_back);
847 SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
848 psk_tls_client_hello_call_back,
851 SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
852 psk_tls_client_hello_call_back,
858 if (!o_context->dtls.ssl) {
860 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
861 if (!o_context->dtls.ssl)
863 bio = BIO_new(o_context->dtls.meth);
865 SSL_free (o_context->dtls.ssl);
866 o_context->dtls.ssl = NULL;
869 SSL_set_bio(o_context->dtls.ssl, bio, bio);
870 SSL_set_app_data(o_context->dtls.ssl, NULL);
871 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
874 o_context->psk_pki_enabled |= IS_PSK;
879#if COAP_CLIENT_SUPPORT
884 coap_openssl_context_t *o_context =
888 if (!setup_data || !o_context)
891 if (!o_context->dtls.ssl) {
893 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
894 if (!o_context->dtls.ssl)
896 bio = BIO_new(o_context->dtls.meth);
898 SSL_free (o_context->dtls.ssl);
899 o_context->dtls.ssl = NULL;
902 SSL_set_bio(o_context->dtls.ssl, bio, bio);
903 SSL_set_app_data(o_context->dtls.ssl, NULL);
904 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
907 o_context->psk_pki_enabled |= IS_PSK;
913map_key_type(
int asn1_private_key_type
915 switch (asn1_private_key_type) {
933 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
934 asn1_private_key_type);
940static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
942#if COAP_SERVER_SUPPORT
945 const unsigned char **out,
946 unsigned char *outlen,
947 const unsigned char *in,
951 unsigned char *tout = NULL;
954 return SSL_TLSEXT_ERR_NOACK;
955 ret = SSL_select_next_proto(&tout,
962 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
968add_ca_to_cert_store(X509_STORE *st, X509 *x509)
973 while ((e = ERR_get_error()) != 0) {
976 if (!X509_STORE_add_cert(st, x509)) {
977 while ((e = ERR_get_error()) != 0) {
978 int r = ERR_GET_REASON(e);
979 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
982 ERR_reason_error_string(e),
983 ERR_lib_error_string(e),
984 ERR_func_error_string(e));
991missing_ENGINE_load_cert (
const char *cert_id)
998 params.cert_id = cert_id;
1002 if (!ENGINE_ctrl_cmd(ssl_engine,
"LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
1008#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT
1010setup_pki_server(SSL_CTX *ctx,
1017 if (!(SSL_CTX_use_certificate_file(ctx,
1019 SSL_FILETYPE_PEM))) {
1021 "*** setup_pki: (D)TLS: %s: Unable to configure "
1022 "Server Certificate\n",
1029 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1035 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1037 SSL_FILETYPE_PEM))) {
1039 "*** setup_pki: (D)TLS: %s: Unable to configure "
1040 "Server Private Key\n",
1047 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1053 STACK_OF(X509_NAME) *cert_names;
1057 char *rw_var = NULL;
1059 if (cert_names != NULL)
1060 SSL_CTX_set_client_CA_list(ctx, cert_names);
1063 "*** setup_pki: (D)TLS: %s: Unable to configure "
1070 st = SSL_CTX_get_cert_store(ctx);
1071 in = BIO_new(BIO_s_file());
1074 if (!BIO_read_filename(in, rw_var)) {
1081 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
1083 add_ca_to_cert_store(st, x);
1095 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1097 if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
1099 "*** setup_pki: (D)TLS: Unable to configure "
1100 "Server PEM Certificate\n");
1101 if (bp) BIO_free(bp);
1102 if (cert) X509_free(cert);
1105 if (bp) BIO_free(bp);
1106 if (cert) X509_free(cert);
1110 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1118 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1120 if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
1122 "*** setup_pki: (D)TLS: Unable to configure "
1123 "Server PEM Private Key\n");
1124 if (bp) BIO_free(bp);
1125 if (pkey) EVP_PKEY_free(pkey);
1128 if (bp) BIO_free(bp);
1129 if (pkey) EVP_PKEY_free(pkey);
1133 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1144 st = SSL_CTX_get_cert_store(ctx);
1147 if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
1149 add_ca_to_cert_store(st, x);
1150 SSL_CTX_add_client_CA(ctx, x);
1161 if (!(SSL_CTX_use_certificate_ASN1(ctx,
1165 "*** setup_pki: (D)TLS: %s: Unable to configure "
1166 "Server Certificate\n",
1173 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1180 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
1184 "*** setup_pki: (D)TLS: %s: Unable to configure "
1185 "Server Private Key\n",
1192 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1202 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1204 "*** setup_pki: (D)TLS: %s: Unable to configure "
1207 if (x509) X509_free(x509);
1210 st = SSL_CTX_get_cert_store(ctx);
1211 add_ca_to_cert_store(st, x509);
1218 ssl_engine = ENGINE_by_id(
"pkcs11");
1221 "*** setup_pki: (D)TLS: No PKCS11 support\nn");
1224 if (!ENGINE_init(ssl_engine)) {
1226 ENGINE_free(ssl_engine);
1229 "*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1236 if (ENGINE_ctrl_cmd_string(ssl_engine,
"PIN",
1239 "*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1248 "pkcs11:", 7) == 0) {
1249 EVP_PKEY* pkey = ENGINE_load_private_key(ssl_engine,
1255 "*** setup_pki: (D)TLS: %s: Unable to load "
1256 "Server Private Key\n",
1260 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1262 "*** setup_pki: (D)TLS: %s: Unable to configure "
1263 "Server Private Key\n",
1265 EVP_PKEY_free(pkey);
1268 EVP_PKEY_free(pkey);
1271 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1273 SSL_FILETYPE_ASN1))) {
1275 "*** setup_pki: (D)TLS: %s: Unable to configure "
1276 "Server Private Key\n",
1284 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1291 "pkcs11:", 7) == 0) {
1294 x509 = missing_ENGINE_load_cert(
1298 "*** setup_pki: (D)TLS: %s: Unable to load "
1299 "Server Certificate\n",
1303 if (!SSL_CTX_use_certificate(ctx, x509)) {
1305 "*** setup_pki: (D)TLS: %s: Unable to configure "
1306 "Server Certificate\n",
1314 if (!(SSL_CTX_use_certificate_file(ctx,
1316 SSL_FILETYPE_ASN1))) {
1318 "*** setup_pki: (D)TLS: %s: Unable to configure "
1319 "Server Certificate\n",
1327 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1338 x509 = missing_ENGINE_load_cert (
1342 "*** setup_pki: (D)TLS: %s: Unable to load "
1343 "Server CA Certificate\n",
1347 if (!SSL_CTX_add_client_CA(ctx, x509)) {
1349 "*** setup_pki: (D)TLS: %s: Unable to configure "
1355 st = SSL_CTX_get_cert_store(ctx);
1356 add_ca_to_cert_store(st, x509);
1361 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1363 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1365 "*** setup_pki: (D)TLS: %s: Unable to configure "
1368 if (x509) X509_free(x509);
1371 st = SSL_CTX_get_cert_store(ctx);
1372 add_ca_to_cert_store(st, x509);
1380 "*** setup_pki: (D)TLS: Unknown key type %d\n",
1389#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT
1391setup_pki_ssl(SSL *ssl,
1396 "RPK Support not available in OpenSSL\n");
1403 if (!(SSL_use_certificate_file(ssl,
1405 SSL_FILETYPE_PEM))) {
1407 "*** setup_pki: (D)TLS: %s: Unable to configure "
1418 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
1424 if (!(SSL_use_PrivateKey_file(ssl,
1426 SSL_FILETYPE_PEM))) {
1428 "*** setup_pki: (D)TLS: %s: Unable to configure "
1429 "Client Private Key\n",
1438 "*** setup_pki: (D)TLS: No %s Private Key defined\n",
1447 char *rw_var = NULL;
1448 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1451 STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(setup_data->
pki_key.
key.
pem.
ca_file);
1453 if (cert_names != NULL)
1454 SSL_set_client_CA_list(ssl, cert_names);
1457 "*** setup_pki: (D)TLS: %s: Unable to configure "
1466 in = BIO_new(BIO_s_file());
1469 if (!BIO_read_filename(in, rw_var)) {
1474 st = SSL_CTX_get_cert_store(ctx);
1476 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
1478 add_ca_to_cert_store(st, x);
1490 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1492 if (!cert || !SSL_use_certificate(ssl, cert)) {
1494 "*** setup_pki: (D)TLS: Unable to configure "
1495 "Server PEM Certificate\n");
1496 if (bp) BIO_free(bp);
1497 if (cert) X509_free(cert);
1500 if (bp) BIO_free(bp);
1501 if (cert) X509_free(cert);
1505 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1513 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1515 if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
1517 "*** setup_pki: (D)TLS: Unable to configure "
1518 "Server PEM Private Key\n");
1519 if (bp) BIO_free(bp);
1520 if (pkey) EVP_PKEY_free(pkey);
1523 if (bp) BIO_free(bp);
1524 if (pkey) EVP_PKEY_free(pkey);
1528 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1536 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1538 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
1542 if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
1544 add_ca_to_cert_store(st, x);
1545 SSL_add_client_CA(ssl, x);
1556 if (!(SSL_use_certificate_ASN1(ssl,
1560 "*** setup_pki: (D)TLS: %s: Unable to configure "
1571 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
1578 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
1582 "*** setup_pki: (D)TLS: %s: Unable to configure "
1593 "*** setup_pki: (D)TLS: No %s Private Key defined",
1603 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1606 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1608 "*** setup_pki: (D)TLS: %s: Unable to configure "
1617 st = SSL_CTX_get_cert_store(ctx);
1618 add_ca_to_cert_store(st, x509);
1625 ssl_engine = ENGINE_by_id(
"pkcs11");
1628 "*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL pkcs11 engine\n");
1631 if (!ENGINE_init(ssl_engine)) {
1633 ENGINE_free(ssl_engine);
1636 "*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1643 if (ENGINE_ctrl_cmd_string(ssl_engine,
1647 "*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1656 "pkcs11:", 7) == 0) {
1657 EVP_PKEY* pkey = ENGINE_load_private_key(ssl_engine,
1663 "*** setup_pki: (D)TLS: %s: Unable to load "
1669 if (!SSL_use_PrivateKey(ssl, pkey)) {
1671 "*** setup_pki: (D)TLS: %s: Unable to configure "
1675 EVP_PKEY_free(pkey);
1678 EVP_PKEY_free(pkey);
1681 if (!(SSL_use_PrivateKey_file(ssl,
1683 SSL_FILETYPE_ASN1))) {
1685 "*** setup_pki: (D)TLS: %s: Unable to configure "
1695 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1702 "pkcs11:", 7) == 0) {
1705 x509 = missing_ENGINE_load_cert(
1709 "*** setup_pki: (D)TLS: %s: Unable to load "
1715 if (!SSL_use_certificate(ssl, x509)) {
1717 "*** setup_pki: (D)TLS: %s: Unable to configure "
1727 if (!(SSL_use_certificate_file(ssl,
1729 SSL_FILETYPE_ASN1))) {
1731 "*** setup_pki: (D)TLS: %s: Unable to configure "
1741 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1751 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1753 x509 = missing_ENGINE_load_cert(
1757 "*** setup_pki: (D)TLS: %s: Unable to load "
1758 "%s CA Certificate\n",
1763 if (!SSL_add_client_CA(ssl, x509)) {
1765 "*** setup_pki: (D)TLS: %s: Unable to configure "
1766 "%s CA Certificate\n",
1772 st = SSL_CTX_get_cert_store(ctx);
1773 add_ca_to_cert_store(st, x509);
1778 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1779 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1781 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1783 "*** setup_pki: (D)TLS: %s: Unable to configure "
1787 if (x509) X509_free(x509);
1790 st = SSL_CTX_get_cert_store(ctx);
1791 add_ca_to_cert_store(st, x509);
1799 "*** setup_pki: (D)TLS: Unknown key type %d\n",
1808get_san_or_cn_from_cert(X509* x509) {
1812 STACK_OF(GENERAL_NAME) *san_list;
1815 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1817 int san_count = sk_GENERAL_NAME_num(san_list);
1819 for (
n = 0;
n < san_count;
n++) {
1820 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list,
n);
1822 if (name->type == GEN_DNS) {
1823 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1826 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
1828 cn = OPENSSL_strdup(dns_name);
1829 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1833 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1836 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
1839 n = (int)strlen(buffer) - 3;
1842 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1843 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1852 char * ecn = strchr(cn,
'/');
1854 return OPENSSL_strndup(cn, ecn-cn);
1857 return OPENSSL_strdup(cn);
1865tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1866 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1867 SSL_get_ex_data_X509_STORE_CTX_idx());
1869 coap_openssl_context_t *context =
1872 int depth = X509_STORE_CTX_get_error_depth(ctx);
1873 int err = X509_STORE_CTX_get_error(ctx);
1874 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1875 char *cn = get_san_or_cn_from_cert(x509);
1876 int keep_preverify_ok = preverify_ok;
1878 if (!preverify_ok) {
1880 case X509_V_ERR_CERT_NOT_YET_VALID:
1881 case X509_V_ERR_CERT_HAS_EXPIRED:
1885 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1889 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1893 case X509_V_ERR_UNABLE_TO_GET_CRL:
1897 case X509_V_ERR_CRL_NOT_YET_VALID:
1898 case X509_V_ERR_CRL_HAS_EXPIRED:
1902 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1903 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1913 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1914 X509_STORE_CTX_set_error(ctx, err);
1916 if (!preverify_ok) {
1917 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
1919 " %s: %s: '%s' depth=%d\n",
1921 "Unknown CA", cn ? cn :
"?", depth);
1925 " %s: %s: '%s' depth=%d\n",
1927 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1932 " %s: %s: overridden: '%s' depth=%d\n",
1934 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1939 int length = i2d_X509(x509, NULL);
1941 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1944 i2d_X509(x509, &base_buf2);
1946 depth, preverify_ok,
1949 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1952 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1956 OPENSSL_free(base_buf);
1959 return preverify_ok;
1962#if COAP_SERVER_SUPPORT
1963#if OPENSSL_VERSION_NUMBER < 0x10101000L
1972tls_secret_call_back(SSL *ssl,
1975 STACK_OF(SSL_CIPHER) *peer_ciphers,
1980 int psk_requested = 0;
1985 assert(session != NULL);
1986 assert(session->
context != NULL);
1987 if (session == NULL ||
1995 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1996 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1999 SSL_CIPHER_get_name(peer_cipher));
2000 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
2006 if (!psk_requested) {
2013 SSL_VERIFY_CLIENT_ONCE |
2014 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2015 tls_verify_call_back);
2018 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2027 X509_VERIFY_PARAM *param;
2029 param = X509_VERIFY_PARAM_new();
2030 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2031 SSL_set1_param(ssl, param);
2032 X509_VERIFY_PARAM_free(param);
2056 SSL_set_cipher_list (ssl, COAP_OPENSSL_PSK_CIPHERS);
2057 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2071tls_server_name_call_back(SSL *ssl,
2078 return SSL_TLSEXT_ERR_NOACK;
2084 coap_openssl_context_t *context =
2086 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2089 if (!sni || !sni[0]) {
2092 for (i = 0; i < context->sni_count; i++) {
2093 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2097 if (i == context->sni_count) {
2103 return SSL_TLSEXT_ERR_ALERT_FATAL;
2108 ctx = SSL_CTX_new(DTLS_method());
2111 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2112 SSL_CTX_set_app_data(ctx, &context->dtls);
2113 SSL_CTX_set_read_ahead(ctx, 1);
2114 coap_set_user_prefs(ctx);
2115 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2116 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2117 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2118 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2120#if !COAP_DISABLE_TCP
2123 ctx = SSL_CTX_new(TLS_method());
2126 SSL_CTX_set_app_data(ctx, &context->tls);
2127 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2128 coap_set_user_prefs(ctx);
2129 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2130 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2133 sni_setup_data = *setup_data;
2134 sni_setup_data.
pki_key = *new_entry;
2135 setup_pki_server(ctx, &sni_setup_data);
2137 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2138 (context->sni_count+1)*
sizeof(sni_entry));
2139 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2140 context->sni_entry_list[context->sni_count].ctx = ctx;
2141 context->sni_count++;
2143 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
2144 SSL_clear_options (ssl, 0xFFFFFFFFL);
2145 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
2152 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2153 return SSL_TLSEXT_ERR_OK;
2156 return SSL_TLSEXT_ERR_ALERT_WARNING;
2167psk_tls_server_name_call_back(SSL *ssl,
2174 return SSL_TLSEXT_ERR_NOACK;
2180 coap_openssl_context_t *o_context =
2182 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2186 if (!sni || !sni[0]) {
2189 for (i = 0; i < o_context->psk_sni_count; i++) {
2190 if (!strcasecmp(sni, (
char*)o_context->psk_sni_entry_list[i].sni)) {
2194 if (i == o_context->psk_sni_count) {
2201 return SSL_TLSEXT_ERR_ALERT_FATAL;
2206 ctx = SSL_CTX_new(DTLS_method());
2209 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2210 SSL_CTX_set_app_data(ctx, &o_context->dtls);
2211 SSL_CTX_set_read_ahead(ctx, 1);
2212 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2213 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2214 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2215 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2216 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2218#if !COAP_DISABLE_TCP
2221 ctx = SSL_CTX_new(TLS_method());
2224 SSL_CTX_set_app_data(ctx, &o_context->tls);
2225 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2226 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2227 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2228 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2232 o_context->psk_sni_entry_list =
2233 OPENSSL_realloc(o_context->psk_sni_entry_list,
2234 (o_context->psk_sni_count+1)*
sizeof(psk_sni_entry));
2235 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2236 OPENSSL_strdup(sni);
2237 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2239 o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
2241 o_context->psk_sni_count++;
2243 SSL_set_SSL_CTX (ssl, o_context->psk_sni_entry_list[i].ctx);
2244 SSL_clear_options (ssl, 0xFFFFFFFFL);
2245 SSL_set_options (ssl,
2246 SSL_CTX_get_options (o_context->psk_sni_entry_list[i].ctx));
2248 &o_context->psk_sni_entry_list[i].psk_info.key);
2249 snprintf(lhint,
sizeof(lhint),
"%.*s",
2250 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2251 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2252 SSL_use_psk_identity_hint(ssl, lhint);
2259 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2260 return SSL_TLSEXT_ERR_OK;
2263 return SSL_TLSEXT_ERR_ALERT_WARNING;
2275tls_client_hello_call_back(SSL *ssl,
2280 coap_openssl_context_t *dtls_context;
2282 int psk_requested = 0;
2283 const unsigned char *out;
2287 *al = SSL_AD_INTERNAL_ERROR;
2288 return SSL_CLIENT_HELLO_ERROR;
2291 assert(session != NULL);
2292 assert(session->
context != NULL);
2294 if (session == NULL ||
2297 *al = SSL_AD_INTERNAL_ERROR;
2298 return SSL_CLIENT_HELLO_ERROR;
2301 setup_data = &dtls_context->setup_data;
2309 size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
2310 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
2311 STACK_OF(SSL_CIPHER) *scsvc = NULL;
2313 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
2314 SSL_client_hello_isv2(ssl),
2315 &peer_ciphers, &scsvc)) {
2317 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
2318 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2321 SSL_CIPHER_get_name(peer_cipher),
2322 SSL_CIPHER_get_protocol_id(peer_cipher));
2323 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
2329 sk_SSL_CIPHER_free(peer_ciphers);
2330 sk_SSL_CIPHER_free(scsvc);
2333 if (psk_requested) {
2339 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2345 return SSL_CLIENT_HELLO_SUCCESS;
2355 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
2358 for (ii = 0; ii < outlen; ii++) {
2374 *al = SSL_AD_UNSUPPORTED_EXTENSION;
2375 return SSL_CLIENT_HELLO_ERROR;
2384 coap_openssl_context_t *context =
2386 const char *sni =
"";
2387 char *sni_tmp = NULL;
2390 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2392 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2393 out[2] == TLSEXT_NAMETYPE_host_name &&
2394 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2398 sni_tmp = OPENSSL_malloc(outlen+1);
2399 sni_tmp[outlen] =
'\000';
2400 memcpy(sni_tmp, out, outlen);
2404 for (i = 0; i < context->sni_count; i++) {
2405 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2409 if (i == context->sni_count) {
2416 *al = SSL_AD_UNRECOGNIZED_NAME;
2417 return SSL_CLIENT_HELLO_ERROR;
2421 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2422 (context->sni_count+1)*
sizeof(sni_entry));
2423 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2424 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
2425 context->sni_count++;
2428 OPENSSL_free(sni_tmp);
2430 sni_setup_data = *setup_data;
2431 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
2444 SSL_VERIFY_CLIENT_ONCE |
2445 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2446 tls_verify_call_back);
2449 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2458 X509_VERIFY_PARAM *param;
2460 param = X509_VERIFY_PARAM_new();
2461 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2462 SSL_set1_param(ssl, param);
2463 X509_VERIFY_PARAM_free(param);
2470 return SSL_CLIENT_HELLO_SUCCESS;
2481psk_tls_client_hello_call_back(SSL *ssl,
2486 coap_openssl_context_t *o_context;
2488 const unsigned char *out;
2494 if (!c_session || !c_session->
context) {
2507 const char *sni =
"";
2508 char *sni_tmp = NULL;
2512 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2514 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2515 out[2] == TLSEXT_NAMETYPE_host_name &&
2516 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2520 sni_tmp = OPENSSL_malloc(outlen+1);
2522 sni_tmp[outlen] =
'\000';
2523 memcpy(sni_tmp, out, outlen);
2529 for (i = 0; i < o_context->psk_sni_count; i++) {
2530 if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
2534 if (i == o_context->psk_sni_count) {
2538 psk_sni_entry *tmp_entry;
2544 *al = SSL_AD_UNRECOGNIZED_NAME;
2545 return SSL_CLIENT_HELLO_ERROR;
2549 OPENSSL_realloc(o_context->psk_sni_entry_list,
2550 (o_context->psk_sni_count+1)*
sizeof(sni_entry));
2552 o_context->psk_sni_entry_list = tmp_entry;
2553 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2554 OPENSSL_strdup(sni);
2555 if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
2556 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2558 o_context->psk_sni_count++;
2563 OPENSSL_free(sni_tmp);
2566 &o_context->psk_sni_entry_list[i].psk_info.hint)
2571 &o_context->psk_sni_entry_list[i].psk_info.key)
2575 if (o_context->psk_sni_entry_list[i].psk_info.hint.s) {
2576 snprintf(lhint,
sizeof(lhint),
"%.*s",
2577 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2578 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2579 SSL_use_psk_identity_hint(ssl, lhint);
2582 return SSL_CLIENT_HELLO_SUCCESS;
2585 *al = SSL_AD_INTERNAL_ERROR;
2586 return SSL_CLIENT_HELLO_ERROR;
2596 coap_openssl_context_t *context =
2601 context->setup_data = *setup_data;
2602 if (!context->setup_data.verify_peer_cert) {
2606 context->setup_data.allow_self_signed = 1;
2607 context->setup_data.allow_expired_certs = 1;
2608 context->setup_data.cert_chain_validation = 1;
2609 context->setup_data.cert_chain_verify_depth = 10;
2610 context->setup_data.check_cert_revocation = 1;
2611 context->setup_data.allow_no_crl = 1;
2612 context->setup_data.allow_expired_crl = 1;
2613 context->setup_data.allow_bad_md_hash = 1;
2614 context->setup_data.allow_short_rsa_length = 1;
2616#if COAP_SERVER_SUPPORT
2618 if (context->dtls.ctx) {
2620#if OPENSSL_VERSION_NUMBER < 0x10101000L
2621 if (!setup_pki_server(context->dtls.ctx, setup_data))
2630#if OPENSSL_VERSION_NUMBER < 0x10101000L
2631 if (SSLeay() >= 0x10101000L) {
2633 "OpenSSL compiled with %lux, linked with %lux, so "
2634 "no certificate checking\n",
2635 OPENSSL_VERSION_NUMBER, SSLeay());
2637 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
2638 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
2639 tls_server_name_call_back);
2641 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
2642 tls_client_hello_call_back,
2646#if !COAP_DISABLE_TCP
2647 if (context->tls.ctx) {
2649#if OPENSSL_VERSION_NUMBER < 0x10101000L
2650 if (!setup_pki_server(context->tls.ctx, setup_data))
2659#if OPENSSL_VERSION_NUMBER < 0x10101000L
2660 if (SSLeay() >= 0x10101000L) {
2662 "OpenSSL compiled with %lux, linked with %lux, so "
2663 "no certificate checking\n",
2664 OPENSSL_VERSION_NUMBER, SSLeay());
2666 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
2667 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
2668 tls_server_name_call_back);
2670 SSL_CTX_set_client_hello_cb(context->tls.ctx,
2671 tls_client_hello_call_back,
2675 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
2683 if (!context->dtls.ssl) {
2685 context->dtls.ssl = SSL_new(context->dtls.ctx);
2686 if (!context->dtls.ssl)
2688 bio = BIO_new(context->dtls.meth);
2690 SSL_free (context->dtls.ssl);
2691 context->dtls.ssl = NULL;
2694 SSL_set_bio(context->dtls.ssl, bio, bio);
2695 SSL_set_app_data(context->dtls.ssl, NULL);
2696 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
2699 context->psk_pki_enabled |= IS_PKI;
2705 const char *ca_file,
2708 coap_openssl_context_t *context =
2710 if (context->dtls.ctx) {
2711 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
2713 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2717#if !COAP_DISABLE_TCP
2718 if (context->tls.ctx) {
2719 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
2721 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2732 coap_openssl_context_t *context =
2734 return context->psk_pki_enabled ? 1 : 0;
2740 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
2742 if (context->dtls.ssl)
2743 SSL_free(context->dtls.ssl);
2744 if (context->dtls.ctx)
2745 SSL_CTX_free(context->dtls.ctx);
2746 if (context->dtls.cookie_hmac)
2747 HMAC_CTX_free(context->dtls.cookie_hmac);
2748 if (context->dtls.meth)
2749 BIO_meth_free(context->dtls.meth);
2750 if (context->dtls.bio_addr)
2751 BIO_ADDR_free(context->dtls.bio_addr);
2752#if !COAP_DISABLE_TCP
2753 if ( context->tls.ctx )
2754 SSL_CTX_free( context->tls.ctx );
2755 if ( context->tls.meth )
2756 BIO_meth_free( context->tls.meth );
2758 for (i = 0; i < context->sni_count; i++) {
2759 OPENSSL_free(context->sni_entry_list[i].sni);
2760#if OPENSSL_VERSION_NUMBER < 0x10101000L
2761 SSL_CTX_free(context->sni_entry_list[i].ctx);
2764 if (context->sni_count)
2765 OPENSSL_free(context->sni_entry_list);
2766 for (i = 0; i < context->psk_sni_count; i++) {
2767 OPENSSL_free((
char*)context->psk_sni_entry_list[i].sni);
2768#if OPENSSL_VERSION_NUMBER < 0x10101000L
2769 SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
2772 if (context->psk_sni_count)
2773 OPENSSL_free(context->psk_sni_entry_list);
2777#if COAP_SERVER_SUPPORT
2780 SSL *nssl = NULL, *ssl = NULL;
2781 coap_ssl_data *data;
2782 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
2786 nssl = SSL_new(dtls->ctx);
2789 nbio = BIO_new(dtls->meth);
2792 SSL_set_bio(nssl, nbio, nbio);
2793 SSL_set_app_data(nssl, NULL);
2794 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
2795 SSL_set_mtu(nssl, (
long)session->
mtu);
2799 SSL_set_app_data(ssl, session);
2801 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
2802 data->session = session;
2806 if (psk_hint != NULL && psk_hint->
length) {
2807 char* hint = OPENSSL_malloc(psk_hint->
length + 1);
2810 memcpy(hint, psk_hint->
s, psk_hint->
length);
2811 hint[psk_hint->
length] =
'\000';
2812 SSL_use_psk_identity_hint(ssl, hint);
2819 r = SSL_accept(ssl);
2821 int err = SSL_get_error(ssl, r);
2822 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2840#if COAP_CLIENT_SUPPORT
2844 coap_openssl_context_t *context =
2847 if (context->psk_pki_enabled & IS_PSK) {
2852 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
2856 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
2857#if COAP_SERVER_SUPPORT
2858 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2860 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2863 SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
2865#if !COAP_DISABLE_TCP
2867 SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
2871 "CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
2874 if (context->psk_pki_enabled & IS_PKI) {
2879#if !COAP_DISABLE_TCP
2881 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
2886 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
2892 X509_VERIFY_PARAM *param;
2894 param = X509_VERIFY_PARAM_new();
2895 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2896 SSL_set1_param(ssl, param);
2897 X509_VERIFY_PARAM_free(param);
2904 SSL_VERIFY_CLIENT_ONCE |
2905 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2906 tls_verify_call_back);
2908 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2921 coap_ssl_data *data;
2923 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2924 coap_dtls_context_t *dtls = &context->dtls;
2926 ssl = SSL_new(dtls->ctx);
2929 bio = BIO_new(dtls->meth);
2932 data = (coap_ssl_data *)BIO_get_data(bio);
2933 data->session = session;
2934 SSL_set_bio(ssl, bio, bio);
2935 SSL_set_app_data(ssl, session);
2936 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
2937 SSL_set_mtu(ssl, (
long)session->
mtu);
2939 if (!setup_client_ssl_session(session, ssl))
2944 r = SSL_connect(ssl);
2946 int ret = SSL_get_error(ssl, r);
2947 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2963 SSL *ssl = (SSL *)session->
tls;
2965 SSL_set_mtu(ssl, (
long)session->
mtu);
2970 SSL *ssl = (SSL *)session->
tls;
2972 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2973 int r = SSL_shutdown(ssl);
2974 if (r == 0) r = SSL_shutdown(ssl);
2977 session->
tls = NULL;
2984 const uint8_t *data,
size_t data_len) {
2986 SSL *ssl = (SSL *)session->
tls;
2988 assert(ssl != NULL);
2991 r = SSL_write(ssl, data, (
int)data_len);
2994 int err = SSL_get_error(ssl, r);
2995 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2999 if (err == SSL_ERROR_ZERO_RETURN)
3001 else if (err == SSL_ERROR_SSL)
3031 SSL *ssl = (SSL *)session->
tls;
3032 coap_ssl_data *ssl_data;
3035 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
3036 return ssl_data->timeout;
3045 SSL *ssl = (SSL *)session->
tls;
3049 (DTLSv1_handle_timeout(ssl) < 0)) {
3057#if COAP_SERVER_SUPPORT
3059 const uint8_t *data,
size_t data_len) {
3060 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
3061 coap_ssl_data *ssl_data;
3064 SSL_set_mtu(dtls->ssl, (
long)session->
mtu);
3065 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
3066 assert(ssl_data != NULL);
3067 if (ssl_data->pdu_len) {
3071 ssl_data->session = session;
3072 ssl_data->pdu = data;
3073 ssl_data->pdu_len = (unsigned)data_len;
3074 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
3076 int err = SSL_get_error(dtls->ssl, r);
3077 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3096 const uint8_t *data,
size_t data_len) {
3097 coap_ssl_data *ssl_data;
3098 SSL *ssl = (SSL *)session->
tls;
3101 assert(ssl != NULL);
3103 int in_init = SSL_in_init(ssl);
3105 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
3106 assert(ssl_data != NULL);
3108 if (ssl_data->pdu_len) {
3112 ssl_data->pdu = data;
3113 ssl_data->pdu_len = (unsigned)data_len;
3116 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
3121 int err = SSL_get_error(ssl, r);
3122 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3123 if (in_init && SSL_is_init_finished(ssl)) {
3131 if (err == SSL_ERROR_ZERO_RETURN)
3133 else if (err == SSL_ERROR_SSL)
3151 if (ssl_data && ssl_data->pdu_len) {
3153 coap_log(
LOG_DEBUG,
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
3154 ssl_data->pdu_len = 0;
3155 ssl_data->pdu = NULL;
3161 unsigned int overhead = 37;
3162 const SSL_CIPHER *s_ciph = NULL;
3163 if (session->
tls != NULL)
3164 s_ciph = SSL_get_current_cipher(session->
tls);
3166 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
3168 const EVP_CIPHER *e_ciph;
3172 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
3174 switch (EVP_CIPHER_mode(e_ciph)) {
3175 case EVP_CIPH_GCM_MODE:
3176 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
3177 maclen = EVP_GCM_TLS_TAG_LEN;
3180 case EVP_CIPH_CCM_MODE:
3181 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
3182 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3183 if (strstr(cipher,
"CCM8"))
3189 case EVP_CIPH_CBC_MODE:
3190 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
3191 blocksize = EVP_CIPHER_block_size(e_ciph);
3192 ivlen = EVP_CIPHER_iv_length(e_ciph);
3194 maclen = EVP_MD_size(e_md);
3197 case EVP_CIPH_STREAM_CIPHER:
3204 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3211 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
3216#if !COAP_DISABLE_TCP
3217#if COAP_CLIENT_SUPPORT
3222 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3223 coap_tls_context_t *tls = &context->tls;
3226 ssl = SSL_new(tls->ctx);
3229 bio = BIO_new(tls->meth);
3232 BIO_set_data(bio, session);
3233 SSL_set_bio(ssl, bio, bio);
3234 SSL_set_app_data(ssl, session);
3236 if (!setup_client_ssl_session(session, ssl))
3239 r = SSL_connect(ssl);
3241 int ret = SSL_get_error(ssl, r);
3242 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3244 if (ret == SSL_ERROR_WANT_READ)
3246 if (ret == SSL_ERROR_WANT_WRITE) {
3248#ifdef COAP_EPOLL_SUPPORT
3261 *connected = SSL_is_init_finished(ssl);
3272#if COAP_SERVER_SUPPORT
3276 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
3281 ssl = SSL_new(tls->ctx);
3284 bio = BIO_new(tls->meth);
3287 BIO_set_data(bio, session);
3288 SSL_set_bio(ssl, bio, bio);
3289 SSL_set_app_data(ssl, session);
3292 if (psk_hint != NULL && psk_hint->
length) {
3293 char* hint = OPENSSL_malloc(psk_hint->
length + 1);
3296 memcpy(hint, psk_hint->
s, psk_hint->
length);
3297 hint[psk_hint->
length] =
'\000';
3298 SSL_use_psk_identity_hint(ssl, hint);
3305 r = SSL_accept(ssl);
3307 int err = SSL_get_error(ssl, r);
3308 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3310 if (err == SSL_ERROR_WANT_READ)
3312 if (err == SSL_ERROR_WANT_WRITE) {
3314#ifdef COAP_EPOLL_SUPPORT
3327 *connected = SSL_is_init_finished(ssl);
3339 SSL *ssl = (SSL *)session->
tls;
3341 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3342 int r = SSL_shutdown(ssl);
3343 if (r == 0) r = SSL_shutdown(ssl);
3346 session->
tls = NULL;
3353 const uint8_t *data,
3356 SSL *ssl = (SSL *)session->
tls;
3362 in_init = !SSL_is_init_finished(ssl);
3364 r = SSL_write(ssl, data, (
int)data_len);
3367 int err = SSL_get_error(ssl, r);
3368 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3369 if (in_init && SSL_is_init_finished(ssl)) {
3375 if (err == SSL_ERROR_WANT_READ)
3377 if (err == SSL_ERROR_WANT_WRITE) {
3379#ifdef COAP_EPOLL_SUPPORT
3391 if (err == SSL_ERROR_ZERO_RETURN)
3393 else if (err == SSL_ERROR_SSL)
3397 }
else if (in_init && SSL_is_init_finished(ssl)) {
3422 SSL *ssl = (SSL *)session->
tls;
3428 in_init = !SSL_is_init_finished(ssl);
3430 r = SSL_read(ssl, data, (
int)data_len);
3432 int err = SSL_get_error(ssl, r);
3433 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3434 if (in_init && SSL_is_init_finished(ssl)) {
3440 if (err == SSL_ERROR_WANT_READ)
3442 if (err == SSL_ERROR_WANT_WRITE) {
3444#ifdef COAP_EPOLL_SUPPORT
3454 if (err == SSL_ERROR_ZERO_RETURN)
3456 else if (err == SSL_ERROR_SSL)
3460 }
else if (in_init && SSL_is_init_finished(ssl)) {
3482#if COAP_SERVER_SUPPORT
3485 EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new();
3488 EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL);
3495 EVP_MD_CTX_free(digest_ctx);
3500 const uint8_t *data,
3502 return EVP_DigestUpdate(digest_ctx, data, data_len);
3509 int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t*)digest_buffer, &size);
3522#pragma GCC diagnostic ignored "-Wunused-function"
Pulls together all the internal only header files.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
const char * coap_socket_strerror(void)
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
#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)
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
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)
int 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_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_check_keys_enabled(coap_context_t *ctx COAP_UNUSED)
static int dtls_log_level
ssize_t coap_tls_write(coap_session_t *session COAP_UNUSED, const uint8_t *data COAP_UNUSED, size_t data_len COAP_UNUSED)
void coap_dtls_session_update_mtu(coap_session_t *session COAP_UNUSED)
int coap_dtls_context_set_pki_root_cas(coap_context_t *ctx COAP_UNUSED, const char *ca_file COAP_UNUSED, const char *ca_path COAP_UNUSED)
int coap_dtls_handle_timeout(coap_session_t *session COAP_UNUSED)
void coap_dtls_free_context(void *handle COAP_UNUSED)
void coap_dtls_free_session(coap_session_t *coap_session COAP_UNUSED)
void * coap_dtls_new_context(coap_context_t *coap_context COAP_UNUSED)
void coap_tls_free_session(coap_session_t *coap_session COAP_UNUSED)
void coap_digest_free(coap_digest_ctx_t *digest_ctx)
Free off coap_digest_ctx_t.
struct coap_digest_t coap_digest_t
int coap_digest_final(coap_digest_ctx_t *digest_ctx, coap_digest_t *digest_buffer)
Finalize the coap_digest information into the provided digest_buffer.
int coap_digest_update(coap_digest_ctx_t *digest_ctx, const uint8_t *data, size_t data_len)
Update the coap_digest information with the next chunk of data.
coap_digest_ctx_t * coap_digest_setup(void)
Initialize a coap_digest.
coap_tick_t coap_ticks_from_rt_us(uint64_t t)
Helper function that converts POSIX wallclock time in us to coap ticks.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
int coap_prng(void *buf, size_t len)
Fills buf with len random bytes using the default pseudo random number generator.
int coap_handle_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_handle_event(coap_context_t *context, coap_event_t event, coap_session_t *session)
Invokes the event handler of context for the given event and data.
const coap_bin_const_t * coap_get_session_client_psk_identity(const coap_session_t *session)
Get the current client's PSK identity.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
void * coap_dtls_new_client_session(coap_session_t *coap_session)
Create a new client-side session.
void * coap_tls_new_client_session(coap_session_t *coap_session, int *connected)
Create a new TLS client-side session.
void * coap_tls_new_server_session(coap_session_t *coap_session, int *connected)
Create a TLS new server-side session.
void * coap_dtls_new_server_session(coap_session_t *coap_session)
Create a new DTLS server-side session.
int coap_dtls_hello(coap_session_t *coap_session, const uint8_t *data, size_t data_len)
Handling client HELLO messages from a new candiate peer.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
int coap_dtls_context_set_cpsk(coap_context_t *coap_context, coap_dtls_cpsk_t *setup_data)
Set the DTLS context's default client PSK information.
int coap_dtls_context_set_spsk(coap_context_t *coap_context, coap_dtls_spsk_t *setup_data)
Set the DTLS context's default server PSK information.
void coap_dtls_shutdown(void)
Close down the underlying (D)TLS Library layer.
const coap_bin_const_t * coap_get_session_client_psk_key(const coap_session_t *coap_session)
Get the current client's PSK key.
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.
#define COAP_DTLS_HINT_LENGTH
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
int coap_tls_is_supported(void)
Check whether TLS is available.
int coap_dtls_is_supported(void)
Check whether DTLS is available.
@ 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_PEM_BUF
The PKI key type is PEM buffer.
@ COAP_PKI_KEY_PEM
The PKI key type is PEM file.
@ COAP_PKI_KEY_ASN1
The PKI key type is ASN.1 (DER) buffer.
@ COAP_ASN1_PKEY_DH
DH type.
@ COAP_ASN1_PKEY_NONE
NONE.
@ COAP_ASN1_PKEY_TLS1_PRF
TLS1_PRF type.
@ COAP_ASN1_PKEY_RSA2
RSA2 type.
@ COAP_ASN1_PKEY_DSA
DSA type.
@ COAP_ASN1_PKEY_DHX
DHX type.
@ COAP_ASN1_PKEY_DSA4
DSA4 type.
@ COAP_ASN1_PKEY_DSA2
DSA2 type.
@ COAP_ASN1_PKEY_RSA
RSA type.
@ COAP_ASN1_PKEY_DSA1
DSA1 type.
@ COAP_ASN1_PKEY_HKDF
HKDF type.
@ COAP_ASN1_PKEY_EC
EC type.
@ COAP_ASN1_PKEY_DSA3
DSA3 type.
@ COAP_ASN1_PKEY_HMAC
HMAC type.
@ COAP_ASN1_PKEY_CMAC
CMAC type.
@ COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
@ COAP_EVENT_DTLS_CLOSED
Triggerred when (D)TLS session closed.
@ COAP_EVENT_DTLS_CONNECTED
Triggered when (D)TLS session connected.
@ COAP_EVENT_DTLS_RENEGOTIATE
Triggered when (D)TLS session renegotiated.
@ COAP_EVENT_DTLS_ERROR
Triggered when (D)TLS error occurs.
void coap_dtls_set_log_level(int level)
Sets the (D)TLS logging level to the specified level.
int coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log(level,...)
Logging function.
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).
void coap_session_send_csm(coap_session_t *session)
Notify session transport has just connected and CSM exchange can now start.
ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for datagram data transmission.
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).
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
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(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
@ COAP_SESSION_STATE_HANDSHAKE
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
CoAP binary data definition with const data.
size_t length
length of binary data
const uint8_t * s
read-only binary data
The CoAP stack's global state is stored in a coap_context_t object.
coap_dtls_spsk_t spsk_setup_data
Contains the initial PSK server setup data.
The structure that holds the 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_pem_t pem
for PEM file keys
coap_pki_key_pkcs11_t pkcs11
for PKCS11 keys
union coap_dtls_key_t::@2 key
coap_pki_key_pem_buf_t pem_buf
for PEM memory keys
coap_pki_key_t key_type
key format type
coap_pki_key_asn1_t asn1
for ASN.1 (DER) memory keys
The structure used for defining the PKI setup data to be used.
uint8_t allow_no_crl
1 ignore if CRL not there
void * cn_call_back_arg
Passed in to the CN callback function.
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
uint8_t check_cert_revocation
1 if revocation checks wanted
coap_dtls_pki_sni_callback_t validate_sni_call_back
SNI check callback function.
uint8_t cert_chain_verify_depth
recommended depth is 3
coap_dtls_security_setup_t additional_tls_setup_call_back
Additional Security callback handler that is invoked when libcoap has done the standard,...
uint8_t allow_expired_certs
1 if expired certs are allowed
uint8_t verify_peer_cert
Set to COAP_DTLS_PKI_SETUP_VERSION to support this version of the struct.
char * client_sni
If not NULL, SNI to use in client TLS setup.
uint8_t allow_self_signed
1 if self-signed certs are allowed.
void * sni_call_back_arg
Passed in to the sni callback function.
coap_dtls_cn_callback_t validate_cn_call_back
CN check callback function.
uint8_t allow_expired_crl
1 if expired crl is allowed
uint8_t is_rpk_not_cert
1 is RPK instead of Public Certificate.
uint8_t check_common_ca
1 if peer cert is to be signed by the same CA as the local cert
coap_dtls_key_t pki_key
PKI key definition.
The structure that holds the Server Pre-Shared Key and Identity Hint information.
The structure used for defining the Server PSK setup data to be used.
coap_dtls_psk_sni_callback_t validate_sni_call_back
SNI check callback function.
coap_dtls_id_callback_t validate_id_call_back
Identity check callback function.
void * id_call_back_arg
Passed in to the Identity callback function.
void * sni_call_back_arg
Passed in to the SNI callback function.
coap_dtls_spsk_info_t psk_info
Server PSK definition.
const uint8_t * private_key
ASN1 (DER) Private Key.
coap_asn1_privatekey_type_t private_key_type
Private Key Type.
size_t public_cert_len
ASN1 Public Cert length.
size_t private_key_len
ASN1 Private Key length.
const uint8_t * ca_cert
ASN1 (DER) Common CA Cert.
size_t ca_cert_len
ASN1 CA Cert length.
const uint8_t * public_cert
ASN1 (DER) Public Cert, or Public Key if RPK.
size_t ca_cert_len
PEM buffer CA Cert length.
const uint8_t * ca_cert
PEM buffer Common CA Cert.
size_t private_key_len
PEM buffer Private Key length.
const uint8_t * private_key
PEM buffer Private Key If RPK and 'EC PRIVATE KEY' this can be used for both the public_cert and priv...
size_t public_cert_len
PEM buffer Public Cert length.
const uint8_t * public_cert
PEM buffer Public Cert, or Public Key if RPK.
const char * ca_file
File location of Common CA in PEM format.
const char * public_cert
File location of Public Cert.
const char * private_key
File location of Private Key in PEM format.
const char * private_key
pkcs11: URI for Private Key
const char * ca
pkcs11: URI for Common CA Certificate
const char * user_pin
User pin to access PKCS11.
const char * public_cert
pkcs11: URI for Public Cert
Abstraction of virtual session that can be attached to coap_context_t (client) or coap_endpoint_t (se...
unsigned int dtls_timeout_count
dtls setup retry counter
coap_bin_const_t * psk_key
If client, this field contains the current pre-shared key for server; When this field is NULL,...
coap_socket_t sock
socket object for the session, if any
coap_session_state_t state
current state of relationaship with peer
coap_proto_t proto
protocol used
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
size_t mtu
path or CSM mtu (xmt)
int dtls_event
Tracking any (D)TLS events on this sesison.
void * tls
security parameters
uint16_t max_retransmit
maximum re-transmit count (default 4)
coap_context_t * context
session's context
coap_socket_flags_t flags
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