59 #include <openssl/ssl.h>
60 #include <openssl/engine.h>
61 #include <openssl/err.h>
62 #include <openssl/rand.h>
63 #include <openssl/hmac.h>
64 #include <openssl/x509v3.h>
66 #ifdef COAP_EPOLL_SUPPORT
67 # include <sys/epoll.h>
70 #if OPENSSL_VERSION_NUMBER < 0x10100000L
71 #error Must be compiled against OpenSSL 1.1.0 or later
75 #define UNUSED __attribute__((unused))
81 #define strcasecmp _stricmp
82 #define strncasecmp _strnicmp
86 #ifndef TLSEXT_TYPE_client_certificate_type
87 #define TLSEXT_TYPE_client_certificate_type 19
89 #ifndef TLSEXT_TYPE_server_certificate_type
90 #define TLSEXT_TYPE_server_certificate_type 20
93 #ifndef COAP_OPENSSL_CIPHERS
94 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
95 #define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL"
97 #define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL"
101 #ifndef COAP_OPENSSL_PSK_CIPHERS
102 #define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL"
109 HMAC_CTX *cookie_hmac;
114 typedef struct coap_tls_context_t {
117 } coap_tls_context_t;
122 typedef struct sni_entry {
124 #if OPENSSL_VERSION_NUMBER < 0x10101000L
131 typedef struct psk_sni_entry {
133 #if OPENSSL_VERSION_NUMBER < 0x10101000L
139 typedef struct coap_openssl_context_t {
141 #if !COAP_DISABLE_TCP
142 coap_tls_context_t tls;
147 sni_entry *sni_entry_list;
148 size_t psk_sni_count;
149 psk_sni_entry *psk_sni_entry_list;
150 } coap_openssl_context_t;
152 #if OPENSSL_VERSION_NUMBER < 0x10101000L
153 static int psk_tls_server_name_call_back(SSL *ssl,
int *sd,
void *arg);
155 static int psk_tls_client_hello_call_back(SSL *ssl,
int *al,
void *arg);
159 if (SSLeay() < 0x10100000L) {
163 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
171 if (SSLeay() < 0x10101000L) {
180 #if !COAP_DISABLE_TCP
181 if (SSLeay() < 0x10100000L) {
185 #if OPENSSL_VERSION_NUMBER >= 0x10101000L
186 if (SSLeay() < 0x10101000L) {
206 static ENGINE* ssl_engine = NULL;
209 SSL_load_error_strings();
211 ENGINE_load_dynamic();
217 ENGINE_finish(ssl_engine);
219 ENGINE_free(ssl_engine);
234 typedef struct coap_ssl_st {
242 static int coap_dgram_create(BIO *a) {
243 coap_ssl_data *data = NULL;
244 data = malloc(
sizeof(coap_ssl_data));
248 BIO_set_data(a, data);
249 memset(data, 0x00,
sizeof(coap_ssl_data));
253 static int coap_dgram_destroy(BIO *a) {
257 data = (coap_ssl_data *)BIO_get_data(a);
263 static int coap_dgram_read(BIO *a,
char *out,
int outl) {
265 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
268 if (data != NULL && data->pdu_len > 0) {
269 if (outl < (
int)data->pdu_len) {
270 memcpy(out, data->pdu, outl);
273 memcpy(out, data->pdu, data->pdu_len);
274 ret = (int)data->pdu_len;
276 if (!data->peekmode) {
283 BIO_clear_retry_flags(a);
285 BIO_set_retry_read(a);
290 static int coap_dgram_write(BIO *a,
const char *in,
int inl) {
292 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
295 if (data->session->sock.flags ==
COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
297 BIO_clear_retry_flags(a);
301 BIO_clear_retry_flags(a);
303 BIO_set_retry_write(a);
305 BIO_clear_retry_flags(a);
311 static int coap_dgram_puts(BIO *a,
const char *pstr) {
312 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
315 static long coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
317 coap_ssl_data *data = BIO_get_data(a);
322 case BIO_CTRL_GET_CLOSE:
323 ret = BIO_get_shutdown(a);
325 case BIO_CTRL_SET_CLOSE:
326 BIO_set_shutdown(a, (
int)num);
329 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
330 data->peekmode = (unsigned)num;
332 case BIO_CTRL_DGRAM_CONNECT:
335 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
336 case BIO_CTRL_DGRAM_GET_MTU:
337 case BIO_CTRL_DGRAM_SET_MTU:
338 case BIO_CTRL_DGRAM_QUERY_MTU:
339 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
344 case BIO_CTRL_DGRAM_MTU_DISCOVER:
345 case BIO_CTRL_DGRAM_SET_CONNECTED:
348 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
349 data->timeout =
coap_ticks_from_rt_us((uint64_t)((
struct timeval*)ptr)->tv_sec * 1000000 + ((
struct timeval*)ptr)->tv_usec);
353 case BIO_C_FILE_SEEK:
354 case BIO_C_FILE_TELL:
356 case BIO_CTRL_PENDING:
357 case BIO_CTRL_WPENDING:
358 case BIO_CTRL_DGRAM_GET_PEER:
359 case BIO_CTRL_DGRAM_SET_PEER:
360 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
361 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
362 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
363 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
364 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
365 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
366 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
367 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
376 coap_dtls_generate_cookie(SSL *ssl,
377 unsigned char *cookie,
378 unsigned int *cookie_len) {
381 coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
382 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
383 r &= HMAC_Update(dtls->cookie_hmac,
384 (
const uint8_t*)&data->session->addr_info.local.addr,
385 (
size_t)data->session->addr_info.local.size);
386 r &= HMAC_Update(dtls->cookie_hmac,
387 (
const uint8_t*)&data->session->addr_info.remote.addr,
388 (
size_t)data->session->addr_info.remote.size);
389 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
394 coap_dtls_verify_cookie(SSL *ssl,
396 unsigned int cookie_len) {
399 if (coap_dtls_generate_cookie(ssl, hmac, &len) &&
400 cookie_len == len && memcmp(cookie, hmac, len) == 0)
407 coap_dtls_psk_client_callback(
411 unsigned int max_identity_len,
413 unsigned int max_psk_len
415 size_t hint_len = 0, identity_len = 0, psk_len;
417 coap_openssl_context_t *o_context;
421 if (c_session == NULL || c_session->
context == NULL ||
425 if (o_context == NULL)
434 hint_len = strlen(hint);
451 if (psk_info == NULL)
463 memcpy(identity, psk_info->
identity.
s, identity_len);
464 identity[identity_len] =
'\000';
471 memcpy(psk, psk_info->
key.
s, psk_len);
473 return (
unsigned int)psk_len;
480 max_identity_len - 1,
482 if (identity_len < max_identity_len)
483 identity[identity_len] = 0;
484 return (
unsigned)psk_len;
488 coap_dtls_psk_server_callback(
490 const char *identity,
492 unsigned int max_psk_len
494 size_t identity_len = 0;
499 if (c_session == NULL || c_session->
context == NULL ||
506 identity_len = strlen(identity);
517 (
int)identity_len, identity);
521 lidentity.
length = identity_len;
522 lidentity.
s = (
const uint8_t*)identity;
530 if (psk_key->
length > max_psk_len)
532 memcpy(psk, psk_key->
s, psk_key->
length);
534 return (
unsigned int)psk_key->
length;
544 static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
547 int w = where &~SSL_ST_MASK;
549 if (w & SSL_ST_CONNECT)
550 pstr =
"SSL_connect";
551 else if (w & SSL_ST_ACCEPT)
556 if (where & SSL_CB_LOOP) {
560 }
else if (where & SSL_CB_ALERT) {
562 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
563 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL) {
565 if ((ret & 0xff) != SSL3_AD_CLOSE_NOTIFY)
569 coap_log(log_level,
"* %s: SSL3 alert %s:%s:%s\n",
572 SSL_alert_type_string_long(ret),
573 SSL_alert_desc_string_long(ret));
574 }
else if (where & SSL_CB_EXIT) {
580 while ((e = ERR_get_error()))
583 ERR_lib_error_string(e), ERR_func_error_string(e));
585 }
else if (ret < 0) {
587 int err = SSL_get_error(ssl, ret);
588 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) {
592 while ((e = ERR_get_error()))
595 ERR_lib_error_string(e), ERR_func_error_string(e));
601 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
605 #if !COAP_DISABLE_TCP
606 static int coap_sock_create(BIO *a) {
611 static int coap_sock_destroy(BIO *a) {
616 static int coap_sock_read(BIO *a,
char *out,
int outl) {
623 BIO_set_retry_read(a);
626 BIO_clear_retry_flags(a);
632 static int coap_sock_write(BIO *a,
const char *in,
int inl) {
637 BIO_clear_retry_flags(a);
639 BIO_set_retry_read(a);
642 BIO_clear_retry_flags(a);
646 (errno == EPIPE || errno == ECONNRESET)) {
670 static int coap_sock_puts(BIO *a,
const char *pstr) {
671 return coap_sock_write(a, pstr, (
int)strlen(pstr));
674 static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
685 case BIO_CTRL_SET_CLOSE:
691 case BIO_CTRL_GET_CLOSE:
699 static void coap_set_user_prefs(SSL_CTX *ctx) {
700 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
702 #ifdef COAP_OPENSSL_SIGALGS
703 SSL_CTX_set1_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
704 SSL_CTX_set1_client_sigalgs_list(ctx, COAP_OPENSSL_SIGALGS);
707 #if OPENSSL_VERSION_NUMBER >= 0x10101000L && defined(COAP_OPENSSL_GROUPS)
708 SSL_CTX_set1_groups_list(ctx, COAP_OPENSSL_GROUPS);
713 coap_openssl_context_t *context;
716 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
720 memset(context, 0,
sizeof(coap_openssl_context_t));
723 context->dtls.ctx = SSL_CTX_new(DTLS_method());
724 if (!context->dtls.ctx)
726 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
727 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
728 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
729 coap_set_user_prefs(context->dtls.ctx);
730 memset(cookie_secret, 0,
sizeof(cookie_secret));
731 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
734 "Insufficient entropy for random cookie generation");
735 coap_prng(cookie_secret,
sizeof(cookie_secret));
737 context->dtls.cookie_hmac = HMAC_CTX_new();
738 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
740 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
741 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
742 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
743 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
744 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
745 if (!context->dtls.meth)
747 context->dtls.bio_addr = BIO_ADDR_new();
748 if (!context->dtls.bio_addr)
750 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
751 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
752 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
753 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
754 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
755 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
757 #if !COAP_DISABLE_TCP
759 context->tls.ctx = SSL_CTX_new(TLS_method());
760 if (!context->tls.ctx)
762 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
763 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
764 coap_set_user_prefs(context->tls.ctx);
765 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
766 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
767 if (!context->tls.meth)
769 BIO_meth_set_write(context->tls.meth, coap_sock_write);
770 BIO_meth_set_read(context->tls.meth, coap_sock_read);
771 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
772 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
773 BIO_meth_set_create(context->tls.meth, coap_sock_create);
774 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
789 coap_openssl_context_t *o_context =
793 if (!setup_data || !o_context)
796 SSL_CTX_set_psk_server_callback(o_context->dtls.ctx,
797 coap_dtls_psk_server_callback);
798 #if !COAP_DISABLE_TCP
799 SSL_CTX_set_psk_server_callback(o_context->tls.ctx,
800 coap_dtls_psk_server_callback);
806 SSL_CTX_use_psk_identity_hint(o_context->dtls.ctx, hint);
807 #if !COAP_DISABLE_TCP
808 SSL_CTX_use_psk_identity_hint(o_context->tls.ctx, hint);
812 #if OPENSSL_VERSION_NUMBER < 0x10101000L
813 SSL_CTX_set_tlsext_servername_arg(o_context->dtls.ctx,
815 SSL_CTX_set_tlsext_servername_callback(o_context->dtls.ctx,
816 psk_tls_server_name_call_back);
817 #if !COAP_DISABLE_TCP
818 SSL_CTX_set_tlsext_servername_arg(o_context->tls.ctx,
820 SSL_CTX_set_tlsext_servername_callback(o_context->tls.ctx,
821 psk_tls_server_name_call_back);
824 SSL_CTX_set_client_hello_cb(o_context->dtls.ctx,
825 psk_tls_client_hello_call_back,
827 #if !COAP_DISABLE_TCP
828 SSL_CTX_set_client_hello_cb(o_context->tls.ctx,
829 psk_tls_client_hello_call_back,
835 if (!o_context->dtls.ssl) {
837 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
838 if (!o_context->dtls.ssl)
840 bio = BIO_new(o_context->dtls.meth);
842 SSL_free (o_context->dtls.ssl);
843 o_context->dtls.ssl = NULL;
846 SSL_set_bio(o_context->dtls.ssl, bio, bio);
847 SSL_set_app_data(o_context->dtls.ssl, NULL);
848 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
851 o_context->psk_pki_enabled |= IS_PSK;
859 coap_openssl_context_t *o_context =
863 if (!setup_data || !o_context)
866 if (!o_context->dtls.ssl) {
868 o_context->dtls.ssl = SSL_new(o_context->dtls.ctx);
869 if (!o_context->dtls.ssl)
871 bio = BIO_new(o_context->dtls.meth);
873 SSL_free (o_context->dtls.ssl);
874 o_context->dtls.ssl = NULL;
877 SSL_set_bio(o_context->dtls.ssl, bio, bio);
878 SSL_set_app_data(o_context->dtls.ssl, NULL);
879 SSL_set_options(o_context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
882 o_context->psk_pki_enabled |= IS_PSK;
887 map_key_type(
int asn1_private_key_type
889 switch (asn1_private_key_type) {
907 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
908 asn1_private_key_type);
913 #if !COAP_DISABLE_TCP
914 static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
917 server_alpn_callback (SSL *ssl
UNUSED,
918 const unsigned char **out,
919 unsigned char *outlen,
920 const unsigned char *in,
924 unsigned char *tout = NULL;
927 return SSL_TLSEXT_ERR_NOACK;
928 ret = SSL_select_next_proto(&tout,
935 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
940 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
945 while ((e = ERR_get_error()) != 0) {
948 if (!X509_STORE_add_cert(st, x509)) {
949 while ((e = ERR_get_error()) != 0) {
950 int r = ERR_GET_REASON(e);
951 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
954 ERR_reason_error_string(e),
955 ERR_lib_error_string(e),
956 ERR_func_error_string(e));
963 missing_ENGINE_load_cert (
const char *cert_id)
970 params.cert_id = cert_id;
974 if (!ENGINE_ctrl_cmd(ssl_engine,
"LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
980 #if OPENSSL_VERSION_NUMBER < 0x10101000L
982 setup_pki_server(SSL_CTX *ctx,
989 if (!(SSL_CTX_use_certificate_file(ctx,
991 SSL_FILETYPE_PEM))) {
993 "*** setup_pki: (D)TLS: %s: Unable to configure "
994 "Server Certificate\n",
1001 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1007 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1009 SSL_FILETYPE_PEM))) {
1011 "*** setup_pki: (D)TLS: %s: Unable to configure "
1012 "Server Private Key\n",
1019 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1025 STACK_OF(X509_NAME) *cert_names;
1029 char *rw_var = NULL;
1032 if (cert_names != NULL)
1033 SSL_CTX_set_client_CA_list(ctx, cert_names);
1036 "*** setup_pki: (D)TLS: %s: Unable to configure "
1044 st = SSL_CTX_get_cert_store(ctx);
1045 in = BIO_new(BIO_s_file());
1048 if (!BIO_read_filename(in, rw_var)) {
1055 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
1057 add_ca_to_cert_store(st, x);
1069 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1071 if (!cert || !SSL_CTX_use_certificate(ctx, cert)) {
1073 "*** setup_pki: (D)TLS: Unable to configure "
1074 "Server PEM Certificate\n");
1075 if (bp) BIO_free(bp);
1076 if (cert) X509_free(cert);
1079 if (bp) BIO_free(bp);
1080 if (cert) X509_free(cert);
1084 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1092 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1094 if (!pkey || !SSL_CTX_use_PrivateKey(ctx, pkey)) {
1096 "*** setup_pki: (D)TLS: Unable to configure "
1097 "Server PEM Private Key\n");
1098 if (bp) BIO_free(bp);
1099 if (pkey) EVP_PKEY_free(pkey);
1102 if (bp) BIO_free(bp);
1103 if (pkey) EVP_PKEY_free(pkey);
1107 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1118 st = SSL_CTX_get_cert_store(ctx);
1121 if ((x = PEM_read_bio_X509(bp, NULL, NULL, NULL)) == NULL)
1123 add_ca_to_cert_store(st, x);
1124 SSL_CTX_add_client_CA(ctx, x);
1135 if (!(SSL_CTX_use_certificate_ASN1(ctx,
1139 "*** setup_pki: (D)TLS: %s: Unable to configure "
1140 "Server Certificate\n",
1147 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1154 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
1158 "*** setup_pki: (D)TLS: %s: Unable to configure "
1159 "Server Private Key\n",
1166 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1176 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1178 "*** setup_pki: (D)TLS: %s: Unable to configure "
1181 if (x509) X509_free(x509);
1184 st = SSL_CTX_get_cert_store(ctx);
1185 add_ca_to_cert_store(st, x509);
1192 ssl_engine = ENGINE_by_id(
"pkcs11");
1195 "*** setup_pki: (D)TLS: No PKCS11 support\nn");
1198 if (!ENGINE_init(ssl_engine)) {
1200 ENGINE_free(ssl_engine);
1203 "*** setup_pki: (D)TLS: PKCS11 engine initialize failed\n");
1210 if (ENGINE_ctrl_cmd_string(ssl_engine,
"PIN",
1213 "*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1222 "pkcs11:", 7) == 0) {
1223 EVP_PKEY* pkey = ENGINE_load_private_key(ssl_engine,
1229 "*** setup_pki: (D)TLS: %s: Unable to load "
1230 "Server Private Key\n",
1234 if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
1236 "*** setup_pki: (D)TLS: %s: Unable to configure "
1237 "Server Private Key\n",
1239 EVP_PKEY_free(pkey);
1242 EVP_PKEY_free(pkey);
1245 if (!(SSL_CTX_use_PrivateKey_file(ctx,
1247 SSL_FILETYPE_ASN1))) {
1249 "*** setup_pki: (D)TLS: %s: Unable to configure "
1250 "Server Private Key\n",
1258 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1265 "pkcs11:", 7) == 0) {
1268 x509 = missing_ENGINE_load_cert(
1272 "*** setup_pki: (D)TLS: %s: Unable to load "
1273 "Server Certificate\n",
1277 if (!SSL_CTX_use_certificate(ctx, x509)) {
1279 "*** setup_pki: (D)TLS: %s: Unable to configure "
1280 "Server Certificate\n",
1288 if (!(SSL_CTX_use_certificate_file(ctx,
1290 SSL_FILETYPE_ASN1))) {
1292 "*** setup_pki: (D)TLS: %s: Unable to configure "
1293 "Server Certificate\n",
1301 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1312 x509 = missing_ENGINE_load_cert (
1316 "*** setup_pki: (D)TLS: %s: Unable to load "
1317 "Server CA Certificate\n",
1321 if (!SSL_CTX_add_client_CA(ctx, x509)) {
1323 "*** setup_pki: (D)TLS: %s: Unable to configure "
1329 st = SSL_CTX_get_cert_store(ctx);
1330 add_ca_to_cert_store(st, x509);
1335 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1337 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
1339 "*** setup_pki: (D)TLS: %s: Unable to configure "
1342 if (x509) X509_free(x509);
1345 st = SSL_CTX_get_cert_store(ctx);
1346 add_ca_to_cert_store(st, x509);
1354 "*** setup_pki: (D)TLS: Unknown key type %d\n",
1364 setup_pki_ssl(SSL *ssl,
1369 "RPK Support not available in OpenSSL\n");
1376 if (!(SSL_use_certificate_file(ssl,
1378 SSL_FILETYPE_PEM))) {
1380 "*** setup_pki: (D)TLS: %s: Unable to configure "
1391 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
1397 if (!(SSL_use_PrivateKey_file(ssl,
1399 SSL_FILETYPE_PEM))) {
1401 "*** setup_pki: (D)TLS: %s: Unable to configure "
1402 "Client Private Key\n",
1411 "*** setup_pki: (D)TLS: No %s Private Key defined\n",
1420 char *rw_var = NULL;
1421 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1424 STACK_OF(X509_NAME) *cert_names = SSL_load_client_CA_file(setup_data->
pki_key.
key.
pem.
ca_file);
1426 if (cert_names != NULL)
1427 SSL_set_client_CA_list(ssl, cert_names);
1430 "*** setup_pki: (D)TLS: %s: Unable to configure "
1439 in = BIO_new(BIO_s_file());
1442 if (!BIO_read_filename(in, rw_var)) {
1447 st = SSL_CTX_get_cert_store(ctx);
1449 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
1451 add_ca_to_cert_store(st, x);
1463 X509 *cert = bp ? PEM_read_bio_X509(bp, NULL, 0, NULL) : NULL;
1465 if (!cert || !SSL_use_certificate(ssl, cert)) {
1467 "*** setup_pki: (D)TLS: Unable to configure "
1468 "Server PEM Certificate\n");
1469 if (bp) BIO_free(bp);
1470 if (cert) X509_free(cert);
1473 if (bp) BIO_free(bp);
1474 if (cert) X509_free(cert);
1478 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1486 EVP_PKEY *pkey = bp ? PEM_read_bio_PrivateKey(bp, NULL, 0, NULL) : NULL;
1488 if (!pkey || !SSL_use_PrivateKey(ssl, pkey)) {
1490 "*** setup_pki: (D)TLS: Unable to configure "
1491 "Server PEM Private Key\n");
1492 if (bp) BIO_free(bp);
1493 if (pkey) EVP_PKEY_free(pkey);
1496 if (bp) BIO_free(bp);
1497 if (pkey) EVP_PKEY_free(pkey);
1501 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1509 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1511 X509_STORE *st = SSL_CTX_get_cert_store(ctx);
1515 if ((x = PEM_read_bio_X509(bp, NULL, 0, NULL)) == NULL)
1517 add_ca_to_cert_store(st, x);
1518 SSL_add_client_CA(ssl, x);
1529 if (!(SSL_use_certificate_ASN1(ssl,
1533 "*** setup_pki: (D)TLS: %s: Unable to configure "
1544 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
1551 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
1555 "*** setup_pki: (D)TLS: %s: Unable to configure "
1566 "*** setup_pki: (D)TLS: No %s Private Key defined",
1576 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1579 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1581 "*** setup_pki: (D)TLS: %s: Unable to configure "
1590 st = SSL_CTX_get_cert_store(ctx);
1591 add_ca_to_cert_store(st, x509);
1598 ssl_engine = ENGINE_by_id(
"pkcs11");
1601 "*** setup_pki: (D)TLS: No PKCS11 support\nn");
1604 if (!ENGINE_init(ssl_engine)) {
1606 ENGINE_free(ssl_engine);
1609 "*** setup_pki: (D)TLS: PKCS11 engine initialize failed\nn");
1616 if (ENGINE_ctrl_cmd_string(ssl_engine,
1620 "*** setup_pki: (D)TLS: PKCS11: %s: Unable to set pin\n",
1629 "pkcs11:", 7) == 0) {
1630 EVP_PKEY* pkey = ENGINE_load_private_key(ssl_engine,
1636 "*** setup_pki: (D)TLS: %s: Unable to load "
1642 if (!SSL_use_PrivateKey(ssl, pkey)) {
1644 "*** setup_pki: (D)TLS: %s: Unable to configure "
1648 EVP_PKEY_free(pkey);
1651 EVP_PKEY_free(pkey);
1654 if (!(SSL_use_PrivateKey_file(ssl,
1656 SSL_FILETYPE_ASN1))) {
1658 "*** setup_pki: (D)TLS: %s: Unable to configure "
1668 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
1675 "pkcs11:", 7) == 0) {
1678 x509 = missing_ENGINE_load_cert(
1682 "*** setup_pki: (D)TLS: %s: Unable to load "
1688 if (!SSL_use_certificate(ssl, x509)) {
1690 "*** setup_pki: (D)TLS: %s: Unable to configure "
1700 if (!(SSL_use_certificate_file(ssl,
1702 SSL_FILETYPE_ASN1))) {
1704 "*** setup_pki: (D)TLS: %s: Unable to configure "
1714 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
1724 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1726 x509 = missing_ENGINE_load_cert(
1730 "*** setup_pki: (D)TLS: %s: Unable to load "
1731 "%s CA Certificate\n",
1736 if (!SSL_add_client_CA(ssl, x509)) {
1738 "*** setup_pki: (D)TLS: %s: Unable to configure "
1739 "%s CA Certificate\n",
1745 st = SSL_CTX_get_cert_store(ctx);
1746 add_ca_to_cert_store(st, x509);
1751 X509 *x509 = fp ? d2i_X509_fp(fp, NULL) : NULL;
1752 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
1754 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
1756 "*** setup_pki: (D)TLS: %s: Unable to configure "
1760 if (x509) X509_free(x509);
1763 st = SSL_CTX_get_cert_store(ctx);
1764 add_ca_to_cert_store(st, x509);
1772 "*** setup_pki: (D)TLS: Unknown key type %d\n",
1780 get_san_or_cn_from_cert(X509* x509) {
1784 STACK_OF(GENERAL_NAME) *san_list;
1787 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1789 int san_count = sk_GENERAL_NAME_num(san_list);
1791 for (
n = 0;
n < san_count;
n++) {
1792 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list,
n);
1794 if (name->type == GEN_DNS) {
1795 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1798 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
1800 cn = OPENSSL_strdup(dns_name);
1801 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1805 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1808 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
1811 n = (int)strlen(buffer) - 3;
1814 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1815 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1824 char * ecn = strchr(cn,
'/');
1826 return OPENSSL_strndup(cn, ecn-cn);
1829 return OPENSSL_strdup(cn);
1837 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1838 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1839 SSL_get_ex_data_X509_STORE_CTX_idx());
1841 coap_openssl_context_t *context =
1844 int depth = X509_STORE_CTX_get_error_depth(ctx);
1845 int err = X509_STORE_CTX_get_error(ctx);
1846 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1847 char *cn = get_san_or_cn_from_cert(x509);
1848 int keep_preverify_ok = preverify_ok;
1850 if (!preverify_ok) {
1852 case X509_V_ERR_CERT_NOT_YET_VALID:
1853 case X509_V_ERR_CERT_HAS_EXPIRED:
1857 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
1861 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1865 case X509_V_ERR_UNABLE_TO_GET_CRL:
1869 case X509_V_ERR_CRL_NOT_YET_VALID:
1870 case X509_V_ERR_CRL_HAS_EXPIRED:
1874 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
1875 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
1885 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
1886 X509_STORE_CTX_set_error(ctx, err);
1888 if (!preverify_ok) {
1889 if (err == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
1891 " %s: %s: '%s' depth=%d\n",
1893 "Unknown CA", cn ? cn :
"?", depth);
1897 " %s: %s: '%s' depth=%d\n",
1899 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1904 " %s: %s: overridden: '%s' depth=%d\n",
1906 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1911 int length = i2d_X509(x509, NULL);
1913 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1916 i2d_X509(x509, &base_buf2);
1918 depth, preverify_ok,
1921 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1924 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1928 OPENSSL_free(base_buf);
1931 return preverify_ok;
1934 #if OPENSSL_VERSION_NUMBER < 0x10101000L
1943 tls_secret_call_back(SSL *ssl,
1946 STACK_OF(SSL_CIPHER) *peer_ciphers,
1947 const SSL_CIPHER **cipher
UNUSED,
1951 int psk_requested = 0;
1956 assert(session != NULL);
1957 assert(session->
context != NULL);
1958 if (session == NULL ||
1966 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1967 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1970 SSL_CIPHER_get_name(peer_cipher));
1971 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1977 if (!psk_requested) {
1984 SSL_VERIFY_CLIENT_ONCE |
1985 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1986 tls_verify_call_back);
1989 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
1998 X509_VERIFY_PARAM *param;
2000 param = X509_VERIFY_PARAM_new();
2001 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2002 SSL_set1_param(ssl, param);
2003 X509_VERIFY_PARAM_free(param);
2027 SSL_set_cipher_list (ssl, COAP_OPENSSL_PSK_CIPHERS);
2028 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2042 tls_server_name_call_back(SSL *ssl,
2049 return SSL_TLSEXT_ERR_NOACK;
2055 coap_openssl_context_t *context =
2057 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2060 if (!sni || !sni[0]) {
2063 for (i = 0; i < context->sni_count; i++) {
2064 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2068 if (i == context->sni_count) {
2074 return SSL_TLSEXT_ERR_ALERT_FATAL;
2079 ctx = SSL_CTX_new(DTLS_method());
2082 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2083 SSL_CTX_set_app_data(ctx, &context->dtls);
2084 SSL_CTX_set_read_ahead(ctx, 1);
2085 coap_set_user_prefs(ctx);
2086 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2087 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2088 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2089 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2091 #if !COAP_DISABLE_TCP
2094 ctx = SSL_CTX_new(TLS_method());
2097 SSL_CTX_set_app_data(ctx, &context->tls);
2098 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2099 coap_set_user_prefs(ctx);
2100 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2101 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2104 sni_setup_data = *setup_data;
2105 sni_setup_data.
pki_key = *new_entry;
2106 setup_pki_server(ctx, &sni_setup_data);
2108 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2109 (context->sni_count+1)*
sizeof(sni_entry));
2110 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2111 context->sni_entry_list[context->sni_count].ctx = ctx;
2112 context->sni_count++;
2114 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
2115 SSL_clear_options (ssl, 0xFFFFFFFFL);
2116 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
2123 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
2124 return SSL_TLSEXT_ERR_OK;
2127 return SSL_TLSEXT_ERR_ALERT_WARNING;
2138 psk_tls_server_name_call_back(SSL *ssl,
2145 return SSL_TLSEXT_ERR_NOACK;
2151 coap_openssl_context_t *o_context =
2153 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
2157 if (!sni || !sni[0]) {
2160 for (i = 0; i < o_context->psk_sni_count; i++) {
2161 if (!strcasecmp(sni, (
char*)o_context->psk_sni_entry_list[i].sni)) {
2165 if (i == o_context->psk_sni_count) {
2172 return SSL_TLSEXT_ERR_ALERT_FATAL;
2177 ctx = SSL_CTX_new(DTLS_method());
2180 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
2181 SSL_CTX_set_app_data(ctx, &o_context->dtls);
2182 SSL_CTX_set_read_ahead(ctx, 1);
2183 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2184 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
2185 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
2186 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2187 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
2189 #if !COAP_DISABLE_TCP
2192 ctx = SSL_CTX_new(TLS_method());
2195 SSL_CTX_set_app_data(ctx, &o_context->tls);
2196 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
2197 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
2198 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
2199 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
2203 o_context->psk_sni_entry_list =
2204 OPENSSL_realloc(o_context->psk_sni_entry_list,
2205 (o_context->psk_sni_count+1)*
sizeof(psk_sni_entry));
2206 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2207 OPENSSL_strdup(sni);
2208 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2210 o_context->psk_sni_entry_list[o_context->psk_sni_count].ctx =
2212 o_context->psk_sni_count++;
2214 SSL_set_SSL_CTX (ssl, o_context->psk_sni_entry_list[i].ctx);
2215 SSL_clear_options (ssl, 0xFFFFFFFFL);
2216 SSL_set_options (ssl,
2217 SSL_CTX_get_options (o_context->psk_sni_entry_list[i].ctx));
2219 &o_context->psk_sni_entry_list[i].psk_info.key);
2220 snprintf(lhint,
sizeof(lhint),
"%.*s",
2221 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2222 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2223 SSL_use_psk_identity_hint(ssl, lhint);
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;
2246 tls_client_hello_call_back(SSL *ssl,
2251 coap_openssl_context_t *dtls_context;
2253 int psk_requested = 0;
2254 const unsigned char *out;
2258 *al = SSL_AD_INTERNAL_ERROR;
2259 return SSL_CLIENT_HELLO_ERROR;
2262 assert(session != NULL);
2263 assert(session->
context != NULL);
2265 if (session == NULL ||
2268 *al = SSL_AD_INTERNAL_ERROR;
2269 return SSL_CLIENT_HELLO_ERROR;
2272 setup_data = &dtls_context->setup_data;
2280 size_t len = SSL_client_hello_get0_ciphers(ssl, &out);
2281 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
2282 STACK_OF(SSL_CIPHER) *scsvc = NULL;
2284 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
2285 SSL_client_hello_isv2(ssl),
2286 &peer_ciphers, &scsvc)) {
2288 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
2289 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
2292 SSL_CIPHER_get_name(peer_cipher),
2293 SSL_CIPHER_get_protocol_id(peer_cipher));
2294 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
2300 sk_SSL_CIPHER_free(peer_ciphers);
2301 sk_SSL_CIPHER_free(scsvc);
2304 if (psk_requested) {
2310 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2316 return SSL_CLIENT_HELLO_SUCCESS;
2326 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
2329 for (ii = 0; ii < outlen; ii++) {
2345 *al = SSL_AD_UNSUPPORTED_EXTENSION;
2346 return SSL_CLIENT_HELLO_ERROR;
2355 coap_openssl_context_t *context =
2357 const char *sni =
"";
2358 char *sni_tmp = NULL;
2361 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2363 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2364 out[2] == TLSEXT_NAMETYPE_host_name &&
2365 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2369 sni_tmp = OPENSSL_malloc(outlen+1);
2370 sni_tmp[outlen] =
'\000';
2371 memcpy(sni_tmp, out, outlen);
2375 for (i = 0; i < context->sni_count; i++) {
2376 if (!strcasecmp(sni, context->sni_entry_list[i].sni)) {
2380 if (i == context->sni_count) {
2387 *al = SSL_AD_UNRECOGNIZED_NAME;
2388 return SSL_CLIENT_HELLO_ERROR;
2392 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
2393 (context->sni_count+1)*
sizeof(sni_entry));
2394 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
2395 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
2396 context->sni_count++;
2399 OPENSSL_free(sni_tmp);
2401 sni_setup_data = *setup_data;
2402 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
2403 setup_pki_ssl(ssl, &sni_setup_data, 1);
2406 setup_pki_ssl(ssl, setup_data, 1);
2415 SSL_VERIFY_CLIENT_ONCE |
2416 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2417 tls_verify_call_back);
2420 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2429 X509_VERIFY_PARAM *param;
2431 param = X509_VERIFY_PARAM_new();
2432 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2433 SSL_set1_param(ssl, param);
2434 X509_VERIFY_PARAM_free(param);
2441 return SSL_CLIENT_HELLO_SUCCESS;
2452 psk_tls_client_hello_call_back(SSL *ssl,
2457 coap_openssl_context_t *o_context;
2459 const unsigned char *out;
2465 if (!c_session || !c_session->
context) {
2478 const char *sni =
"";
2479 char *sni_tmp = NULL;
2483 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
2485 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
2486 out[2] == TLSEXT_NAMETYPE_host_name &&
2487 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
2491 sni_tmp = OPENSSL_malloc(outlen+1);
2493 sni_tmp[outlen] =
'\000';
2494 memcpy(sni_tmp, out, outlen);
2500 for (i = 0; i < o_context->psk_sni_count; i++) {
2501 if (strcasecmp(sni, o_context->psk_sni_entry_list[i].sni) == 0) {
2505 if (i == o_context->psk_sni_count) {
2509 psk_sni_entry *tmp_entry;
2515 *al = SSL_AD_UNRECOGNIZED_NAME;
2516 return SSL_CLIENT_HELLO_ERROR;
2520 OPENSSL_realloc(o_context->psk_sni_entry_list,
2521 (o_context->psk_sni_count+1)*
sizeof(sni_entry));
2523 o_context->psk_sni_entry_list = tmp_entry;
2524 o_context->psk_sni_entry_list[o_context->psk_sni_count].sni =
2525 OPENSSL_strdup(sni);
2526 if (o_context->psk_sni_entry_list[o_context->psk_sni_count].sni) {
2527 o_context->psk_sni_entry_list[o_context->psk_sni_count].psk_info =
2529 o_context->psk_sni_count++;
2534 OPENSSL_free(sni_tmp);
2537 &o_context->psk_sni_entry_list[i].psk_info.hint)
2542 &o_context->psk_sni_entry_list[i].psk_info.key)
2546 if (o_context->psk_sni_entry_list[i].psk_info.hint.s) {
2547 snprintf(lhint,
sizeof(lhint),
"%.*s",
2548 (
int)o_context->psk_sni_entry_list[i].psk_info.hint.length,
2549 o_context->psk_sni_entry_list[i].psk_info.hint.s);
2550 SSL_use_psk_identity_hint(ssl, lhint);
2553 return SSL_CLIENT_HELLO_SUCCESS;
2556 *al = SSL_AD_INTERNAL_ERROR;
2557 return SSL_CLIENT_HELLO_ERROR;
2566 coap_openssl_context_t *context =
2571 context->setup_data = *setup_data;
2572 if (!context->setup_data.verify_peer_cert) {
2576 context->setup_data.allow_self_signed = 1;
2577 context->setup_data.allow_expired_certs = 1;
2578 context->setup_data.cert_chain_validation = 1;
2579 context->setup_data.cert_chain_verify_depth = 10;
2580 context->setup_data.check_cert_revocation = 1;
2581 context->setup_data.allow_no_crl = 1;
2582 context->setup_data.allow_expired_crl = 1;
2583 context->setup_data.allow_bad_md_hash = 1;
2584 context->setup_data.allow_short_rsa_length = 1;
2587 if (context->dtls.ctx) {
2589 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2590 if (!setup_pki_server(context->dtls.ctx, setup_data))
2599 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2600 if (SSLeay() >= 0x10101000L) {
2602 "OpenSSL compiled with %lux, linked with %lux, so "
2603 "no certificate checking\n",
2604 OPENSSL_VERSION_NUMBER, SSLeay());
2606 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
2607 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
2608 tls_server_name_call_back);
2610 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
2611 tls_client_hello_call_back,
2615 #if !COAP_DISABLE_TCP
2616 if (context->tls.ctx) {
2618 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2619 if (!setup_pki_server(context->tls.ctx, setup_data))
2628 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2629 if (SSLeay() >= 0x10101000L) {
2631 "OpenSSL compiled with %lux, linked with %lux, so "
2632 "no certificate checking\n",
2633 OPENSSL_VERSION_NUMBER, SSLeay());
2635 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
2636 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
2637 tls_server_name_call_back);
2639 SSL_CTX_set_client_hello_cb(context->tls.ctx,
2640 tls_client_hello_call_back,
2644 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
2649 if (!context->dtls.ssl) {
2651 context->dtls.ssl = SSL_new(context->dtls.ctx);
2652 if (!context->dtls.ssl)
2654 bio = BIO_new(context->dtls.meth);
2656 SSL_free (context->dtls.ssl);
2657 context->dtls.ssl = NULL;
2660 SSL_set_bio(context->dtls.ssl, bio, bio);
2661 SSL_set_app_data(context->dtls.ssl, NULL);
2662 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
2665 context->psk_pki_enabled |= IS_PKI;
2671 const char *ca_file,
2674 coap_openssl_context_t *context =
2676 if (context->dtls.ctx) {
2677 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
2679 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2683 #if !COAP_DISABLE_TCP
2684 if (context->tls.ctx) {
2685 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
2687 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
2698 coap_openssl_context_t *context =
2700 return context->psk_pki_enabled ? 1 : 0;
2706 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
2708 if (context->dtls.ssl)
2709 SSL_free(context->dtls.ssl);
2710 if (context->dtls.ctx)
2711 SSL_CTX_free(context->dtls.ctx);
2712 if (context->dtls.cookie_hmac)
2713 HMAC_CTX_free(context->dtls.cookie_hmac);
2714 if (context->dtls.meth)
2715 BIO_meth_free(context->dtls.meth);
2716 if (context->dtls.bio_addr)
2717 BIO_ADDR_free(context->dtls.bio_addr);
2718 #if !COAP_DISABLE_TCP
2719 if ( context->tls.ctx )
2720 SSL_CTX_free( context->tls.ctx );
2721 if ( context->tls.meth )
2722 BIO_meth_free( context->tls.meth );
2724 for (i = 0; i < context->sni_count; i++) {
2725 OPENSSL_free(context->sni_entry_list[i].sni);
2726 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2727 SSL_CTX_free(context->sni_entry_list[i].ctx);
2730 if (context->sni_count)
2731 OPENSSL_free(context->sni_entry_list);
2732 for (i = 0; i < context->psk_sni_count; i++) {
2733 OPENSSL_free((
char*)context->psk_sni_entry_list[i].sni);
2734 #if OPENSSL_VERSION_NUMBER < 0x10101000L
2735 SSL_CTX_free(context->psk_sni_entry_list[i].ctx);
2738 if (context->psk_sni_count)
2739 OPENSSL_free(context->psk_sni_entry_list);
2745 SSL *nssl = NULL, *ssl = NULL;
2746 coap_ssl_data *data;
2750 nssl = SSL_new(dtls->
ctx);
2753 nbio = BIO_new(dtls->meth);
2756 SSL_set_bio(nssl, nbio, nbio);
2757 SSL_set_app_data(nssl, NULL);
2758 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
2759 SSL_set_mtu(nssl, session->
mtu);
2763 SSL_set_app_data(ssl, session);
2765 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
2766 data->session = session;
2772 (
uint8_t*)hint,
sizeof(hint) - 1);
2773 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2775 SSL_use_psk_identity_hint(ssl, hint);
2779 r = SSL_accept(ssl);
2781 int err = SSL_get_error(ssl, r);
2782 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2802 coap_openssl_context_t *context =
2805 if (context->psk_pki_enabled & IS_PSK) {
2810 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
2814 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
2815 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
2816 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
2819 SSL_set_max_proto_version(ssl, DTLS1_2_VERSION);
2821 #if !COAP_DISABLE_TCP
2823 SSL_set_max_proto_version(ssl, TLS1_2_VERSION);
2827 "CoAP Client restricted to (D)TLS1.2 with Identity Hint callback\n");
2830 if (context->psk_pki_enabled & IS_PKI) {
2832 if (!setup_pki_ssl(ssl, setup_data, 0))
2835 #if !COAP_DISABLE_TCP
2837 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
2842 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
2848 X509_VERIFY_PARAM *param;
2850 param = X509_VERIFY_PARAM_new();
2851 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
2852 SSL_set1_param(ssl, param);
2853 X509_VERIFY_PARAM_free(param);
2860 SSL_VERIFY_CLIENT_ONCE |
2861 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
2862 tls_verify_call_back);
2864 SSL_set_verify(ssl, SSL_VERIFY_NONE, tls_verify_call_back);
2877 coap_ssl_data *data;
2879 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2882 ssl = SSL_new(dtls->
ctx);
2885 bio = BIO_new(dtls->meth);
2888 data = (coap_ssl_data *)BIO_get_data(bio);
2889 data->session = session;
2890 SSL_set_bio(ssl, bio, bio);
2891 SSL_set_app_data(ssl, session);
2892 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
2893 SSL_set_mtu(ssl, session->
mtu);
2895 if (!setup_client_ssl_session(session, ssl))
2900 r = SSL_connect(ssl);
2902 int ret = SSL_get_error(ssl, r);
2903 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2919 SSL *ssl = (SSL *)session->
tls;
2921 SSL_set_mtu(ssl, session->
mtu);
2925 SSL *ssl = (SSL *)session->
tls;
2927 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2928 int r = SSL_shutdown(ssl);
2929 if (r == 0) r = SSL_shutdown(ssl);
2932 session->
tls = NULL;
2939 const uint8_t *data,
size_t data_len) {
2941 SSL *ssl = (SSL *)session->
tls;
2943 assert(ssl != NULL);
2946 r = SSL_write(ssl, data, (
int)data_len);
2949 int err = SSL_get_error(ssl, r);
2950 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2954 if (err == SSL_ERROR_ZERO_RETURN)
2956 else if (err == SSL_ERROR_SSL)
2986 SSL *ssl = (SSL *)session->
tls;
2987 coap_ssl_data *ssl_data;
2990 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
2991 return ssl_data->timeout;
2995 SSL *ssl = (SSL *)session->
tls;
2999 (DTLSv1_handle_timeout(ssl) < 0)) {
3006 const uint8_t *data,
size_t data_len) {
3008 coap_ssl_data *ssl_data;
3011 SSL_set_mtu(dtls->ssl, session->
mtu);
3012 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
3013 assert(ssl_data != NULL);
3014 if (ssl_data->pdu_len) {
3018 ssl_data->session = session;
3019 ssl_data->pdu = data;
3020 ssl_data->pdu_len = (unsigned)data_len;
3021 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
3023 int err = SSL_get_error(dtls->ssl, r);
3024 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3042 const uint8_t *data,
size_t data_len) {
3043 coap_ssl_data *ssl_data;
3044 SSL *ssl = (SSL *)session->
tls;
3047 assert(ssl != NULL);
3049 int in_init = SSL_in_init(ssl);
3051 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
3052 assert(ssl_data != NULL);
3054 if (ssl_data->pdu_len) {
3058 ssl_data->pdu = data;
3059 ssl_data->pdu_len = (unsigned)data_len;
3062 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
3067 int err = SSL_get_error(ssl, r);
3068 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3069 if (in_init && SSL_is_init_finished(ssl)) {
3077 if (err == SSL_ERROR_ZERO_RETURN)
3079 else if (err == SSL_ERROR_SSL)
3097 if (ssl_data && ssl_data->pdu_len) {
3099 coap_log(
LOG_DEBUG,
"coap_dtls_receive: ret %d: remaining data %u\n", r, ssl_data->pdu_len);
3100 ssl_data->pdu_len = 0;
3101 ssl_data->pdu = NULL;
3107 unsigned int overhead = 37;
3108 const SSL_CIPHER *s_ciph = NULL;
3109 if (session->
tls != NULL)
3110 s_ciph = SSL_get_current_cipher(session->
tls);
3112 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
3114 const EVP_CIPHER *e_ciph;
3118 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
3120 switch (EVP_CIPHER_mode(e_ciph)) {
3121 case EVP_CIPH_GCM_MODE:
3122 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
3123 maclen = EVP_GCM_TLS_TAG_LEN;
3126 case EVP_CIPH_CCM_MODE:
3127 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
3128 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3129 if (strstr(cipher,
"CCM8"))
3135 case EVP_CIPH_CBC_MODE:
3136 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
3137 blocksize = EVP_CIPHER_block_size(e_ciph);
3138 ivlen = EVP_CIPHER_iv_length(e_ciph);
3140 maclen = EVP_MD_size(e_md);
3143 case EVP_CIPH_STREAM_CIPHER:
3150 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
3157 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
3162 #if !COAP_DISABLE_TCP
3167 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
3168 coap_tls_context_t *tls = &context->tls;
3171 ssl = SSL_new(tls->ctx);
3174 bio = BIO_new(tls->meth);
3177 BIO_set_data(bio, session);
3178 SSL_set_bio(ssl, bio, bio);
3179 SSL_set_app_data(ssl, session);
3181 if (!setup_client_ssl_session(session, ssl))
3184 r = SSL_connect(ssl);
3186 int ret = SSL_get_error(ssl, r);
3187 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
3189 if (ret == SSL_ERROR_WANT_READ)
3191 if (ret == SSL_ERROR_WANT_WRITE) {
3193 #ifdef COAP_EPOLL_SUPPORT
3206 *connected = SSL_is_init_finished(ssl);
3219 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
3223 ssl = SSL_new(tls->ctx);
3226 bio = BIO_new(tls->meth);
3229 BIO_set_data(bio, session);
3230 SSL_set_bio(ssl, bio, bio);
3231 SSL_set_app_data(ssl, session);
3236 if (hint_len > 0 && hint_len <
sizeof(hint)) {
3238 SSL_use_psk_identity_hint(ssl, hint);
3242 r = SSL_accept(ssl);
3244 int err = SSL_get_error(ssl, r);
3245 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
3247 if (err == SSL_ERROR_WANT_READ)
3249 if (err == SSL_ERROR_WANT_WRITE) {
3251 #ifdef COAP_EPOLL_SUPPORT
3264 *connected = SSL_is_init_finished(ssl);
3275 SSL *ssl = (SSL *)session->
tls;
3277 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
3278 int r = SSL_shutdown(ssl);
3279 if (r == 0) r = SSL_shutdown(ssl);
3282 session->
tls = NULL;
3292 SSL *ssl = (SSL *)session->
tls;
3298 in_init = !SSL_is_init_finished(ssl);
3300 r = SSL_write(ssl, data, (
int)data_len);
3303 int err = SSL_get_error(ssl, r);
3304 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3305 if (in_init && SSL_is_init_finished(ssl)) {
3311 if (err == SSL_ERROR_WANT_READ)
3313 if (err == SSL_ERROR_WANT_WRITE) {
3315 #ifdef COAP_EPOLL_SUPPORT
3327 if (err == SSL_ERROR_ZERO_RETURN)
3329 else if (err == SSL_ERROR_SSL)
3333 }
else if (in_init && SSL_is_init_finished(ssl)) {
3358 SSL *ssl = (SSL *)session->
tls;
3364 in_init = !SSL_is_init_finished(ssl);
3366 r = SSL_read(ssl, data, (
int)data_len);
3368 int err = SSL_get_error(ssl, r);
3369 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
3370 if (in_init && SSL_is_init_finished(ssl)) {
3376 if (err == SSL_ERROR_WANT_READ)
3378 if (err == SSL_ERROR_WANT_WRITE) {
3380 #ifdef COAP_EPOLL_SUPPORT
3390 if (err == SSL_ERROR_ZERO_RETURN)
3392 else if (err == SSL_ERROR_SSL)
3396 }
else if (in_init && SSL_is_init_finished(ssl)) {
3420 SHA256_CTX *digest_ctx = OPENSSL_malloc(
sizeof(SHA256_CTX));
3423 SHA256_Init(digest_ctx);
3430 OPENSSL_free(digest_ctx);
3437 return SHA256_Update(digest_ctx, data, data_len);
3443 int ret = SHA256_Final((
uint8_t*)digest_buffer, digest_ctx);
3455 #pragma GCC diagnostic ignored "-Wunused-function"
void coap_dtls_free_context(struct coap_dtls_context_t *dtls_context)
Releases the storage allocated for dtls_context.
struct coap_dtls_context_t coap_dtls_context_t
int coap_dtls_send(struct coap_context_t *coap_context, struct coap_dtls_session_t *session, const coap_pdu_t *pdu)
void coap_dtls_free_session(struct coap_dtls_context_t *dtls_context, struct coap_dtls_session_t *session)
Pulls together all the internal only header files.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
const char * coap_socket_strerror(void)
#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_root_cas(struct coap_context_t *ctx UNUSED, const char *ca_file UNUSED, const char *ca_path UNUSED)
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, const coap_dtls_pki_t *setup_data UNUSED, const coap_dtls_role_t role UNUSED)
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED)
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
int coap_dtls_receive(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
int coap_dtls_hello(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
int coap_dtls_context_set_cpsk(coap_context_t *ctx UNUSED, coap_dtls_cpsk_t *setup_data UNUSED)
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
ssize_t coap_tls_read(coap_session_t *session UNUSED, uint8_t *data UNUSED, size_t data_len UNUSED)
int coap_dtls_context_set_spsk(coap_context_t *ctx UNUSED, coap_dtls_spsk_t *setup_data UNUSED)
coap_tick_t coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED)
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
static int dtls_log_level
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
void coap_dtls_session_update_mtu(coap_session_t *session UNUSED)
void coap_dtls_handle_timeout(coap_session_t *session UNUSED)
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
ssize_t coap_tls_write(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
int coap_session_refresh_psk_hint(coap_session_t *session, const coap_bin_const_t *psk_hint)
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)
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
#define COAP_SESSION_STATE_HANDSHAKE
#define COAP_SESSION_STATE_CSM
void coap_digest_free(coap_digest_ctx_t *digest_ctx)
Free off coap_digest_ctx_t.
coap_digest_ctx_t * coap_digest_setup(void)
Initialize a coap_digest.
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_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.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
void coap_dtls_shutdown(void)
Close down the underlying (D)TLS Library layer.
struct coap_dtls_context_t * coap_dtls_new_context(struct coap_context_t *coap_context)
Creates a new DTLS context for the given coap_context.
@ COAP_DTLS_ROLE_SERVER
Internal function invoked for server.
#define COAP_DTLS_HINT_LENGTH
int coap_tls_is_supported(void)
Check whether TLS is available.
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
int coap_dtls_is_supported(void)
Returns 1 if support for DTLS is enabled, or 0 otherwise.
@ 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.
#define COAP_EVENT_DTLS_RENEGOTIATE
#define COAP_EVENT_DTLS_ERROR
#define COAP_EVENT_DTLS_CLOSED
(D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
#define COAP_EVENT_DTLS_CONNECTED
void coap_dtls_set_log_level(int level)
Sets the log level to the specified value.
const char * coap_session_str(const coap_session_t *session)
Get session description.
int coap_dtls_get_log_level(void)
Returns the current log level.
#define coap_log(level,...)
Logging function.
@ COAP_LOG_CIPHERS
CipherInfo.
void coap_delete_bin_const(coap_bin_const_t *s)
Deletes the given const binary data and releases any memory allocated.
coap_bin_const_t * coap_new_bin_const(const uint8_t *data, size_t size)
Take the specified byte array (text) and create a coap_bin_const_t * Returns a new const binary objec...
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
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.
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.
size_t(* get_server_psk)(const coap_session_t *session, const uint8_t *identity, size_t identity_len, uint8_t *psk, size_t max_psk_len)
size_t(* get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len)
size_t(* get_client_psk)(const coap_session_t *session, const uint8_t *hint, size_t hint_len, uint8_t *identity, size_t *identity_len, size_t max_identity_len, uint8_t *psk, size_t max_psk_len)
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::@1 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
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
unsigned int max_retransmit
maximum re-transmit count (default 4)
coap_bin_const_t * psk_identity
If client, this field contains the current identity for server; When this field is NULL,...
coap_session_state_t state
current state of relationaship with peer
coap_proto_t proto
protocol used
coap_bin_const_t * psk_hint
If client, this field contains the server provided identity hint.
coap_dtls_cpsk_t cpsk_setup_data
client provided PSK initial setup data
struct coap_context_t * context
session's context
int dtls_event
Tracking any (D)TLS events on this sesison.
void * tls
security parameters
uint64_t mtu
path or CSM mtu
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