43 #include <openssl/ssl.h> 44 #include <openssl/err.h> 45 #include <openssl/rand.h> 46 #include <openssl/hmac.h> 47 #include <openssl/x509v3.h> 49 #ifdef COAP_EPOLL_SUPPORT 50 # include <sys/epoll.h> 53 #if OPENSSL_VERSION_NUMBER < 0x10100000L 54 #error Must be compiled against OpenSSL 1.1.0 or later 58 #define UNUSED __attribute__((unused)) 64 #ifndef TLSEXT_TYPE_client_certificate_type 65 #define TLSEXT_TYPE_client_certificate_type 19 67 #ifndef TLSEXT_TYPE_server_certificate_type 68 #define TLSEXT_TYPE_server_certificate_type 20 71 #ifndef COAP_OPENSSL_CIPHERS 72 #if OPENSSL_VERSION_NUMBER >= 0x10101000L 73 #define COAP_OPENSSL_CIPHERS "TLSv1.3:TLSv1.2:!NULL" 75 #define COAP_OPENSSL_CIPHERS "TLSv1.2:!NULL" 79 #ifndef COAP_OPENSSL_PSK_CIPHERS 80 #define COAP_OPENSSL_PSK_CIPHERS "PSK:!NULL" 87 HMAC_CTX *cookie_hmac;
92 typedef struct coap_tls_context_t {
100 typedef struct sni_entry {
102 #if OPENSSL_VERSION_NUMBER < 0x10101000L 109 typedef struct coap_openssl_context_t {
111 coap_tls_context_t tls;
115 sni_entry *sni_entry_list;
116 } coap_openssl_context_t;
119 if (SSLeay() < 0x10100000L) {
123 #if OPENSSL_VERSION_NUMBER >= 0x10101000L 131 if (SSLeay() < 0x10101000L) {
140 if (SSLeay() < 0x10100000L) {
144 #if OPENSSL_VERSION_NUMBER >= 0x10101000L 145 if (SSLeay() < 0x10101000L) {
163 SSL_load_error_strings();
170 dtls_log_level = level;
177 typedef struct coap_ssl_st {
185 static int coap_dgram_create(BIO *a) {
186 coap_ssl_data *data = NULL;
187 data = malloc(
sizeof(coap_ssl_data));
191 BIO_set_data(a, data);
192 memset(data, 0x00,
sizeof(coap_ssl_data));
196 static int coap_dgram_destroy(BIO *a) {
200 data = (coap_ssl_data *)BIO_get_data(a);
206 static int coap_dgram_read(BIO *a,
char *out,
int outl) {
208 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
211 if (data != NULL && data->pdu_len > 0) {
212 if (outl < (
int)data->pdu_len) {
213 memcpy(out, data->pdu, outl);
216 memcpy(out, data->pdu, data->pdu_len);
217 ret = (int)data->pdu_len;
219 if (!data->peekmode) {
226 BIO_clear_retry_flags(a);
228 BIO_set_retry_read(a);
233 static int coap_dgram_write(BIO *a,
const char *in,
int inl) {
235 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
238 if (data->session->sock.flags ==
COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
240 BIO_clear_retry_flags(a);
244 BIO_clear_retry_flags(a);
246 BIO_set_retry_write(a);
248 BIO_clear_retry_flags(a);
254 static int coap_dgram_puts(BIO *a,
const char *pstr) {
255 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
258 static long coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
260 coap_ssl_data *data = BIO_get_data(a);
265 case BIO_CTRL_GET_CLOSE:
266 ret = BIO_get_shutdown(a);
268 case BIO_CTRL_SET_CLOSE:
269 BIO_set_shutdown(a, (
int)num);
272 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
273 data->peekmode = (unsigned)num;
275 case BIO_CTRL_DGRAM_CONNECT:
278 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
279 case BIO_CTRL_DGRAM_GET_MTU:
280 case BIO_CTRL_DGRAM_SET_MTU:
281 case BIO_CTRL_DGRAM_QUERY_MTU:
282 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
287 case BIO_CTRL_DGRAM_MTU_DISCOVER:
288 case BIO_CTRL_DGRAM_SET_CONNECTED:
291 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
292 data->timeout =
coap_ticks_from_rt_us((uint64_t)((
struct timeval*)ptr)->tv_sec * 1000000 + ((
struct timeval*)ptr)->tv_usec);
296 case BIO_C_FILE_SEEK:
297 case BIO_C_FILE_TELL:
299 case BIO_CTRL_PENDING:
300 case BIO_CTRL_WPENDING:
301 case BIO_CTRL_DGRAM_GET_PEER:
302 case BIO_CTRL_DGRAM_SET_PEER:
303 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
304 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
305 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
306 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
307 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
308 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
309 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
310 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
318 static int coap_dtls_generate_cookie(SSL *ssl,
unsigned char *cookie,
unsigned int *cookie_len) {
320 coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
321 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
322 r &= HMAC_Update(dtls->cookie_hmac,
323 (
const uint8_t*)&data->session->addr_info.local.addr,
324 (
size_t)data->session->addr_info.local.size);
325 r &= HMAC_Update(dtls->cookie_hmac,
326 (
const uint8_t*)&data->session->addr_info.remote.addr,
327 (
size_t)data->session->addr_info.remote.size);
328 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
332 static int coap_dtls_verify_cookie(SSL *ssl,
const uint8_t *cookie,
unsigned int cookie_len) {
335 if (coap_dtls_generate_cookie(ssl, hmac, &len) && cookie_len == len && memcmp(cookie, hmac, len) == 0)
341 static unsigned coap_dtls_psk_client_callback(SSL *ssl,
const char *hint,
char *identity,
unsigned int max_identity_len,
unsigned char *buf,
unsigned max_len) {
342 size_t hint_len = 0, identity_len = 0, psk_len;
346 hint_len = strlen(hint);
356 if (identity_len < max_identity_len)
357 identity[identity_len] = 0;
358 return (
unsigned)psk_len;
361 static unsigned coap_dtls_psk_server_callback(SSL *ssl,
const char *identity,
unsigned char *buf,
unsigned max_len) {
362 size_t identity_len = 0;
366 identity_len = strlen(identity);
371 (
int)identity_len, identity);
379 static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
382 int w = where &~SSL_ST_MASK;
384 if (w & SSL_ST_CONNECT)
385 pstr =
"SSL_connect";
386 else if (w & SSL_ST_ACCEPT)
391 if (where & SSL_CB_LOOP) {
395 }
else if (where & SSL_CB_ALERT) {
396 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
401 SSL_alert_type_string_long(ret),
402 SSL_alert_desc_string_long(ret));
403 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL)
405 }
else if (where & SSL_CB_EXIT) {
411 while ((e = ERR_get_error()))
414 ERR_lib_error_string(e), ERR_func_error_string(e));
416 }
else if (ret < 0) {
418 int err = SSL_get_error(ssl, ret);
419 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) {
423 while ((e = ERR_get_error()))
426 ERR_lib_error_string(e), ERR_func_error_string(e));
432 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
436 static int coap_sock_create(BIO *a) {
441 static int coap_sock_destroy(BIO *a) {
446 static int coap_sock_read(BIO *a,
char *out,
int outl) {
453 BIO_set_retry_read(a);
456 BIO_clear_retry_flags(a);
462 static int coap_sock_write(BIO *a,
const char *in,
int inl) {
467 BIO_clear_retry_flags(a);
469 BIO_set_retry_read(a);
472 BIO_clear_retry_flags(a);
477 static int coap_sock_puts(BIO *a,
const char *pstr) {
478 return coap_sock_write(a, pstr, (
int)strlen(pstr));
481 static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
492 case BIO_CTRL_SET_CLOSE:
498 case BIO_CTRL_GET_CLOSE:
506 coap_openssl_context_t *context;
509 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
513 memset(context, 0,
sizeof(coap_openssl_context_t));
516 context->dtls.ctx = SSL_CTX_new(DTLS_method());
517 if (!context->dtls.ctx)
519 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
520 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
521 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
522 SSL_CTX_set_cipher_list(context->dtls.ctx, COAP_OPENSSL_CIPHERS);
523 memset(cookie_secret, 0,
sizeof(cookie_secret));
524 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
527 "Insufficient entropy for random cookie generation");
528 prng(cookie_secret,
sizeof(cookie_secret));
530 context->dtls.cookie_hmac = HMAC_CTX_new();
531 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
533 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
534 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
535 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
536 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
537 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
538 if (!context->dtls.meth)
540 context->dtls.bio_addr = BIO_ADDR_new();
541 if (!context->dtls.bio_addr)
543 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
544 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
545 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
546 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
547 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
548 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
551 context->tls.ctx = SSL_CTX_new(TLS_method());
552 if (!context->tls.ctx)
554 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
555 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
556 SSL_CTX_set_cipher_list(context->tls.ctx, COAP_OPENSSL_CIPHERS);
557 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
558 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
559 if (!context->tls.meth)
561 BIO_meth_set_write(context->tls.meth, coap_sock_write);
562 BIO_meth_set_read(context->tls.meth, coap_sock_read);
563 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
564 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
565 BIO_meth_set_create(context->tls.meth, coap_sock_create);
566 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
578 const char *identity_hint,
581 coap_openssl_context_t *context = ((coap_openssl_context_t *)ctx->
dtls_context);
585 SSL_CTX_set_psk_server_callback(context->dtls.ctx, coap_dtls_psk_server_callback);
586 SSL_CTX_set_psk_server_callback(context->tls.ctx, coap_dtls_psk_server_callback);
587 SSL_CTX_use_psk_identity_hint(context->dtls.ctx, identity_hint ? identity_hint :
"");
588 SSL_CTX_use_psk_identity_hint(context->tls.ctx, identity_hint ? identity_hint :
"");
590 if (!context->dtls.ssl) {
592 context->dtls.ssl = SSL_new(context->dtls.ctx);
593 if (!context->dtls.ssl)
595 bio = BIO_new(context->dtls.meth);
597 SSL_free (context->dtls.ssl);
598 context->dtls.ssl = NULL;
601 SSL_set_bio(context->dtls.ssl, bio, bio);
602 SSL_set_app_data(context->dtls.ssl, NULL);
603 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
606 context->psk_pki_enabled |= IS_PSK;
611 map_key_type(
int asn1_private_key_type
613 switch (asn1_private_key_type) {
631 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
632 asn1_private_key_type);
637 static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
640 server_alpn_callback (SSL *ssl
UNUSED,
641 const unsigned char **out,
642 unsigned char *outlen,
643 const unsigned char *in,
647 unsigned char *tout = NULL;
650 return SSL_TLSEXT_ERR_NOACK;
651 ret = SSL_select_next_proto(&tout,
658 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
662 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
667 while ((e = ERR_get_error()) != 0) {
670 if (!X509_STORE_add_cert(st, x509)) {
671 while ((e = ERR_get_error()) != 0) {
672 int r = ERR_GET_REASON(e);
673 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
676 ERR_reason_error_string(e),
677 ERR_lib_error_string(e),
678 ERR_func_error_string(e));
684 #if OPENSSL_VERSION_NUMBER < 0x10101000L 686 setup_pki_server(SSL_CTX *ctx,
693 if (!(SSL_CTX_use_certificate_file(ctx,
695 SSL_FILETYPE_PEM))) {
697 "*** setup_pki: (D)TLS: %s: Unable to configure " 698 "Server Certificate\n",
705 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
711 if (!(SSL_CTX_use_PrivateKey_file(ctx,
713 SSL_FILETYPE_PEM))) {
715 "*** setup_pki: (D)TLS: %s: Unable to configure " 716 "Server Private Key\n",
723 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
729 STACK_OF(X509_NAME) *cert_names;
735 if (cert_names != NULL)
736 SSL_CTX_set_client_CA_list(ctx, cert_names);
739 "*** setup_pki: (D)TLS: %s: Unable to configure " 744 st = SSL_CTX_get_cert_store(ctx);
745 in = BIO_new(BIO_s_file());
748 if (!BIO_read_filename(in, rw_var)) {
755 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
757 add_ca_to_cert_store(st, x);
767 if (!(SSL_CTX_use_certificate_ASN1(ctx,
771 "*** setup_pki: (D)TLS: %s: Unable to configure " 772 "Server Certificate\n",
779 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
786 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
790 "*** setup_pki: (D)TLS: %s: Unable to configure " 791 "Server Private Key\n",
798 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
808 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
810 "*** setup_pki: (D)TLS: %s: Unable to configure " 816 st = SSL_CTX_get_cert_store(ctx);
817 add_ca_to_cert_store(st, x509);
823 "*** setup_pki: (D)TLS: Unknown key type %d\n",
833 setup_pki_ssl(SSL *ssl,
840 if (!(SSL_use_certificate_file(ssl,
842 SSL_FILETYPE_PEM))) {
844 "*** setup_pki: (D)TLS: %s: Unable to configure " 855 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
861 if (!(SSL_use_PrivateKey_file(ssl,
863 SSL_FILETYPE_PEM))) {
865 "*** setup_pki: (D)TLS: %s: Unable to configure " 866 "Client Private Key\n",
875 "*** setup_pki: (D)TLS: No %s Private Key defined\n",
885 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
890 if (cert_names != NULL)
891 SSL_set_client_CA_list(ssl, cert_names);
894 "*** setup_pki: (D)TLS: %s: Unable to configure " 903 in = BIO_new(BIO_s_file());
906 if (!BIO_read_filename(in, rw_var)) {
911 st = SSL_CTX_get_cert_store(ctx);
913 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
915 add_ca_to_cert_store(st, x);
925 if (!(SSL_use_certificate_ASN1(ssl,
929 "*** setup_pki: (D)TLS: %s: Unable to configure " 940 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
947 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
951 "*** setup_pki: (D)TLS: %s: Unable to configure " 962 "*** setup_pki: (D)TLS: No %s Private Key defined",
972 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
975 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
977 "*** setup_pki: (D)TLS: %s: Unable to configure " 986 st = SSL_CTX_get_cert_store(ctx);
987 add_ca_to_cert_store(st, x509);
993 "*** setup_pki: (D)TLS: Unknown key type %d\n",
1001 get_san_or_cn_from_cert(X509* x509) {
1005 STACK_OF(GENERAL_NAME) *san_list;
1008 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
1010 int san_count = sk_GENERAL_NAME_num(san_list);
1012 for (n = 0; n < san_count; n++) {
1013 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
1015 if (name->type == GEN_DNS) {
1016 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1019 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
1021 cn = OPENSSL_strdup(dns_name);
1022 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1026 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1029 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
1032 n = strlen(buffer) - 3;
1035 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1036 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1045 char * ecn = strchr(cn,
'/');
1047 return OPENSSL_strndup(cn, ecn-cn);
1050 return OPENSSL_strdup(cn);
1058 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1059 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1060 SSL_get_ex_data_X509_STORE_CTX_idx());
1062 coap_openssl_context_t *context =
1065 int depth = X509_STORE_CTX_get_error_depth(ctx);
1066 int err = X509_STORE_CTX_get_error(ctx);
1067 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1068 char *cn = get_san_or_cn_from_cert(x509);
1069 int keep_preverify_ok = preverify_ok;
1071 if (!preverify_ok) {
1073 case X509_V_ERR_CERT_NOT_YET_VALID:
1074 case X509_V_ERR_CERT_HAS_EXPIRED:
1078 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1082 case X509_V_ERR_UNABLE_TO_GET_CRL:
1086 case X509_V_ERR_CRL_NOT_YET_VALID:
1087 case X509_V_ERR_CRL_HAS_EXPIRED:
1094 if (!preverify_ok) {
1096 " %s: %s: '%s' depth=%d\n",
1098 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1100 keep_preverify_ok = 1;
1104 " %s: %s: overridden: '%s' depth=%d\n",
1106 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1111 int length = i2d_X509(x509, NULL);
1113 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1116 i2d_X509(x509, &base_buf2);
1118 depth, preverify_ok,
1121 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1124 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1128 OPENSSL_free(base_buf);
1131 return preverify_ok;
1134 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1143 tls_secret_call_back(SSL *ssl,
1144 void *secret UNUSED,
1145 int *secretlen UNUSED,
1146 STACK_OF(SSL_CIPHER) *peer_ciphers,
1147 const SSL_CIPHER **cipher UNUSED,
1151 int psk_requested = 0;
1157 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1158 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1161 SSL_CIPHER_get_name(peer_cipher));
1162 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1168 if (!psk_requested) {
1180 SSL_VERIFY_CLIENT_ONCE |
1181 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1182 tls_verify_call_back);
1187 SSL_VERIFY_CLIENT_ONCE,
1188 tls_verify_call_back);
1192 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1201 X509_VERIFY_PARAM *param;
1203 param = X509_VERIFY_PARAM_new();
1204 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1205 SSL_set1_param(ssl, param);
1206 X509_VERIFY_PARAM_free(param);
1224 SSL_set_cipher_list (ssl, COAP_OPENSSL_PSK_CIPHERS);
1225 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1243 tls_server_name_call_back(SSL *ssl,
1250 return SSL_TLSEXT_ERR_NOACK;
1256 coap_openssl_context_t *context =
1258 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1261 if (!sni || !sni[0]) {
1264 for (i = 0; i < context->sni_count; i++) {
1265 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1269 if (i == context->sni_count) {
1275 return SSL_TLSEXT_ERR_ALERT_FATAL;
1280 ctx = SSL_CTX_new(DTLS_method());
1283 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1284 SSL_CTX_set_app_data(ctx, &context->dtls);
1285 SSL_CTX_set_read_ahead(ctx, 1);
1286 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1287 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1288 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1289 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1290 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1294 ctx = SSL_CTX_new(TLS_method());
1297 SSL_CTX_set_app_data(ctx, &context->tls);
1298 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1299 SSL_CTX_set_cipher_list(ctx, COAP_OPENSSL_CIPHERS);
1300 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1301 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1303 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1307 setup_pki_server(ctx, &sni_setup_data);
1309 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1310 (context->sni_count+1)*
sizeof(sni_entry));
1311 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1312 context->sni_entry_list[context->sni_count].ctx =
ctx;
1313 context->sni_count++;
1315 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1316 SSL_clear_options (ssl, 0xFFFFFFFFL);
1317 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1324 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1325 return SSL_TLSEXT_ERR_OK;
1328 return SSL_TLSEXT_ERR_ALERT_WARNING;
1340 tls_client_hello_call_back(SSL *ssl,
1345 coap_openssl_context_t *dtls_context;
1347 int psk_requested = 0;
1348 const unsigned char *out;
1352 *al = SSL_AD_INTERNAL_ERROR;
1353 return SSL_CLIENT_HELLO_ERROR;
1356 assert(session != NULL);
1357 assert(session->
context != NULL);
1360 setup_data = &dtls_context->setup_data;
1366 int len = SSL_client_hello_get0_ciphers(ssl, &out);
1367 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
1368 STACK_OF(SSL_CIPHER) *scsvc = NULL;
1370 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
1371 SSL_client_hello_isv2(ssl),
1372 &peer_ciphers, &scsvc)) {
1374 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1375 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1378 SSL_CIPHER_get_name(peer_cipher),
1379 SSL_CIPHER_get_protocol_id(peer_cipher));
1380 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1386 sk_SSL_CIPHER_free(peer_ciphers);
1387 sk_SSL_CIPHER_free(scsvc);
1390 if (psk_requested) {
1401 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1407 return SSL_CLIENT_HELLO_SUCCESS;
1417 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1420 for (ii = 0; ii < outlen; ii++) {
1436 *al = SSL_AD_UNSUPPORTED_EXTENSION;
1437 return SSL_CLIENT_HELLO_ERROR;
1446 coap_openssl_context_t *context =
1448 const char *sni =
"";
1449 char *sni_tmp = NULL;
1452 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1454 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1455 out[2] == TLSEXT_NAMETYPE_host_name &&
1456 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1460 sni_tmp = OPENSSL_malloc(outlen+1);
1461 sni_tmp[outlen] =
'\000';
1462 memcpy(sni_tmp, out, outlen);
1466 for (i = 0; i < context->sni_count; i++) {
1467 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1471 if (i == context->sni_count) {
1478 *al = SSL_AD_UNRECOGNIZED_NAME;
1479 return SSL_CLIENT_HELLO_ERROR;
1483 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1484 (context->sni_count+1)*
sizeof(sni_entry));
1485 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1486 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1487 context->sni_count++;
1490 OPENSSL_free(sni_tmp);
1492 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1493 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
1494 setup_pki_ssl(ssl, &sni_setup_data, 1);
1497 setup_pki_ssl(ssl, setup_data, 1);
1511 SSL_VERIFY_CLIENT_ONCE |
1512 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1513 tls_verify_call_back);
1518 SSL_VERIFY_CLIENT_ONCE,
1519 tls_verify_call_back);
1523 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1532 X509_VERIFY_PARAM *param;
1534 param = X509_VERIFY_PARAM_new();
1535 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1536 SSL_set1_param(ssl, param);
1537 X509_VERIFY_PARAM_free(param);
1544 return SSL_CLIENT_HELLO_SUCCESS;
1553 coap_openssl_context_t *context =
1558 context->setup_data = *setup_data;
1560 if (context->dtls.ctx) {
1562 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1563 if (!setup_pki_server(context->dtls.ctx, setup_data))
1572 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1573 if (SSLeay() >= 0x10101000L) {
1575 "OpenSSL compiled with %lux, linked with %lux, so " 1576 "no certificate checking\n",
1577 OPENSSL_VERSION_NUMBER, SSLeay());
1579 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1580 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1581 tls_server_name_call_back);
1583 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1584 tls_client_hello_call_back,
1588 if (context->tls.ctx) {
1590 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1591 if (!setup_pki_server(context->tls.ctx, setup_data))
1600 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1601 if (SSLeay() >= 0x10101000L) {
1603 "OpenSSL compiled with %lux, linked with %lux, so " 1604 "no certificate checking\n",
1605 OPENSSL_VERSION_NUMBER, SSLeay());
1607 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
1608 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1609 tls_server_name_call_back);
1611 SSL_CTX_set_client_hello_cb(context->tls.ctx,
1612 tls_client_hello_call_back,
1616 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1620 if (!context->dtls.ssl) {
1622 context->dtls.ssl = SSL_new(context->dtls.ctx);
1623 if (!context->dtls.ssl)
1625 bio = BIO_new(context->dtls.meth);
1627 SSL_free (context->dtls.ssl);
1628 context->dtls.ssl = NULL;
1631 SSL_set_bio(context->dtls.ssl, bio, bio);
1632 SSL_set_app_data(context->dtls.ssl, NULL);
1633 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1636 context->psk_pki_enabled |= IS_PKI;
1642 const char *ca_file,
1645 coap_openssl_context_t *context =
1647 if (context->dtls.ctx) {
1648 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1650 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1654 if (context->tls.ctx) {
1655 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1657 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1667 coap_openssl_context_t *context =
1669 return context->psk_pki_enabled ? 1 : 0;
1675 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1677 if (context->dtls.ssl)
1678 SSL_free(context->dtls.ssl);
1679 if (context->dtls.ctx)
1680 SSL_CTX_free(context->dtls.ctx);
1681 if (context->dtls.cookie_hmac)
1682 HMAC_CTX_free(context->dtls.cookie_hmac);
1683 if (context->dtls.meth)
1684 BIO_meth_free(context->dtls.meth);
1685 if (context->dtls.bio_addr)
1686 BIO_ADDR_free(context->dtls.bio_addr);
1687 if ( context->tls.ctx )
1688 SSL_CTX_free( context->tls.ctx );
1689 if ( context->tls.meth )
1690 BIO_meth_free( context->tls.meth );
1691 for (i = 0; i < context->sni_count; i++) {
1692 OPENSSL_free(context->sni_entry_list[i].sni);
1693 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1694 SSL_CTX_free(context->sni_entry_list[i].ctx);
1697 if (context->sni_count)
1698 OPENSSL_free(context->sni_entry_list);
1704 SSL *nssl = NULL, *ssl = NULL;
1705 coap_ssl_data *data;
1709 nssl = SSL_new(dtls->
ctx);
1712 nbio = BIO_new(dtls->meth);
1715 SSL_set_bio(nssl, nbio, nbio);
1716 SSL_set_app_data(nssl, NULL);
1717 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1718 SSL_set_mtu(nssl, session->
mtu);
1722 SSL_set_app_data(ssl, session);
1724 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1725 data->session = session;
1728 char hint[128] =
"";
1730 if (hint_len > 0 && hint_len <
sizeof(hint)) {
1732 SSL_use_psk_identity_hint(ssl, hint);
1736 r = SSL_accept(ssl);
1738 int err = SSL_get_error(ssl, r);
1739 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1759 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1761 if (context->psk_pki_enabled & IS_PSK) {
1762 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1763 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1764 SSL_set_cipher_list(ssl, COAP_OPENSSL_PSK_CIPHERS);
1766 if (context->psk_pki_enabled & IS_PKI) {
1768 if (!setup_pki_ssl(ssl, setup_data, 0))
1772 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1776 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
1782 X509_VERIFY_PARAM *param;
1784 param = X509_VERIFY_PARAM_new();
1785 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1786 SSL_set1_param(ssl, param);
1787 X509_VERIFY_PARAM_free(param);
1792 SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1794 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1807 coap_ssl_data *data;
1809 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1812 ssl = SSL_new(dtls->
ctx);
1815 bio = BIO_new(dtls->meth);
1818 data = (coap_ssl_data *)BIO_get_data(bio);
1819 data->session = session;
1820 SSL_set_bio(ssl, bio, bio);
1821 SSL_set_app_data(ssl, session);
1822 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1823 SSL_set_mtu(ssl, session->
mtu);
1825 if (!setup_client_ssl_session(session, ssl))
1830 r = SSL_connect(ssl);
1832 int ret = SSL_get_error(ssl, r);
1833 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1849 SSL *ssl = (SSL *)session->
tls;
1851 SSL_set_mtu(ssl, session->
mtu);
1855 SSL *ssl = (SSL *)session->
tls;
1857 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1858 int r = SSL_shutdown(ssl);
1859 if (r == 0) r = SSL_shutdown(ssl);
1862 session->
tls = NULL;
1869 const uint8_t *data,
size_t data_len) {
1871 SSL *ssl = (SSL *)session->
tls;
1873 assert(ssl != NULL);
1876 r = SSL_write(ssl, data, (
int)data_len);
1879 int err = SSL_get_error(ssl, r);
1880 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1884 if (err == SSL_ERROR_ZERO_RETURN)
1886 else if (err == SSL_ERROR_SSL)
1916 SSL *ssl = (SSL *)session->
tls;
1917 coap_ssl_data *ssl_data;
1919 assert(ssl != NULL);
1920 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1921 return ssl_data->timeout;
1925 SSL *ssl = (SSL *)session->
tls;
1927 assert(ssl != NULL);
1930 (DTLSv1_handle_timeout(ssl) < 0)) {
1937 const uint8_t *data,
size_t data_len) {
1939 coap_ssl_data *ssl_data;
1942 SSL_set_mtu(dtls->ssl, session->
mtu);
1943 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1944 ssl_data->session = session;
1945 ssl_data->pdu = data;
1946 ssl_data->pdu_len = (unsigned)data_len;
1947 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1949 int err = SSL_get_error(dtls->ssl, r);
1950 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1963 const uint8_t *data,
size_t data_len) {
1964 coap_ssl_data *ssl_data;
1965 SSL *ssl = (SSL *)session->
tls;
1968 assert(ssl != NULL);
1970 int in_init = SSL_in_init(ssl);
1972 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1973 ssl_data->pdu = data;
1974 ssl_data->pdu_len = (unsigned)data_len;
1977 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
1981 int err = SSL_get_error(ssl, r);
1982 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1983 if (in_init && SSL_is_init_finished(ssl)) {
1991 if (err == SSL_ERROR_ZERO_RETURN)
1993 else if (err == SSL_ERROR_SSL)
2013 unsigned int overhead = 37;
2014 const SSL_CIPHER *s_ciph = NULL;
2015 if (session->
tls != NULL)
2016 s_ciph = SSL_get_current_cipher(session->
tls);
2018 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
2020 const EVP_CIPHER *e_ciph;
2024 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
2026 switch (EVP_CIPHER_mode(e_ciph)) {
2027 case EVP_CIPH_GCM_MODE:
2028 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
2029 maclen = EVP_GCM_TLS_TAG_LEN;
2032 case EVP_CIPH_CCM_MODE:
2033 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
2034 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2035 if (strstr(cipher,
"CCM8"))
2041 case EVP_CIPH_CBC_MODE:
2042 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
2043 blocksize = EVP_CIPHER_block_size(e_ciph);
2044 ivlen = EVP_CIPHER_iv_length(e_ciph);
2046 maclen = EVP_MD_size(e_md);
2049 case EVP_CIPH_STREAM_CIPHER:
2056 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2063 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
2072 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2073 coap_tls_context_t *tls = &context->tls;
2076 ssl = SSL_new(tls->ctx);
2079 bio = BIO_new(tls->meth);
2082 BIO_set_data(bio, session);
2083 SSL_set_bio(ssl, bio, bio);
2084 SSL_set_app_data(ssl, session);
2086 if (!setup_client_ssl_session(session, ssl))
2089 r = SSL_connect(ssl);
2091 int ret = SSL_get_error(ssl, r);
2092 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2094 if (ret == SSL_ERROR_WANT_READ)
2096 if (ret == SSL_ERROR_WANT_WRITE) {
2098 #ifdef COAP_EPOLL_SUPPORT 2111 *connected = SSL_is_init_finished(ssl);
2124 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
2128 ssl = SSL_new(tls->ctx);
2131 bio = BIO_new(tls->meth);
2134 BIO_set_data(bio, session);
2135 SSL_set_bio(ssl, bio, bio);
2136 SSL_set_app_data(ssl, session);
2139 char hint[128] =
"";
2141 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2143 SSL_use_psk_identity_hint(ssl, hint);
2147 r = SSL_accept(ssl);
2149 int err = SSL_get_error(ssl, r);
2150 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2152 if (err == SSL_ERROR_WANT_READ)
2154 if (err == SSL_ERROR_WANT_WRITE) {
2156 #ifdef COAP_EPOLL_SUPPORT 2169 *connected = SSL_is_init_finished(ssl);
2180 SSL *ssl = (SSL *)session->
tls;
2182 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2183 int r = SSL_shutdown(ssl);
2184 if (r == 0) r = SSL_shutdown(ssl);
2187 session->
tls = NULL;
2197 SSL *ssl = (SSL *)session->
tls;
2203 in_init = !SSL_is_init_finished(ssl);
2205 r = SSL_write(ssl, data, (
int)data_len);
2208 int err = SSL_get_error(ssl, r);
2209 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2210 if (in_init && SSL_is_init_finished(ssl)) {
2216 if (err == SSL_ERROR_WANT_READ)
2218 if (err == SSL_ERROR_WANT_WRITE) {
2220 #ifdef COAP_EPOLL_SUPPORT 2232 if (err == SSL_ERROR_ZERO_RETURN)
2234 else if (err == SSL_ERROR_SSL)
2238 }
else if (in_init && SSL_is_init_finished(ssl)) {
2263 SSL *ssl = (SSL *)session->
tls;
2269 in_init = !SSL_is_init_finished(ssl);
2271 r = SSL_read(ssl, data, (
int)data_len);
2273 int err = SSL_get_error(ssl, r);
2274 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2275 if (in_init && SSL_is_init_finished(ssl)) {
2281 if (err == SSL_ERROR_WANT_READ)
2283 if (err == SSL_ERROR_WANT_WRITE) {
2285 #ifdef COAP_EPOLL_SUPPORT 2295 if (err == SSL_ERROR_ZERO_RETURN)
2297 else if (err == SSL_ERROR_SSL)
2301 }
else if (in_init && SSL_is_init_finished(ssl)) {
2328 #pragma GCC diagnostic ignored "-Wunused-function" unsigned mtu
path or CSM mtu
void coap_dtls_set_log_level(int level)
Sets the log level to the specified value.
void coap_dtls_free_session(struct coap_dtls_context_t *dtls_context, struct coap_dtls_session_t *session)
void coap_session_send_csm(coap_session_t *session)
Notify session transport has just connected and CSM exchange can now start.
#define COAP_SOCKET_EMPTY
coap_socket_flags_t values
int coap_dtls_hello(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
#define COAP_RXBUFFER_SIZE
uint8_t allow_self_signed
1 if self signed certs are allowed
void coap_tls_free_session(coap_session_t *coap_session UNUSED)
struct coap_context_t * context
session's context
The PKI key type is ASN.1 (DER)
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.
void * tls
security parameters
coap_pki_key_t key_type
key format type
#define COAP_SESSION_STATE_HANDSHAKE
int coap_dtls_receive(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
int coap_dtls_context_check_keys_enabled(coap_context_t *ctx UNUSED)
#define COAP_EVENT_DTLS_RENEGOTIATE
ssize_t coap_tls_read(coap_session_t *session UNUSED, uint8_t *data UNUSED, size_t data_len UNUSED)
void coap_epoll_ctl_mod(coap_socket_t *sock, uint32_t events, const char *func)
int coap_dtls_get_log_level(void)
Returns the current log level.
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Internal function invoked for server.
int coap_dtls_is_supported(void)
Returns 1 if support for DTLS is enabled, or 0 otherwise.
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, coap_dtls_pki_t *setup_data UNUSED, coap_dtls_role_t role UNUSED)
void * coap_tls_new_server_session(coap_session_t *session UNUSED, int *connected UNUSED)
ssize_t coap_tls_write(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len UNUSED)
void * sni_call_back_arg
Passed in to the sni call-back function.
ssize_t coap_socket_read(coap_socket_t *sock, uint8_t *data, size_t data_len)
ssize_t coap_session_send(coap_session_t *session, const uint8_t *data, size_t datalen)
Function interface for datagram data transmission.
int dtls_event
Tracking any (D)TLS events on this sesison.
uint8_t verify_peer_cert
Set to 1 to support this version of the struct.
uint8_t allow_no_crl
1 ignore if CRL not there
uint64_t version
(D)TLS runtime Library Version
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_sni_callback_t validate_sni_call_back
SNI check call-back function.
void * coap_tls_new_client_session(coap_session_t *session UNUSED, int *connected UNUSED)
const char * coap_session_str(const coap_session_t *session)
Get session description.
struct coap_dtls_context_t coap_dtls_context_t
unsigned int max_retransmit
maximum re-transmit count (default 4)
int coap_dtls_send(struct coap_context_t *coap_context, struct coap_dtls_session_t *session, const coap_pdu_t *pdu)
COAP_STATIC_INLINE void * coap_malloc(size_t size)
Wrapper function to coap_malloc_type() for backwards compatibility.
coap_dtls_security_setup_t additional_tls_setup_call_back
Additional Security call-back handler that is invoked when libcoap has done the standerd, defined validation checks at the TLS level, If not NULL, called from within the TLS Client Hello connection setup.
int coap_tls_is_supported(void)
Check whether TLS is available.
coap_tls_library_t type
Library type.
coap_tls_version_t * coap_get_tls_library_version(void)
Determine the type and version of the underlying (D)TLS library.
const char * private_key
File location of Private Key in PEM format.
uint8_t require_peer_cert
1 if peer cert is required
coap_proto_t proto
protocol used
coap_dtls_key_t pki_key
PKI key definition.
coap_pki_key_pem_t pem
for PEM keys
char * client_sni
If not NULL, SNI to use in client TLS setup.
uint64_t coap_tick_t
This data type represents internal timer ticks with COAP_TICKS_PER_SECOND resolution.
The structure that holds the PKI key information.
unsigned int coap_dtls_get_overhead(coap_session_t *session UNUSED)
const uint8_t * public_cert
ASN1 (DER) Public Cert.
const char * ca_file
File location of Common CA in PEM format.
size_t ca_cert_len
ASN1 CA Cert length.
coap_socket_t sock
socket object for the session, if any
ssize_t coap_socket_write(coap_socket_t *sock, const uint8_t *data, size_t data_len)
static int dtls_log_level
The structure used for returning the underlying (D)TLS library information.
#define COAP_EVENT_DTLS_CLOSED
(D)TLS events for COAP_PROTO_DTLS and COAP_PROTO_TLS
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_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, coap_dtls_role_t role UNUSED)
uint8_t cert_chain_validation
1 if to check cert_chain_verify_depth
COAP_STATIC_INLINE void coap_free(void *object)
Wrapper function to coap_free_type() for backwards compatibility.
union coap_dtls_key_t::@1 key
coap_session_state_t state
current state of relationaship with peer
const uint8_t * private_key
ASN1 (DER) Private Key.
coap_dtls_cn_callback_t validate_cn_call_back
CN check call-back function.
uint8_t allow_expired_certs
1 if expired certs are allowed
uint8_t check_cert_revocation
1 if revocation checks wanted
size_t(* get_server_hint)(const coap_session_t *session, uint8_t *hint, size_t max_hint_len)
#define COAP_EVENT_DTLS_ERROR
#define COAP_EVENT_DTLS_CONNECTED
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.
void * cn_call_back_arg
Passed in to the CN call-back function.
void * coap_dtls_new_server_session(coap_session_t *session UNUSED)
void coap_session_connected(coap_session_t *session)
Notify session that it has just connected or reconnected.
uint8_t allow_expired_crl
1 if expired crl is allowed
#define COAP_SOCKET_WANT_READ
non blocking socket is waiting for reading
The structure used for defining the PKI setup data to be used.
int coap_dtls_context_set_pki_root_cas(struct coap_context_t *ctx UNUSED, const char *ca_file UNUSED, const char *ca_path UNUSED)
coap_asn1_privatekey_type_t private_key_type
Private Key Type.
uint8_t cert_chain_verify_depth
recommended depth is 3
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)
coap_tick_t coap_ticks_from_rt_us(uint64_t t)
Helper function that converts POSIX wallclock time in us to coap ticks.
void coap_dtls_handle_timeout(coap_session_t *session UNUSED)
const char * public_cert
File location of Public Cert in PEM format.
void coap_dtls_startup(void)
Initialize the underlying (D)TLS Library layer.
coap_tick_t coap_dtls_get_timeout(coap_session_t *session UNUSED, coap_tick_t now UNUSED)
void coap_dtls_free_context(struct coap_dtls_context_t *dtls_context)
Releases the storage allocated for dtls_context.
coap_socket_flags_t flags
void coap_session_disconnected(coap_session_t *session, coap_nack_reason_t reason)
Notify session that it has failed.
#define coap_log(level,...)
Logging function.
const uint8_t * ca_cert
ASN1 (DER) Common CA Cert.
size_t public_cert_len
ASN1 Public Cert length.
#define prng(Buf, Length)
Fills Buf with Length bytes of random data.
coap_tick_t coap_dtls_get_context_timeout(void *dtls_context UNUSED)
uint64_t built_version
(D)TLS Built against Library Version
void coap_dtls_session_update_mtu(coap_session_t *session UNUSED)
unsigned int dtls_timeout_count
dtls setup retry counter
The CoAP stack's global state is stored in a coap_context_t object.
int coap_dtls_is_context_timeout(void)
Check if timeout is handled per CoAP session or per CoAP context.
size_t private_key_len
ASN1 Private Key length.
Pulls together all the internal only header files.
coap_pki_key_asn1_t asn1
for ASN.1 (DER) keys
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing