20#ifdef COAP_WITH_LIBOPENSSL
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#if OPENSSL_VERSION_NUMBER >= 0x30000000L
76#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
79#if !defined(__MINGW32__)
80#pragma warning(disable : 4996)
85#ifdef COAP_EPOLL_SUPPORT
86# include <sys/epoll.h>
89#if OPENSSL_VERSION_NUMBER < 0x10100000L
90#error Must be compiled against OpenSSL 1.1.0 or later
94#define strcasecmp _stricmp
95#define strncasecmp _strnicmp
99#ifndef TLSEXT_TYPE_client_certificate_type
100#define TLSEXT_TYPE_client_certificate_type 19
102#ifndef TLSEXT_TYPE_server_certificate_type
103#define TLSEXT_TYPE_server_certificate_type 20
106#ifndef COAP_OPENSSL_CIPHERS
107#if OPENSSL_VERSION_NUMBER >= 0x10101000L
108#define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL"
110#define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL"
114#ifndef COAP_OPENSSL_PSK_CIPHERS
115#define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL"
119typedef struct coap_dtls_context_t {
122 HMAC_CTX *cookie_hmac;
125} coap_dtls_context_t;
127typedef struct coap_tls_context_t {
135typedef struct sni_entry {
137#if OPENSSL_VERSION_NUMBER < 0x10101000L
144typedef struct psk_sni_entry {
146#if OPENSSL_VERSION_NUMBER < 0x10101000L
152typedef struct coap_openssl_context_t {
153 coap_dtls_context_t dtls;
155 coap_tls_context_t tls;
160 sni_entry *sni_entry_list;
161 size_t psk_sni_count;
162 psk_sni_entry *psk_sni_entry_list;
163} coap_openssl_context_t;
165#if COAP_SERVER_SUPPORT
166#if OPENSSL_VERSION_NUMBER < 0x10101000L
167static int psk_tls_server_name_call_back(SSL *ssl,
int *sd,
void *arg);
169static int psk_tls_client_hello_call_back(SSL *ssl,
int *al,
void *arg);
175 if (SSLeay() < 0x10100000L) {
176 coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
179#if OPENSSL_VERSION_NUMBER >= 0x10101000L
187 if (SSLeay() < 0x10101000L) {
188 coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
198 if (SSLeay() < 0x10100000L) {
199 coap_log_warn(
"OpenSSL version 1.1.0 or later is required\n");
202#if OPENSSL_VERSION_NUMBER >= 0x10101000L
203 if (SSLeay() < 0x10101000L) {
204 coap_log_warn(
"OpenSSL version 1.1.1 or later is required\n");
259static ENGINE *ssl_engine = NULL;
263 SSL_load_error_strings();
265 ENGINE_load_dynamic();
272 ENGINE_finish(ssl_engine);
274 ENGINE_free(ssl_engine);
287 return c_session->
tls;
307typedef struct coap_ssl_data {
316coap_dgram_create(BIO *a) {
317 coap_ssl_data *data = NULL;
318 data = malloc(
sizeof(coap_ssl_data));
322 BIO_set_data(a, data);
323 memset(data, 0x00,
sizeof(coap_ssl_data));
328coap_dgram_destroy(BIO *a) {
332 data = (coap_ssl_data *)BIO_get_data(a);
339coap_dgram_read(BIO *a,
char *out,
int outl) {
341 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
344 if (data != NULL && data->pdu_len > 0) {
345 if (outl < (
int)data->pdu_len) {
346 memcpy(out, data->pdu, outl);
349 memcpy(out, data->pdu, data->pdu_len);
350 ret = (int)data->pdu_len;
352 if (!data->peekmode) {
359 BIO_clear_retry_flags(a);
361 BIO_set_retry_read(a);
367coap_dgram_write(BIO *a,
const char *in,
int inl) {
369 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
371 if (data && data->session) {
373#if COAP_SERVER_SUPPORT
374 && data->session->endpoint == NULL
378 BIO_clear_retry_flags(a);
382 ret = (int)data->session->sock.lfunc[
COAP_LAYER_TLS].l_write(data->session,
385 BIO_clear_retry_flags(a);
387 BIO_set_retry_write(a);
389 BIO_clear_retry_flags(a);
396coap_dgram_puts(BIO *a,
const char *pstr) {
397 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
401coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
403 coap_ssl_data *data = BIO_get_data(a);
408 case BIO_CTRL_GET_CLOSE:
409 ret = BIO_get_shutdown(a);
411 case BIO_CTRL_SET_CLOSE:
412 BIO_set_shutdown(a, (
int)num);
414 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
416 data->peekmode = (unsigned)num;
420 case BIO_CTRL_DGRAM_CONNECT:
423 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
424 case BIO_CTRL_DGRAM_GET_MTU:
425 case BIO_CTRL_DGRAM_SET_MTU:
426 case BIO_CTRL_DGRAM_QUERY_MTU:
427 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
432 case BIO_CTRL_DGRAM_MTU_DISCOVER:
433 case BIO_CTRL_DGRAM_SET_CONNECTED:
435 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
438 ((
struct timeval *)ptr)->tv_usec);
443 case BIO_C_FILE_SEEK:
444 case BIO_C_FILE_TELL:
446 case BIO_CTRL_PENDING:
447 case BIO_CTRL_WPENDING:
448 case BIO_CTRL_DGRAM_GET_PEER:
449 case BIO_CTRL_DGRAM_SET_PEER:
450 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
451 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
452 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
453 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
454 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
455 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
456 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
457 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
466coap_dtls_generate_cookie(SSL *ssl,
467 unsigned char *cookie,
468 unsigned int *cookie_len) {
469 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
470 coap_dtls_context_t *dtls = ctx ? (coap_dtls_context_t *)SSL_CTX_get_app_data(ctx) : NULL;
471 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(SSL_get_rbio(ssl));
474 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
475 r &= HMAC_Update(dtls->cookie_hmac,
476 (
const uint8_t *)&data->session->addr_info.local.addr,
477 (
size_t)data->session->addr_info.local.size);
478 r &= HMAC_Update(dtls->cookie_hmac,
479 (
const uint8_t *)&data->session->addr_info.remote.addr,
480 (
size_t)data->session->addr_info.remote.size);
481 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
488coap_dtls_verify_cookie(SSL *ssl,
489 const uint8_t *cookie,
490 unsigned int cookie_len) {
493 if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
494 cookie_len == len && memcmp(cookie, hmac, len) == 0)
500#if COAP_CLIENT_SUPPORT
502coap_dtls_psk_client_callback(SSL *ssl,
505 unsigned int max_identity_len,
507 unsigned int max_psk_len) {
509 coap_openssl_context_t *o_context;
517 if (c_session == NULL || c_session->
context == NULL)
520 if (o_context == NULL)
524 temp.
s = hint ? (
const uint8_t *)hint : (const uint8_t *)
"";
525 temp.
length = strlen((
const char *)temp.
s);
529 (
const char *)temp.
s);
541 if (cpsk_info == NULL)
546 psk_identity = &cpsk_info->
identity;
547 psk_key = &cpsk_info->
key;
553 if (psk_identity == NULL || psk_key == NULL) {
559 if (!max_identity_len)
562 if (psk_identity->
length > max_identity_len) {
563 coap_log_warn(
"psk_identity too large, truncated to %d bytes\n",
567 max_identity_len = (
unsigned int)psk_identity->
length;
569 memcpy(identity, psk_identity->
s, max_identity_len);
570 identity[max_identity_len] =
'\000';
572 if (psk_key->
length > max_psk_len) {
577 max_psk_len = (
unsigned int)psk_key->
length;
579 memcpy(psk, psk_key->
s, max_psk_len);
584#if COAP_SERVER_SUPPORT
586coap_dtls_psk_server_callback(
588 const char *identity,
590 unsigned int max_psk_len
598 if (c_session == NULL || c_session->
context == NULL)
604 lidentity.
s = identity ? (
const uint8_t *)identity : (const uint8_t *)
"";
605 lidentity.
length = strlen((
const char *)lidentity.
s);
609 (
int)lidentity.
length, (
const char *)lidentity.
s);
624 if (psk_key->
length > max_psk_len) {
629 max_psk_len = (
unsigned int)psk_key->
length;
631 memcpy(psk, psk_key->
s, max_psk_len);
637ssl_function_definition(
unsigned long e) {
638#if OPENSSL_VERSION_NUMBER >= 0x30000000L
642 static char buff[80];
644 snprintf(buff,
sizeof(buff),
" at %s:%s",
645 ERR_lib_error_string(e), ERR_func_error_string(e));
651coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
654 int w = where &~SSL_ST_MASK;
658 "coap_dtls_info_callback: session not determined, where 0x%0x and ret 0x%0x\n", where, ret);
661 if (w & SSL_ST_CONNECT)
662 pstr =
"SSL_connect";
663 else if (w & SSL_ST_ACCEPT)
668 if (where & SSL_CB_LOOP) {
671 }
else if (where & SSL_CB_ALERT) {
673 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
674 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
676 if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
680 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
683 SSL_alert_type_string_long(ret),
684 SSL_alert_desc_string_long(ret));
685 }
else if (where & SSL_CB_EXIT) {
691 while ((e = ERR_get_error()))
694 ssl_function_definition(e));
696 }
else if (ret < 0) {
698 int err = SSL_get_error(ssl, ret);
699 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE &&
700 err != SSL_ERROR_WANT_CONNECT && err != SSL_ERROR_WANT_ACCEPT &&
701 err != SSL_ERROR_WANT_X509_LOOKUP) {
705 while ((e = ERR_get_error()))
708 ssl_function_definition(e));
714 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
720coap_sock_create(BIO *a) {
726coap_sock_destroy(BIO *a) {
738coap_sock_read(BIO *a,
char *out,
int outl) {
742 if (session && out != NULL) {
747 BIO_set_retry_read(a);
750 BIO_clear_retry_flags(a);
763coap_sock_write(BIO *a,
const char *in,
int inl) {
776 BIO_clear_retry_flags(a);
778 BIO_set_retry_read(a);
781 BIO_clear_retry_flags(a);
785 (errno == EPIPE || errno == ECONNRESET)) {
805coap_sock_puts(BIO *a,
const char *pstr) {
806 return coap_sock_write(a, pstr, (
int)strlen(pstr));
810coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
821 case BIO_CTRL_SET_CLOSE:
827 case BIO_CTRL_GET_CLOSE:
836coap_set_user_prefs(SSL_CTX *ctx) {
837 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
839#ifdef COAP_OPENSSL_SIGALGS
840 SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
841 SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
844#if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS)
845 SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
851 coap_openssl_context_t *context;
856 uint8_t cookie_secret[32];
858 memset(context, 0,
sizeof(coap_openssl_context_t));
861 context->dtls.ctx = SSL_CTX_new(DTLS_method());
862 if (!context->dtls.ctx)
864 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
865 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
866 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
867 coap_set_user_prefs(context->dtls.ctx);
868 memset(cookie_secret, 0,
sizeof(cookie_secret));
869 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
871 "Insufficient entropy for random cookie generation");
872 coap_prng(cookie_secret,
sizeof(cookie_secret));
874 context->dtls.cookie_hmac = HMAC_CTX_new();
875 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret),
878 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
879 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
880 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
881 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
882#if OPENSSL_VERSION_NUMBER >= 0x30000000L
883 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_LEGACY_SERVER_CONNECT);
885 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
886 if (!context->dtls.meth)
888 context->dtls.bio_addr = BIO_ADDR_new();
889 if (!context->dtls.bio_addr)
891 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
892 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
893 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
894 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
895 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
896 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
900 context->tls.ctx = SSL_CTX_new(TLS_method());
901 if (!context->tls.ctx)
903 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
904 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
905 coap_set_user_prefs(context->tls.ctx);
906 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
907 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
908 if (!context->tls.meth)
910 BIO_meth_set_write(context->tls.meth, coap_sock_write);
911 BIO_meth_set_read(context->tls.meth, coap_sock_read);
912 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
913 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
914 BIO_meth_set_create(context->tls.meth, coap_sock_create);
915 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
926#if COAP_SERVER_SUPPORT
931 coap_openssl_context_t *o_context =
935 if (!setup_data || !o_context)
938 SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
939 coap_dtls_psk_server_callback);
941 SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
942 coap_dtls_psk_server_callback);
948 SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
950 SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
954#if OPENSSL_VERSION_NUMBER < 0x10101000L
955 SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
957 SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
958 psk_tls_server_name_call_back);
960 SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
962 SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
963 psk_tls_server_name_call_back);
966 SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
967 psk_tls_client_hello_call_back,
970 SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
971 psk_tls_client_hello_call_back,
977 if (!o_context->dtls.ssl) {
979 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
980 if (!o_context->dtls.ssl)
982 bio = BIO_new(o_context->dtls.meth);
984 SSL_free(o_context->dtls.ssl);
985 o_context->dtls.ssl = NULL;
988 SSL_set_bio(o_context->dtls.ssl, bio, bio);
989 SSL_set_app_data(o_context->dtls.ssl, NULL);
990 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
993 o_context->psk_pki_enabled |= IS_PSK;
998#if COAP_CLIENT_SUPPORT
1003 coap_openssl_context_t *o_context =
1007 if (!setup_data || !o_context)
1010 if (!o_context->dtls.ssl) {
1012 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
1013 if (!o_context->dtls.ssl)
1015 bio = BIO_new(o_context->dtls.meth);
1017 SSL_free(o_context->dtls.ssl);
1018 o_context->dtls.ssl = NULL;
1021 SSL_set_bio(o_context->dtls.ssl, bio, bio);
1022 SSL_set_app_data(o_context->dtls.ssl, NULL);
1023 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1026 o_context->psk_pki_enabled |= IS_PSK;
1032map_key_type(
int asn1_private_key_type
1034 switch (asn1_private_key_type) {
1036 return EVP_PKEY_NONE;
1038 return EVP_PKEY_RSA;
1040 return EVP_PKEY_RSA2;
1042 return EVP_PKEY_DSA;
1044 return EVP_PKEY_DSA1;
1046 return EVP_PKEY_DSA2;
1048 return EVP_PKEY_DSA3;
1050 return EVP_PKEY_DSA4;
1054 return EVP_PKEY_DHX;
1058 return EVP_PKEY_HMAC;
1060 return EVP_PKEY_CMAC;
1062 return EVP_PKEY_TLS1_PRF;
1064 return EVP_PKEY_HKDF;
1066 coap_log_warn(
"*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
1067 asn1_private_key_type);
1072#if !COAP_DISABLE_TCP
1073static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
1075#if COAP_SERVER_SUPPORT
1078 const unsigned char **out,
1079 unsigned char *outlen,
1080 const unsigned char *in,
1084 unsigned char *tout = NULL;
1087 return SSL_TLSEXT_ERR_NOACK;
1088 ret = SSL_select_next_proto(&tout,
1095 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
1101add_ca_to_cert_store(X509_STORE *st, X509 *x509) {
1105 while ((e = ERR_get_error()) != 0) {
1108 if (!X509_STORE_add_cert(st, x509)) {
1109 while ((e = ERR_get_error()) != 0) {
1110 int r = ERR_GET_REASON(e);
1111 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
1114 ERR_reason_error_string(e),
1115 ssl_function_definition(e));
1122missing_ENGINE_load_cert(
const char *cert_id) {
1124 const char *cert_id;
1128 params.cert_id = cert_id;
1132 if (!ENGINE_ctrl_cmd(ssl_engine,
"LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
1138#if OPENSSL_VERSION_NUMBER < 0x10101000L && COAP_SERVER_SUPPORT
1140setup_pki_server(SSL_CTX *ctx,
1147 if (!(SSL_CTX_use_certificate_file(ctx,
1149 SSL_FILETYPE_PEM))) {
1150 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1151 "Server Certificate\n",
1156 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1162 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1164 SSL_FILETYPE_PEM))) {
1165 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1166 "Server Private Key\n",
1171 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1177 STACK_OF(X509_NAME) *cert_names;
1181 char *rw_var = NULL;
1183 if (cert_names != NULL)
1184 SSL_CTX_set_client_CA_list(ctx, cert_names);
1186 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1193 st = SSL_CTX_get_cert_store(ctx);
1194 in = BIO_new(BIO_s_file());
1197 if (!BIO_read_filename(in, rw_var)) {
1204 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
1206 add_ca_to_cert_store(st, x);
1218 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1220 if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
1222 "Server PEM Certificate\n");
1234 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1242 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1244 if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
1246 "Server PEM Private Key\n");
1250 EVP_PKEY_free(pkey);
1256 EVP_PKEY_free(pkey);
1258 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1269 st = SSL_CTX_get_cert_store(ctx);
1272 if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
1274 add_ca_to_cert_store(st, x);
1275 SSL_CTX_add_client_CA(ctx, x);
1286 if (!(SSL_CTX_use_certificate_ASN1(ctx,
1289 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1290 "Server Certificate\n",
1295 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1302 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
1305 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1306 "Server Private Key\n",
1311 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1321 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1322 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1329 st = SSL_CTX_get_cert_store(ctx);
1330 add_ca_to_cert_store(st, x509);
1337 ssl_engine = ENGINE_by_id(
"pkcs11");
1339 coap_log_err(
"*** setup_pki: (D)TLS: No PKCS11 support\nn");
1342 if (!ENGINE_init(ssl_engine)) {
1344 ENGINE_free(ssl_engine);
1346 coap_log_err(
"*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1353 if (ENGINE_ctrl_cmd_string(ssl_engine,
"PIN",
1355 coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1364 "pkcs11:", 7) == 0) {
1365 EVP_PKEY *pkey = ENGINE_load_private_key(ssl_engine,
1371 "Server Private Key\n",
1375 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1376 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1377 "Server Private Key\n",
1379 EVP_PKEY_free(pkey);
1382 EVP_PKEY_free(pkey);
1384 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1386 SSL_FILETYPE_ASN1))) {
1387 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1388 "Server Private Key\n",
1394 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1401 "pkcs11:", 7) == 0) {
1404 x509 = missing_ENGINE_load_cert(
1408 "Server Certificate\n",
1412 if (!SSL_CTX_use_certificate(ctx, x509)) {
1413 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1414 "Server Certificate\n",
1421 if (!(SSL_CTX_use_certificate_file(ctx,
1423 SSL_FILETYPE_ASN1))) {
1424 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1425 "Server Certificate\n",
1431 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1442 x509 = missing_ENGINE_load_cert(
1446 "Server CA Certificate\n",
1450 if (!SSL_CTX_add_client_CA(ctx, x509)) {
1451 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1457 st = SSL_CTX_get_cert_store(ctx);
1458 add_ca_to_cert_store(st, x509);
1462 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1464 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1465 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1472 st = SSL_CTX_get_cert_store(ctx);
1473 add_ca_to_cert_store(st, x509);
1480 coap_log_err(
"*** setup_pki: (D)TLS: Unknown key type %d\n",
1489#if OPENSSL_VERSION_NUMBER >= 0x10101000L || COAP_CLIENT_SUPPORT
1491setup_pki_ssl(SSL *ssl,
1495 coap_log_err(
"RPK Support not available in OpenSSL\n");
1502 if (!(SSL_use_certificate_file(ssl,
1504 SSL_FILETYPE_PEM))) {
1505 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1514 coap_log_err(
"*** setup_pki: (D)TLS: No %s Certificate defined\n",
1520 if (!(SSL_use_PrivateKey_file(ssl,
1522 SSL_FILETYPE_PEM))) {
1523 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1524 "Client Private Key\n",
1531 coap_log_err(
"*** setup_pki: (D)TLS: No %s Private Key defined\n",
1540 char *rw_var = NULL;
1541 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1544 STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(setup_data->
pki_key.
key.
pem.
ca_file);
1546 if (cert_names != NULL)
1547 SSL_set_client_CA_list(ssl, cert_names);
1549 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1558 in = BIO_new(BIO_s_file());
1561 if (!BIO_read_filename(in, rw_var)) {
1565 st = SSL_CTX_get_cert_store(ctx);
1567 if ((x = PEM_read_bio_X509(in, NULL, NULL, NULL)) == NULL)
1569 add_ca_to_cert_store(st, x);
1581 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1583 if (!cert || !SSL_use_certificate(ssl, cert)) {
1585 "Server PEM Certificate\n");
1597 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1605 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1607 if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
1609 "Server PEM Private Key\n");
1613 EVP_PKEY_free(pkey);
1619 EVP_PKEY_free(pkey);
1621 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1629 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1631 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
1635 if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
1637 add_ca_to_cert_store(st, x);
1638 SSL_add_client_CA(ssl, x);
1649 if (!(SSL_use_certificate_ASN1(ssl,
1652 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1661 coap_log_err(
"*** setup_pki: (D)TLS: No %s Certificate defined\n",
1668 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
1671 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1680 coap_log_err(
"*** setup_pki: (D)TLS: No %s Private Key defined",
1690 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1693 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1694 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1703 st = SSL_CTX_get_cert_store(ctx);
1704 add_ca_to_cert_store(st, x509);
1711 ssl_engine = ENGINE_by_id(
"pkcs11");
1713 coap_log_err(
"*** setup_pki: (D)TLS: No PKCS11 support - need OpenSSL pkcs11 engine\n");
1716 if (!ENGINE_init(ssl_engine)) {
1718 ENGINE_free(ssl_engine);
1720 coap_log_err(
"*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1727 if (ENGINE_ctrl_cmd_string(ssl_engine,
1730 coap_log_warn(
"*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1739 "pkcs11:", 7) == 0) {
1740 EVP_PKEY *pkey = ENGINE_load_private_key(ssl_engine,
1751 if (!SSL_use_PrivateKey(ssl, pkey)) {
1752 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1756 EVP_PKEY_free(pkey);
1759 EVP_PKEY_free(pkey);
1761 if (!(SSL_use_PrivateKey_file(ssl,
1763 SSL_FILETYPE_ASN1))) {
1764 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1772 coap_log_err(
"*** setup_pki: (D)TLS: No Server Private Key defined\n");
1779 "pkcs11:", 7) == 0) {
1782 x509 = missing_ENGINE_load_cert(
1791 if (!SSL_use_certificate(ssl, x509)) {
1792 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1801 if (!(SSL_use_certificate_file(ssl,
1803 SSL_FILETYPE_ASN1))) {
1804 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1812 coap_log_err(
"*** setup_pki: (D)TLS: No Server Certificate defined\n");
1822 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1826 "%s CA Certificate (no ctx)\n",
1832 x509 = missing_ENGINE_load_cert(
1836 "%s CA Certificate\n",
1841 if (!SSL_add_client_CA(ssl, x509)) {
1842 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1843 "%s CA Certificate\n",
1849 st = ctx ? SSL_CTX_get_cert_store(ctx) : NULL;
1851 add_ca_to_cert_store(st, x509);
1855 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1856 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1858 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1859 coap_log_warn(
"*** setup_pki: (D)TLS: %s: Unable to configure "
1867 st = ctx ? SSL_CTX_get_cert_store(ctx) : NULL;
1869 add_ca_to_cert_store(st, x509);
1876 coap_log_err(
"*** setup_pki: (D)TLS: Unknown key type %d\n",
1885get_san_or_cn_from_cert(X509 *x509) {
1889 STACK_OF(GENERAL_NAME) *san_list;
1892 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1894 int san_count = sk_GENERAL_NAME_num(san_list);
1896 for (n = 0; n < san_count; n++) {
1897 const GENERAL_NAME *name = sk_GENERAL_NAME_value(san_list, n);
1899 if (name && name->type == GEN_DNS) {
1900 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1903 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen(dns_name))
1905 cn = OPENSSL_strdup(dns_name);
1906 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1910 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1913 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
1916 n = (int)strlen(buffer) - 3;
1919 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1920 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1929 char *ecn = strchr(cn,
'/');
1931 return OPENSSL_strndup(cn, ecn-cn);
1933 return OPENSSL_strdup(cn);
1941tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1942 int index = SSL_get_ex_data_X509_STORE_CTX_idx();
1943 SSL *ssl = index >= 0 ? X509_STORE_CTX_get_ex_data(ctx, index) : NULL;
1945 coap_openssl_context_t *context = (session && session->
context) ?
1948 int depth = X509_STORE_CTX_get_error_depth(ctx);
1949 int err = X509_STORE_CTX_get_error(ctx);
1950 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1951 char *cn = x509 ? get_san_or_cn_from_cert(x509) : NULL;
1952 int keep_preverify_ok = preverify_ok;
1955 X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
1959 if (!preverify_ok) {
1961 case X509_V_ERR_CERT_NOT_YET_VALID:
1962 case X509_V_ERR_CERT_HAS_EXPIRED:
1966 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1970 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1974 case X509_V_ERR_UNABLE_TO_GET_CRL:
1978 case X509_V_ERR_CRL_NOT_YET_VALID:
1979 case X509_V_ERR_CRL_HAS_EXPIRED:
1983 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1984 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1985 case X509_V_ERR_AKID_SKID_MISMATCH:
1995 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1996 X509_STORE_CTX_set_error(ctx, err);
1998 if (!preverify_ok) {
1999 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
2002 "Unknown CA", cn ? cn :
"?", depth);
2006 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
2011 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
2016 int length = i2d_X509(x509, NULL);
2018 uint8_t *base_buf2 = base_buf = length > 0 ? OPENSSL_malloc(length) : NULL;
2022 i2d_X509(x509, &base_buf2);
2024 depth, preverify_ok,
2027 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
2029 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
2033 OPENSSL_free(base_buf);
2035 X509_STORE_CTX_set_error(ctx, X509_V_ERR_UNSPECIFIED);
2040 return preverify_ok;
2043#if COAP_SERVER_SUPPORT
2044#if OPENSSL_VERSION_NUMBER < 0x10101000L
2053tls_secret_call_back(SSL *ssl,
2056 STACK_OF(SSL_CIPHER) *peer_ciphers,
2061 int psk_requested = 0;
2066 assert(session != NULL);
2067 assert(session->
context != NULL);
2068 if (session == NULL ||
2076 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2077 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2080 SSL_CIPHER_get_name(peer_cipher));
2081 if (strstr(SSL_CIPHER_get_name(peer_cipher),
"PSK")) {
2087 if (!psk_requested) {
2094 SSL_VERIFY_CLIENT_ONCE |
2095 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2096 tls_verify_call_back);
2098 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2107 X509_VERIFY_PARAM *param;
2109 param = X509_VERIFY_PARAM_new();
2110 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2111 SSL_set1_param(ssl, param);
2112 X509_VERIFY_PARAM_free(param);
2134 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2135 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2149tls_server_name_call_back(SSL *ssl,
2156 return SSL_TLSEXT_ERR_NOACK;
2162 coap_openssl_context_t *context =
2164 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2167 if (!sni || !sni[0]) {
2170 for (i = 0; i < context->sni_count; i++) {
2171 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2175 if (i == context->sni_count) {
2181 return SSL_TLSEXT_ERR_ALERT_FATAL;
2186 ctx = SSL_CTX_new(DTLS_method());
2189 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2190 SSL_CTX_set_app_data(ctx, &context->dtls);
2191 SSL_CTX_set_read_ahead(ctx, 1);
2192 coap_set_user_prefs(ctx);
2193 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2194 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2195 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2196 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2198#if !COAP_DISABLE_TCP
2201 ctx = SSL_CTX_new(TLS_method());
2204 SSL_CTX_set_app_data(ctx, &context->tls);
2205 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2206 coap_set_user_prefs(ctx);
2207 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2208 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2211 sni_setup_data = *setup_data;
2212 sni_setup_data.
pki_key = *new_entry;
2213 setup_pki_server(ctx, &sni_setup_data);
2215 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2216 (context->sni_count+1)*
sizeof(sni_entry));
2217 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2218 context->sni_entry_list[context->sni_count].ctx = ctx;
2219 context->sni_count++;
2221 SSL_set_SSL_CTX(ssl, context->sni_entry_list[i].ctx);
2222 SSL_clear_options(ssl, 0xFFFFFFFFL);
2223 SSL_set_options(ssl, SSL_CTX_get_options(context->sni_entry_list[i].ctx));
2230 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2231 return SSL_TLSEXT_ERR_OK;
2234 return SSL_TLSEXT_ERR_ALERT_WARNING;
2245psk_tls_server_name_call_back(SSL *ssl,
2252 return SSL_TLSEXT_ERR_NOACK;
2258 coap_openssl_context_t *o_context = (c_session && c_session->
context) ?
2260 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2265 return SSL_TLSEXT_ERR_ALERT_FATAL;
2267 if (!sni || !sni[0]) {
2270 for (i = 0; i < o_context->psk_sni_count; i++) {
2271 if (!strcasecmp(sni, (
char *)o_context->psk_sni_entry_list[i].sni)) {
2275 if (i == o_context->psk_sni_count) {
2282 return SSL_TLSEXT_ERR_ALERT_FATAL;
2287 ctx = SSL_CTX_new(DTLS_method());
2290 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2291 SSL_CTX_set_app_data(ctx, &o_context->dtls);
2292 SSL_CTX_set_read_ahead(ctx, 1);
2293 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2294 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2295 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2296 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2297 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2299#if !COAP_DISABLE_TCP
2302 ctx = SSL_CTX_new(TLS_method());
2305 SSL_CTX_set_app_data(ctx, &o_context->tls);
2306 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2307 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2308 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2309 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2313 o_context->psk_sni_entry_list =
2314 OPENSSL_realloc(o_context->psk_sni_entry_list,
2315 (o_context->psk_sni_count+1)*
sizeof(psk_sni_entry));
2316 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2317 OPENSSL_strdup(sni);
2318 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2320 o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
2322 o_context->psk_sni_count++;
2324 SSL_set_SSL_CTX(ssl, o_context->psk_sni_entry_list[i].ctx);
2325 SSL_clear_options(ssl, 0xFFFFFFFFL);
2326 SSL_set_options(ssl,
2327 SSL_CTX_get_options(o_context->psk_sni_entry_list[i].ctx));
2329 &o_context->psk_sni_entry_list[i].psk_info.key);
2330 snprintf(lhint,
sizeof(lhint),
"%.*s",
2331 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2332 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2333 SSL_use_psk_identity_hint(ssl, lhint);
2340 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2341 return SSL_TLSEXT_ERR_OK;
2344 return SSL_TLSEXT_ERR_ALERT_WARNING;
2356tls_client_hello_call_back(SSL *ssl,
2361 coap_openssl_context_t *dtls_context;
2363 int psk_requested = 0;
2364 const unsigned char *out;
2368 *al = SSL_AD_INTERNAL_ERROR;
2369 return SSL_CLIENT_HELLO_ERROR;
2372 assert(session != NULL);
2373 assert(session->
context != NULL);
2375 if (session == NULL ||
2378 *al = SSL_AD_INTERNAL_ERROR;
2379 return SSL_CLIENT_HELLO_ERROR;
2382 setup_data = &dtls_context->setup_data;
2390 size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
2391 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
2392 STACK_OF(SSL_CIPHER) *scsvc = NULL;
2394 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
2395 SSL_client_hello_isv2(ssl),
2396 &peer_ciphers, &scsvc)) {
2398 for (ii = 0; ii < sk_SSL_CIPHER_num(peer_ciphers); ii++) {
2399 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2402 "Client cipher: %s (%04x)\n",
2403 SSL_CIPHER_get_name(peer_cipher),
2404 SSL_CIPHER_get_protocol_id(peer_cipher));
2405 if (strstr(SSL_CIPHER_get_name(peer_cipher),
"PSK")) {
2411 sk_SSL_CIPHER_free(peer_ciphers);
2412 sk_SSL_CIPHER_free(scsvc);
2415 if (psk_requested) {
2421 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2427 return SSL_CLIENT_HELLO_SUCCESS;
2437 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
2440 for (ii = 0; ii < outlen; ii++) {
2456 *al = SSL_AD_UNSUPPORTED_EXTENSION;
2457 return SSL_CLIENT_HELLO_ERROR;
2466 coap_openssl_context_t *context =
2468 const char *sni =
"";
2469 char *sni_tmp = NULL;
2472 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2474 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2475 out[2] == TLSEXT_NAMETYPE_host_name &&
2476 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2480 sni_tmp = OPENSSL_malloc(outlen+1);
2481 sni_tmp[outlen] =
'\000';
2482 memcpy(sni_tmp, out, outlen);
2486 for (i = 0; i < context->sni_count; i++) {
2487 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2491 if (i == context->sni_count) {
2498 *al = SSL_AD_UNRECOGNIZED_NAME;
2499 return SSL_CLIENT_HELLO_ERROR;
2503 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2504 (context->sni_count+1)*
sizeof(sni_entry));
2505 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2506 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
2507 context->sni_count++;
2510 OPENSSL_free(sni_tmp);
2512 sni_setup_data = *setup_data;
2513 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
2525 SSL_VERIFY_CLIENT_ONCE |
2526 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2527 tls_verify_call_back);
2529 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2538 X509_VERIFY_PARAM *param;
2540 param = X509_VERIFY_PARAM_new();
2541 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2542 SSL_set1_param(ssl, param);
2543 X509_VERIFY_PARAM_free(param);
2550 return SSL_CLIENT_HELLO_SUCCESS;
2561psk_tls_client_hello_call_back(SSL *ssl,
2566 coap_openssl_context_t *o_context;
2568 const unsigned char *out;
2574 if (!c_session || !c_session->
context) {
2587 const char *sni =
"";
2588 char *sni_tmp = NULL;
2592 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2594 (((out[0]<<8) + out[1] +2) == (
int)outlen) &&
2595 out[2] == TLSEXT_NAMETYPE_host_name &&
2596 (((out[3]<<8) + out[4] +2 +3) == (
int)outlen)) {
2600 sni_tmp = OPENSSL_malloc(outlen+1);
2602 sni_tmp[outlen] =
'\000';
2603 memcpy(sni_tmp, out, outlen);
2609 for (i = 0; i < o_context->psk_sni_count; i++) {
2610 if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
2614 if (i == o_context->psk_sni_count) {
2618 psk_sni_entry *tmp_entry;
2624 *al = SSL_AD_UNRECOGNIZED_NAME;
2625 return SSL_CLIENT_HELLO_ERROR;
2629 OPENSSL_realloc(o_context->psk_sni_entry_list,
2630 (o_context->psk_sni_count+1)*
sizeof(sni_entry));
2632 o_context->psk_sni_entry_list = tmp_entry;
2633 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2634 OPENSSL_strdup(sni);
2635 if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
2636 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2638 o_context->psk_sni_count++;
2643 OPENSSL_free(sni_tmp);
2646 &o_context->psk_sni_entry_list[i].psk_info.hint)
2651 &o_context->psk_sni_entry_list[i].psk_info.key)
2655 if (o_context->psk_sni_entry_list[i].psk_info.hint.s) {
2656 snprintf(lhint,
sizeof(lhint),
"%.*s",
2657 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2658 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2659 SSL_use_psk_identity_hint(ssl, lhint);
2662 return SSL_CLIENT_HELLO_SUCCESS;
2665 *al = SSL_AD_INTERNAL_ERROR;
2666 return SSL_CLIENT_HELLO_ERROR;
2676 coap_openssl_context_t *context =
2681 context->setup_data = *setup_data;
2682 if (!context->setup_data.verify_peer_cert) {
2684 context->setup_data.check_common_ca = 0;
2686 context->setup_data.allow_self_signed = 1;
2687 context->setup_data.allow_expired_certs = 1;
2688 context->setup_data.cert_chain_validation = 1;
2689 context->setup_data.cert_chain_verify_depth = 10;
2690 context->setup_data.check_cert_revocation = 1;
2691 context->setup_data.allow_no_crl = 1;
2692 context->setup_data.allow_expired_crl = 1;
2693 context->setup_data.allow_bad_md_hash = 1;
2694 context->setup_data.allow_short_rsa_length = 1;
2696#if COAP_SERVER_SUPPORT
2698 if (context->dtls.ctx) {
2700#if OPENSSL_VERSION_NUMBER < 0x10101000L
2701 if (!setup_pki_server(context->dtls.ctx, setup_data))
2710#if OPENSSL_VERSION_NUMBER < 0x10101000L
2711 if (SSLeay() >= 0x10101000L) {
2712 coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so "
2713 "no certificate checking\n",
2714 OPENSSL_VERSION_NUMBER, SSLeay());
2716 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
2717 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
2718 tls_server_name_call_back);
2720 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
2721 tls_client_hello_call_back,
2725#if !COAP_DISABLE_TCP
2726 if (context->tls.ctx) {
2728#if OPENSSL_VERSION_NUMBER < 0x10101000L
2729 if (!setup_pki_server(context->tls.ctx, setup_data))
2738#if OPENSSL_VERSION_NUMBER < 0x10101000L
2739 if (SSLeay() >= 0x10101000L) {
2740 coap_log_warn(
"OpenSSL compiled with %lux, linked with %lux, so "
2741 "no certificate checking\n",
2742 OPENSSL_VERSION_NUMBER, SSLeay());
2744 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
2745 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
2746 tls_server_name_call_back);
2748 SSL_CTX_set_client_hello_cb(context->tls.ctx,
2749 tls_client_hello_call_back,
2753 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
2761 if (!context->dtls.ssl) {
2763 context->dtls.ssl = SSL_new(context->dtls.ctx);
2764 if (!context->dtls.ssl)
2766 bio = BIO_new(context->dtls.meth);
2768 SSL_free(context->dtls.ssl);
2769 context->dtls.ssl = NULL;
2772 SSL_set_bio(context->dtls.ssl, bio, bio);
2773 SSL_set_app_data(context->dtls.ssl, NULL);
2774 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
2777 context->psk_pki_enabled |= IS_PKI;
2783 const char *ca_file,
2786 coap_openssl_context_t *context =
2788 if (context->dtls.ctx) {
2789 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
2791 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2795#if !COAP_DISABLE_TCP
2796 if (context->tls.ctx) {
2797 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
2799 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2809 coap_openssl_context_t *context =
2811 return context->psk_pki_enabled ? 1 : 0;
2818 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
2820 if (context->dtls.ssl)
2821 SSL_free(context->dtls.ssl);
2822 if (context->dtls.ctx)
2823 SSL_CTX_free(context->dtls.ctx);
2824 if (context->dtls.cookie_hmac)
2825 HMAC_CTX_free(context->dtls.cookie_hmac);
2826 if (context->dtls.meth)
2827 BIO_meth_free(context->dtls.meth);
2828 if (context->dtls.bio_addr)
2829 BIO_ADDR_free(context->dtls.bio_addr);
2830#if !COAP_DISABLE_TCP
2831 if (context->tls.ctx)
2832 SSL_CTX_free(context->tls.ctx);
2833 if (context->tls.meth)
2834 BIO_meth_free(context->tls.meth);
2836 for (i = 0; i < context->sni_count; i++) {
2837 OPENSSL_free(context->sni_entry_list[i].sni);
2838#if OPENSSL_VERSION_NUMBER < 0x10101000L
2839 SSL_CTX_free(context->sni_entry_list[i].ctx);
2842 if (context->sni_count)
2843 OPENSSL_free(context->sni_entry_list);
2844 for (i = 0; i < context->psk_sni_count; i++) {
2845 OPENSSL_free((
char *)context->psk_sni_entry_list[i].sni);
2846#if OPENSSL_VERSION_NUMBER < 0x10101000L
2847 SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
2850 if (context->psk_sni_count)
2851 OPENSSL_free(context->psk_sni_entry_list);
2855#if COAP_SERVER_SUPPORT
2859 SSL *nssl = NULL, *ssl = NULL;
2860 coap_ssl_data *data;
2861 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
2866 nssl = SSL_new(dtls->ctx);
2869 nbio = BIO_new(dtls->meth);
2872 SSL_set_bio(nssl, nbio, nbio);
2873 SSL_set_app_data(nssl, NULL);
2874 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
2875 SSL_set_mtu(nssl, (
long)session->
mtu);
2879 SSL_set_app_data(ssl, session);
2881 rbio = SSL_get_rbio(ssl);
2882 data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
2885 data->session = session;
2889 if (psk_hint != NULL && psk_hint->
length) {
2890 char *hint = OPENSSL_malloc(psk_hint->
length + 1);
2893 memcpy(hint, psk_hint->
s, psk_hint->
length);
2894 hint[psk_hint->
length] =
'\000';
2895 SSL_use_psk_identity_hint(ssl, hint);
2902 r = SSL_accept(ssl);
2904 int err = SSL_get_error(ssl, r);
2905 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2923#if COAP_CLIENT_SUPPORT
2927 coap_openssl_context_t *context =
2930 if (context->psk_pki_enabled & IS_PSK) {
2935 SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
2939 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
2940#if COAP_SERVER_SUPPORT
2941 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2943 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2946 SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
2948#if !COAP_DISABLE_TCP
2950 SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
2953 coap_log_debug(
"CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
2956 if (context->psk_pki_enabled & IS_PKI) {
2961#if !COAP_DISABLE_TCP
2963 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
2968 SSL_set_tlsext_host_name(ssl, setup_data->
client_sni) != 1) {
2974 X509_VERIFY_PARAM *param;
2976 param = X509_VERIFY_PARAM_new();
2977 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2978 SSL_set1_param(ssl, param);
2979 X509_VERIFY_PARAM_free(param);
2986 SSL_VERIFY_CLIENT_ONCE |
2987 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2988 tls_verify_call_back);
2990 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
3004 coap_ssl_data *data;
3006 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3007 coap_dtls_context_t *dtls = &context->dtls;
3009 ssl = SSL_new(dtls->ctx);
3012 bio = BIO_new(dtls->meth);
3015 data = (coap_ssl_data *)BIO_get_data(bio);
3018 data->session = session;
3019 SSL_set_bio(ssl, bio, bio);
3020 SSL_set_app_data(ssl, session);
3021 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
3022 SSL_set_mtu(ssl, (
long)session->
mtu);
3024 if (!setup_client_ssl_session(session, ssl))
3029 r = SSL_connect(ssl);
3031 int ret = SSL_get_error(ssl, r);
3032 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3050 SSL *ssl = (SSL *)session->
tls;
3052 SSL_set_mtu(ssl, (
long)session->
mtu);
3058 SSL *ssl = (SSL *)session->
tls;
3060 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3061 int r = SSL_shutdown(ssl);
3063 r = SSL_shutdown(ssl);
3066 session->
tls = NULL;
3074 const uint8_t *data,
size_t data_len) {
3076 SSL *ssl = (SSL *)session->
tls;
3078 assert(ssl != NULL);
3081 r = SSL_write(ssl, data, (
int)data_len);
3084 int err = SSL_get_error(ssl, r);
3085 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3089 if (err == SSL_ERROR_ZERO_RETURN)
3091 else if (err == SSL_ERROR_SSL)
3109 if (r == (ssize_t)data_len)
3132 SSL *ssl = (SSL *)session->
tls;
3133 coap_ssl_data *ssl_data;
3137 rbio = ssl ? SSL_get_rbio(ssl) : NULL;
3138 ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3139 return ssl_data ? ssl_data->timeout : 1000;
3148 SSL *ssl = (SSL *)session->
tls;
3152 (DTLSv1_handle_timeout(ssl) < 0)) {
3160#if COAP_SERVER_SUPPORT
3163 const uint8_t *data,
size_t data_len) {
3164 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
3165 coap_ssl_data *ssl_data;
3169 SSL_set_mtu(dtls->ssl, (
long)session->
mtu);
3170 rbio = dtls->ssl ? SSL_get_rbio(dtls->ssl) : NULL;
3171 ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3172 assert(ssl_data != NULL);
3177 if (ssl_data->pdu_len) {
3178 coap_log_err(
"** %s: Previous data not read %u bytes\n",
3181 ssl_data->session = session;
3182 ssl_data->pdu = data;
3183 ssl_data->pdu_len = (unsigned)data_len;
3184 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
3186 int err = SSL_get_error(dtls->ssl, r);
3187 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3207 coap_ssl_data *ssl_data;
3208 SSL *ssl = (SSL *)session->
tls;
3212 assert(ssl != NULL);
3214 int in_init = SSL_in_init(ssl);
3216 rbio = ssl ? SSL_get_rbio(ssl) : NULL;
3217 ssl_data = rbio ? (coap_ssl_data *)BIO_get_data(rbio) : NULL;
3218 assert(ssl_data != NULL);
3224 if (ssl_data->pdu_len) {
3225 coap_log_err(
"** %s: Previous data not read %u bytes\n",
3228 ssl_data->pdu = data;
3229 ssl_data->pdu_len = (unsigned)data_len;
3232 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
3237 int err = SSL_get_error(ssl, r);
3238 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3239 if (in_init && SSL_is_init_finished(ssl)) {
3247 if (err == SSL_ERROR_ZERO_RETURN)
3249 else if (err == SSL_ERROR_SSL)
3267 if (ssl_data && ssl_data->pdu_len) {
3269 coap_log_debug(
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
3270 ssl_data->pdu_len = 0;
3271 ssl_data->pdu = NULL;
3282 unsigned int overhead = 37;
3283 const SSL_CIPHER *s_ciph = NULL;
3284 if (session->
tls != NULL)
3285 s_ciph = SSL_get_current_cipher(session->
tls);
3287 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
3289 const EVP_CIPHER *e_ciph;
3293 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
3295 switch (EVP_CIPHER_mode(e_ciph)) {
3296 case EVP_CIPH_GCM_MODE:
3297 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
3298 maclen = EVP_GCM_TLS_TAG_LEN;
3301 case EVP_CIPH_CCM_MODE:
3302 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
3303 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3304 if (strstr(cipher,
"CCM8"))
3310 case EVP_CIPH_CBC_MODE:
3311 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
3312 blocksize = EVP_CIPHER_block_size(e_ciph);
3313 ivlen = EVP_CIPHER_iv_length(e_ciph);
3315 maclen = EVP_MD_size(e_md);
3318 case EVP_CIPH_STREAM_CIPHER:
3325 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3332 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
3337#if !COAP_DISABLE_TCP
3338#if COAP_CLIENT_SUPPORT
3344 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3345 coap_tls_context_t *tls = &context->tls;
3347 ssl = SSL_new(tls->ctx);
3350 bio = BIO_new(tls->meth);
3353 BIO_set_data(bio, session);
3354 SSL_set_bio(ssl, bio, bio);
3355 SSL_set_app_data(ssl, session);
3357 if (!setup_client_ssl_session(session, ssl))
3360 r = SSL_connect(ssl);
3362 int ret = SSL_get_error(ssl, r);
3363 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3365 if (ret == SSL_ERROR_WANT_READ)
3367 if (ret == SSL_ERROR_WANT_WRITE) {
3369#ifdef COAP_EPOLL_SUPPORT
3383 if (SSL_is_init_finished(ssl)) {
3397#if COAP_SERVER_SUPPORT
3402 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
3406 ssl = SSL_new(tls->ctx);
3409 bio = BIO_new(tls->meth);
3412 BIO_set_data(bio, session);
3413 SSL_set_bio(ssl, bio, bio);
3414 SSL_set_app_data(ssl, session);
3417 if (psk_hint != NULL && psk_hint->
length) {
3418 char *hint = OPENSSL_malloc(psk_hint->
length + 1);
3421 memcpy(hint, psk_hint->
s, psk_hint->
length);
3422 hint[psk_hint->
length] =
'\000';
3423 SSL_use_psk_identity_hint(ssl, hint);
3430 r = SSL_accept(ssl);
3432 int err = SSL_get_error(ssl, r);
3433 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3435 if (err == SSL_ERROR_WANT_READ)
3437 if (err == SSL_ERROR_WANT_WRITE) {
3439#ifdef COAP_EPOLL_SUPPORT
3453 if (SSL_is_init_finished(ssl)) {
3469 SSL *ssl = (SSL *)session->
tls;
3471 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3472 int r = SSL_shutdown(ssl);
3474 r = SSL_shutdown(ssl);
3477 session->
tls = NULL;
3490 SSL *ssl = (SSL *)session->
tls;
3496 in_init = !SSL_is_init_finished(ssl);
3498 r = SSL_write(ssl, data, (
int)data_len);
3501 int err = SSL_get_error(ssl, r);
3502 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3503 if (in_init && SSL_is_init_finished(ssl)) {
3509 if (err == SSL_ERROR_WANT_READ)
3511 else if (err == SSL_ERROR_WANT_WRITE) {
3513#ifdef COAP_EPOLL_SUPPORT
3525 if (err == SSL_ERROR_ZERO_RETURN)
3527 else if (err == SSL_ERROR_SSL)
3531 }
else if (in_init && SSL_is_init_finished(ssl)) {
3550 if (r == (ssize_t)data_len)
3567 SSL *ssl = (SSL *)session->
tls;
3575 in_init = !SSL_is_init_finished(ssl);
3577 r = SSL_read(ssl, data, (
int)data_len);
3579 int err = SSL_get_error(ssl, r);
3580 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3581 if (in_init && SSL_is_init_finished(ssl)) {
3587 if (err == SSL_ERROR_WANT_READ)
3589 if (err == SSL_ERROR_WANT_WRITE) {
3591#ifdef COAP_EPOLL_SUPPORT
3601 if (err == SSL_ERROR_ZERO_RETURN)
3603 else if (err == SSL_ERROR_SSL)
3607 }
else if (in_init && SSL_is_init_finished(ssl)) {
3633#if COAP_SERVER_SUPPORT
3636 EVP_MD_CTX *digest_ctx = EVP_MD_CTX_new();
3639 EVP_DigestInit_ex(digest_ctx, EVP_sha256(), NULL);
3646 EVP_MD_CTX_free(digest_ctx);
3651 const uint8_t *data,
3653 return EVP_DigestUpdate(digest_ctx, data, data_len);
3660 int ret = EVP_DigestFinal_ex(digest_ctx, (uint8_t *)digest_buffer, &size);
3667#if COAP_WS_SUPPORT || COAP_OSCORE_SUPPORT
3669coap_crypto_output_errors(
const char *prefix) {
3670#if COAP_MAX_LOGGING_LEVEL < _COAP_LOG_WARN
3675 while ((e = ERR_get_error()))
3678 ERR_reason_error_string(e),
3679 ssl_function_definition(e));
3689static struct hash_algs {
3691 const EVP_MD *(*get_hash)(void);
3700static const EVP_MD *
3701get_hash_alg(
cose_alg_t alg,
size_t *length) {
3704 for (idx = 0; idx <
sizeof(hashs) /
sizeof(
struct hash_algs); idx++) {
3705 if (hashs[idx].alg == alg) {
3706 *length = hashs[idx].length;
3707 return hashs[idx].get_hash();
3710 coap_log_debug(
"get_hash_alg: COSE hash %d not supported\n", alg);
3718 unsigned int length;
3719 const EVP_MD *evp_md;
3720 EVP_MD_CTX *evp_ctx = NULL;
3724 if ((evp_md = get_hash_alg(alg, &hash_length)) == NULL) {
3725 coap_log_debug(
"coap_crypto_hash: algorithm %d not supported\n", alg);
3728 evp_ctx = EVP_MD_CTX_new();
3729 if (evp_ctx == NULL)
3731 if (EVP_DigestInit_ex(evp_ctx, evp_md, NULL) == 0)
3734 if (EVP_DigestUpdate(evp_ctx, data->
s, data->
length) == 0)
3740 if (EVP_DigestFinal_ex(evp_ctx,
dummy->s, &length) == 0)
3742 dummy->length = length;
3743 if (hash_length < dummy->length)
3744 dummy->length = hash_length;
3746 EVP_MD_CTX_free(evp_ctx);
3750 coap_crypto_output_errors(
"coap_crypto_hash");
3753 EVP_MD_CTX_free(evp_ctx);
3758#if COAP_OSCORE_SUPPORT
3764#include <openssl/evp.h>
3765#include <openssl/hmac.h>
3772static struct cipher_algs {
3774 const EVP_CIPHER *(*get_cipher)(void);
3779static const EVP_CIPHER *
3783 for (idx = 0; idx <
sizeof(ciphers) /
sizeof(
struct cipher_algs); idx++) {
3784 if (ciphers[idx].alg == alg)
3785 return ciphers[idx].get_cipher();
3787 coap_log_debug(
"get_cipher_alg: COSE cipher %d not supported\n", alg);
3796static struct hmac_algs {
3798 const EVP_MD *(*get_hmac)(void);
3805static const EVP_MD *
3809 for (idx = 0; idx <
sizeof(hmacs) /
sizeof(
struct hmac_algs); idx++) {
3810 if (hmacs[idx].hmac_alg == hmac_alg)
3811 return hmacs[idx].get_hmac();
3813 coap_log_debug(
"get_hmac_alg: COSE HMAC %d not supported\n", hmac_alg);
3819 return get_cipher_alg(alg) != NULL;
3828 return get_hmac_alg(hmac_alg) != NULL;
3832 if (1 != (Func)) { \
3841 size_t *max_result_len) {
3842 const EVP_CIPHER *cipher;
3845 int result_len = (int)(*max_result_len & INT_MAX);
3850 assert(params != NULL);
3851 if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
3858 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
3861 C(EVP_EncryptInit_ex(ctx, cipher, NULL, NULL, NULL));
3862 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
3863 C(EVP_CIPHER_CTX_ctrl(ctx,
3864 EVP_CTRL_AEAD_SET_IVLEN,
3867 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, NULL));
3868 C(EVP_EncryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
3871 C(EVP_EncryptUpdate(ctx, NULL, &result_len, NULL, (
int)data->
length));
3872 if (aad && aad->
s && (aad->
length > 0)) {
3873 C(EVP_EncryptUpdate(ctx, NULL, &result_len, aad->
s, (
int)aad->
length));
3875 C(EVP_EncryptUpdate(ctx, result, &result_len, data->
s, (
int)data->
length));
3878 C(EVP_EncryptFinal_ex(ctx, result + result_len, &tmp));
3882 C(EVP_CIPHER_CTX_ctrl(ctx,
3883 EVP_CTRL_CCM_GET_TAG,
3885 result + result_len));
3887 *max_result_len = result_len + ccm->
tag_len;
3888 EVP_CIPHER_CTX_free(ctx);
3892 coap_crypto_output_errors(
"coap_crypto_aead_encrypt");
3901 size_t *max_result_len) {
3902 const EVP_CIPHER *cipher;
3912 assert(params != NULL);
3913 if (!params || ((cipher = get_cipher_alg(params->
alg)) == NULL)) {
3925 memcpy(&rwtag, &tag,
sizeof(rwtag));
3928 EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
3930 C(EVP_DecryptInit_ex(ctx, cipher, NULL, NULL, NULL));
3931 C(EVP_CIPHER_CTX_ctrl(ctx,
3932 EVP_CTRL_AEAD_SET_IVLEN,
3935 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (
int)ccm->
tag_len, rwtag));
3936 C(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_L, (
int)ccm->
l, NULL));
3938 C(EVP_DecryptInit_ex(ctx, NULL, NULL, ccm->
key.
s, ccm->
nonce));
3940 C(EVP_DecryptUpdate(ctx, NULL, &len, NULL, (
int)data->
length));
3941 if (aad && aad->
s && (aad->
length > 0)) {
3942 C(EVP_DecryptUpdate(ctx, NULL, &len, aad->
s, (
int)aad->
length));
3944 tmp = EVP_DecryptUpdate(ctx, result, &len, data->
s, (
int)data->
length);
3945 EVP_CIPHER_CTX_free(ctx);
3947 *max_result_len = 0;
3950 *max_result_len = len;
3954 coap_crypto_output_errors(
"coap_crypto_aead_decrypt");
3963 unsigned int result_len;
3964 const EVP_MD *evp_md;
3971 if ((evp_md = get_hmac_alg(hmac_alg)) == 0) {
3972 coap_log_debug(
"coap_crypto_hmac: algorithm %d not supported\n", hmac_alg);
3978 result_len = (
unsigned int)
dummy->length;
3986 dummy->length = result_len;
3991 coap_crypto_output_errors(
"coap_crypto_hmac");
4003#pragma GCC diagnostic ignored "-Wunused-function"
Pulls together all the internal only header files.
#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 ...
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)
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)
void coap_digest_free(coap_digest_ctx_t *digest_ctx)
Free off coap_digest_ctx_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.
int coap_crypto_hmac(cose_hmac_alg_t hmac_alg, coap_bin_const_t *key, coap_bin_const_t *data, coap_bin_const_t **hmac)
Create a HMAC hash of the provided data.
int coap_crypto_aead_decrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Decrypt the provided encrypted data into plaintext.
int coap_crypto_aead_encrypt(const coap_crypto_param_t *params, coap_bin_const_t *data, coap_bin_const_t *aad, uint8_t *result, size_t *max_result_len)
Encrypt the provided plaintext data.
int coap_crypto_hash(cose_alg_t alg, const coap_bin_const_t *data, coap_bin_const_t **hash)
Create a hash of the provided data.
int coap_crypto_check_hkdf_alg(cose_hkdf_alg_t hkdf_alg)
Check whether the defined hkdf algorithm is supported by the underlying crypto library.
int coap_crypto_check_cipher_alg(cose_alg_t alg)
Check whether the defined cipher algorithm is supported by the underlying crypto library.
void * coap_tls_new_server_session(coap_session_t *coap_session)
Create a TLS new server-side session.
const coap_bin_const_t * coap_get_session_client_psk_identity(const coap_session_t *session)
Get the current client's PSK identity.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
void * coap_dtls_new_client_session(coap_session_t *coap_session)
Create a new client-side session.
void * coap_dtls_new_server_session(coap_session_t *coap_session)
Create a new DTLS server-side session.
int coap_dtls_hello(coap_session_t *coap_session, const uint8_t *data, size_t data_len)
Handling client HELLO messages from a new candiate peer.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
int coap_dtls_context_set_cpsk(coap_context_t *coap_context, coap_dtls_cpsk_t *setup_data)
Set the DTLS context's default client PSK information.
int coap_dtls_context_set_spsk(coap_context_t *coap_context, coap_dtls_spsk_t *setup_data)
Set the DTLS context's default server PSK information.
void coap_dtls_shutdown(void)
Close down the underlying (D)TLS Library layer.
const coap_bin_const_t * coap_get_session_client_psk_key(const coap_session_t *coap_session)
Get the current client's PSK key.
void * coap_tls_new_client_session(coap_session_t *coap_session)
Create a new TLS client-side session.
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_dtls_psk_is_supported(void)
Check whether (D)TLS PSK is available.
int coap_tls_is_supported(void)
Check whether TLS is available.
int coap_dtls_is_supported(void)
Check whether DTLS is available.
int coap_dtls_pki_is_supported(void)
Check whether (D)TLS PKI is available.
int coap_dtls_rpk_is_supported(void)
Check whether (D)TLS RPK is available.
int coap_dtls_pkcs11_is_supported(void)
Check whether (D)TLS PKCS11 is available.
@ COAP_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.
#define coap_log_debug(...)
coap_log_t coap_dtls_get_log_level(void)
Get the current (D)TLS logging.
#define coap_dtls_log(level,...)
Logging function.
void coap_dtls_set_log_level(coap_log_t level)
Sets the (D)TLS logging level to the specified level.
const char * coap_session_str(const coap_session_t *session)
Get session description.
#define coap_log_info(...)
#define coap_log_warn(...)
#define coap_log_err(...)
#define coap_log(level,...)
Logging function.
int coap_netif_available(coap_session_t *session)
Function interface to check whether netif for session is still available.
int cose_get_hmac_alg_for_hkdf(cose_hkdf_alg_t hkdf_alg, cose_hmac_alg_t *hmac_alg)
@ COSE_HMAC_ALG_HMAC384_384
@ COSE_HMAC_ALG_HMAC256_256
@ COSE_HMAC_ALG_HMAC512_512
@ COSE_ALGORITHM_SHA_256_64
@ COSE_ALGORITHM_SHA_256_256
@ COSE_ALGORITHM_AES_CCM_16_64_128
@ COSE_ALGORITHM_AES_CCM_16_64_256
int coap_oscore_is_supported(void)
Check whether OSCORE is available.
int coap_session_refresh_psk_hint(coap_session_t *session, const coap_bin_const_t *psk_hint)
Refresh the session's current Identity Hint (PSK).
int coap_session_refresh_psk_key(coap_session_t *session, const coap_bin_const_t *psk_key)
Refresh the session's current pre-shared key (PSK).
int coap_session_refresh_psk_identity(coap_session_t *session, const coap_bin_const_t *psk_identity)
Refresh the session's current pre-shared identity (PSK).
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
@ COAP_SESSION_STATE_HANDSHAKE
coap_binary_t * coap_new_binary(size_t size)
Returns a new binary object with at least size bytes storage allocated.
void coap_delete_binary(coap_binary_t *s)
Deletes the given coap_binary_t object and releases any memory allocated.
CoAP binary data definition with const data.
size_t length
length of binary data
const uint8_t * s
read-only binary data
CoAP binary data definition.
The CoAP stack's global state is stored in a coap_context_t object.
coap_dtls_spsk_t spsk_setup_data
Contains the initial PSK server setup data.
The structure that holds the AES Crypto information.
size_t l
The number of bytes in the length field.
const uint8_t * nonce
must be exactly 15 - l bytes
coap_crypto_key_t key
The Key to use.
size_t tag_len
The size of the Tag.
The common structure that holds the Crypto information.
union coap_crypto_param_t::@2 params
coap_crypto_aes_ccm_t aes
Used if AES type encryption.
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_pem_t pem
for PEM file keys
coap_pki_key_pkcs11_t pkcs11
for PKCS11 keys
union coap_dtls_key_t::@3 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.
coap_layer_write_t l_write
coap_layer_establish_t l_establish
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 relationship with peer
coap_proto_t proto
protocol used
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
size_t mtu
path or CSM mtu (xmt)
int dtls_event
Tracking any (D)TLS events on this session.
void * tls
security parameters
uint16_t max_retransmit
maximum re-transmit count (default 4)
coap_context_t * context
session's context
coap_layer_func_t lfunc[COAP_LAYER_LAST]
Layer functions to use.
coap_socket_flags_t flags
1 or more of COAP_SOCKET* flag values
CoAP string data definition with const data.
const uint8_t * s
read-only string data
size_t length
length of string
The structure used for returning the underlying (D)TLS library information.
uint64_t built_version
(D)TLS Built against Library Version
coap_tls_library_t type
Library type.
uint64_t version
(D)TLS runtime Library Version