11 #include "coap_config.h" 47 #include <openssl/ssl.h> 48 #include <openssl/err.h> 49 #include <openssl/rand.h> 50 #include <openssl/hmac.h> 51 #include <openssl/x509v3.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 75 HMAC_CTX *cookie_hmac;
80 typedef struct coap_tls_context_t {
88 typedef struct sni_entry {
90 #if OPENSSL_VERSION_NUMBER < 0x10101000L 97 typedef struct coap_openssl_context_t {
99 coap_tls_context_t tls;
103 sni_entry *sni_entry_list;
104 } coap_openssl_context_t;
107 if (SSLeay() < 0x10100000L) {
111 #if OPENSSL_VERSION_NUMBER >= 0x10101000L 119 if (SSLeay() < 0x10101000L) {
128 if (SSLeay() < 0x10100000L) {
132 #if OPENSSL_VERSION_NUMBER >= 0x10101000L 133 if (SSLeay() < 0x10101000L) {
151 SSL_load_error_strings();
158 dtls_log_level = level;
165 typedef struct coap_ssl_st {
173 static int coap_dgram_create(BIO *a) {
174 coap_ssl_data *data = NULL;
175 data = malloc(
sizeof(coap_ssl_data));
179 BIO_set_data(a, data);
180 memset(data, 0x00,
sizeof(coap_ssl_data));
184 static int coap_dgram_destroy(BIO *a) {
188 data = (coap_ssl_data *)BIO_get_data(a);
194 static int coap_dgram_read(BIO *a,
char *out,
int outl) {
196 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
199 if (data != NULL && data->pdu_len > 0) {
200 if (outl < (
int)data->pdu_len) {
201 memcpy(out, data->pdu, outl);
204 memcpy(out, data->pdu, data->pdu_len);
205 ret = (int)data->pdu_len;
207 if (!data->peekmode) {
214 BIO_clear_retry_flags(a);
216 BIO_set_retry_read(a);
221 static int coap_dgram_write(BIO *a,
const char *in,
int inl) {
223 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
226 if (data->session->sock.flags ==
COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
228 BIO_clear_retry_flags(a);
232 BIO_clear_retry_flags(a);
234 BIO_set_retry_write(a);
236 BIO_clear_retry_flags(a);
242 static int coap_dgram_puts(BIO *a,
const char *pstr) {
243 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
246 static long coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
248 coap_ssl_data *data = BIO_get_data(a);
253 case BIO_CTRL_GET_CLOSE:
254 ret = BIO_get_shutdown(a);
256 case BIO_CTRL_SET_CLOSE:
257 BIO_set_shutdown(a, (
int)num);
260 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
261 data->peekmode = (unsigned)num;
263 case BIO_CTRL_DGRAM_CONNECT:
266 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
267 case BIO_CTRL_DGRAM_GET_MTU:
268 case BIO_CTRL_DGRAM_SET_MTU:
269 case BIO_CTRL_DGRAM_QUERY_MTU:
270 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
275 case BIO_CTRL_DGRAM_MTU_DISCOVER:
276 case BIO_CTRL_DGRAM_SET_CONNECTED:
279 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
280 data->timeout =
coap_ticks_from_rt_us((uint64_t)((
struct timeval*)ptr)->tv_sec * 1000000 + ((
struct timeval*)ptr)->tv_usec);
284 case BIO_C_FILE_SEEK:
285 case BIO_C_FILE_TELL:
287 case BIO_CTRL_PENDING:
288 case BIO_CTRL_WPENDING:
289 case BIO_CTRL_DGRAM_GET_PEER:
290 case BIO_CTRL_DGRAM_SET_PEER:
291 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
292 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
293 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
294 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
295 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
296 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
297 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
298 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
306 static int coap_dtls_generate_cookie(SSL *ssl,
unsigned char *cookie,
unsigned int *cookie_len) {
308 coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
309 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
310 r &= HMAC_Update(dtls->cookie_hmac, (
const uint8_t*)&data->session->local_addr.addr, (
size_t)data->session->local_addr.size);
311 r &= HMAC_Update(dtls->cookie_hmac, (
const uint8_t*)&data->session->remote_addr.addr, (
size_t)data->session->remote_addr.size);
312 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
316 static int coap_dtls_verify_cookie(SSL *ssl,
const uint8_t *cookie,
unsigned int cookie_len) {
319 if (coap_dtls_generate_cookie(ssl, hmac, &len) && cookie_len == len && memcmp(cookie, hmac, len) == 0)
325 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) {
326 size_t hint_len = 0, identity_len = 0, psk_len;
330 hint_len = strlen(hint);
340 if (identity_len < max_identity_len)
341 identity[identity_len] = 0;
342 return (
unsigned)psk_len;
345 static unsigned coap_dtls_psk_server_callback(SSL *ssl,
const char *identity,
unsigned char *buf,
unsigned max_len) {
346 size_t identity_len = 0;
350 identity_len = strlen(identity);
355 (
int)identity_len, identity);
363 static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
366 int w = where &~SSL_ST_MASK;
368 if (w & SSL_ST_CONNECT)
369 pstr =
"SSL_connect";
370 else if (w & SSL_ST_ACCEPT)
375 if (where & SSL_CB_LOOP) {
379 }
else if (where & SSL_CB_ALERT) {
380 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
385 SSL_alert_type_string_long(ret),
386 SSL_alert_desc_string_long(ret));
387 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL)
389 }
else if (where & SSL_CB_EXIT) {
395 while ((e = ERR_get_error()))
398 ERR_lib_error_string(e), ERR_func_error_string(e));
400 }
else if (ret < 0) {
402 int err = SSL_get_error(ssl, ret);
403 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) {
407 while ((e = ERR_get_error()))
410 ERR_lib_error_string(e), ERR_func_error_string(e));
416 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
420 static int coap_sock_create(BIO *a) {
425 static int coap_sock_destroy(BIO *a) {
430 static int coap_sock_read(BIO *a,
char *out,
int outl) {
437 BIO_set_retry_read(a);
440 BIO_clear_retry_flags(a);
446 static int coap_sock_write(BIO *a,
const char *in,
int inl) {
451 BIO_clear_retry_flags(a);
453 BIO_set_retry_read(a);
456 BIO_clear_retry_flags(a);
461 static int coap_sock_puts(BIO *a,
const char *pstr) {
462 return coap_sock_write(a, pstr, (
int)strlen(pstr));
465 static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
476 case BIO_CTRL_SET_CLOSE:
482 case BIO_CTRL_GET_CLOSE:
490 coap_openssl_context_t *context;
493 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
497 memset(context, 0,
sizeof(coap_openssl_context_t));
500 context->dtls.ctx = SSL_CTX_new(DTLS_method());
501 if (!context->dtls.ctx)
503 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
504 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
505 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
506 SSL_CTX_set_cipher_list(context->dtls.ctx,
"TLSv1.2:TLSv1.0");
507 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
510 "Insufficient entropy for random cookie generation");
511 prng(cookie_secret,
sizeof(cookie_secret));
513 context->dtls.cookie_hmac = HMAC_CTX_new();
514 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
516 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
517 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
518 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
519 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
520 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
521 if (!context->dtls.meth)
523 context->dtls.bio_addr = BIO_ADDR_new();
524 if (!context->dtls.bio_addr)
526 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
527 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
528 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
529 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
530 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
531 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
534 context->tls.ctx = SSL_CTX_new(TLS_method());
535 if (!context->tls.ctx)
537 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
538 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
539 SSL_CTX_set_cipher_list(context->tls.ctx,
"TLSv1.2:TLSv1.0");
540 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
541 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
542 if (!context->tls.meth)
544 BIO_meth_set_write(context->tls.meth, coap_sock_write);
545 BIO_meth_set_read(context->tls.meth, coap_sock_read);
546 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
547 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
548 BIO_meth_set_create(context->tls.meth, coap_sock_create);
549 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
561 const char *identity_hint,
564 coap_openssl_context_t *context = ((coap_openssl_context_t *)ctx->
dtls_context);
568 SSL_CTX_set_psk_server_callback(context->dtls.ctx, coap_dtls_psk_server_callback);
569 SSL_CTX_set_psk_server_callback(context->tls.ctx, coap_dtls_psk_server_callback);
570 SSL_CTX_use_psk_identity_hint(context->dtls.ctx, identity_hint ? identity_hint :
"");
571 SSL_CTX_use_psk_identity_hint(context->tls.ctx, identity_hint ? identity_hint :
"");
573 if (!context->dtls.ssl) {
575 context->dtls.ssl = SSL_new(context->dtls.ctx);
576 if (!context->dtls.ssl)
578 bio = BIO_new(context->dtls.meth);
580 SSL_free (context->dtls.ssl);
581 context->dtls.ssl = NULL;
584 SSL_set_bio(context->dtls.ssl, bio, bio);
585 SSL_set_app_data(context->dtls.ssl, NULL);
586 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
589 context->psk_pki_enabled |= IS_PSK;
594 map_key_type(
int asn1_private_key_type
596 switch (asn1_private_key_type) {
614 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
615 asn1_private_key_type);
620 static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
623 server_alpn_callback (SSL *ssl
UNUSED,
624 const unsigned char **out,
625 unsigned char *outlen,
626 const unsigned char *in,
630 unsigned char *tout = NULL;
633 return SSL_TLSEXT_ERR_NOACK;
634 ret = SSL_select_next_proto(&tout,
641 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
645 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
650 while ((e = ERR_get_error()) != 0) {
653 if (!X509_STORE_add_cert(st, x509)) {
654 while ((e = ERR_get_error()) != 0) {
655 int r = ERR_GET_REASON(e);
656 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
659 ERR_reason_error_string(e),
660 ERR_lib_error_string(e),
661 ERR_func_error_string(e));
667 #if OPENSSL_VERSION_NUMBER < 0x10101000L 669 setup_pki_server(SSL_CTX *ctx,
676 if (!(SSL_CTX_use_certificate_file(ctx,
678 SSL_FILETYPE_PEM))) {
680 "*** setup_pki: (D)TLS: %s: Unable to configure " 681 "Server Certificate\n",
688 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
694 if (!(SSL_CTX_use_PrivateKey_file(ctx,
696 SSL_FILETYPE_PEM))) {
698 "*** setup_pki: (D)TLS: %s: Unable to configure " 699 "Server Private Key\n",
706 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
712 STACK_OF(X509_NAME) *cert_names;
718 if (cert_names != NULL)
719 SSL_CTX_set_client_CA_list(ctx, cert_names);
722 "*** setup_pki: (D)TLS: %s: Unable to configure " 727 st = SSL_CTX_get_cert_store(ctx);
728 in = BIO_new(BIO_s_file());
731 if (!BIO_read_filename(in, rw_var)) {
738 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
740 add_ca_to_cert_store(st, x);
750 if (!(SSL_CTX_use_certificate_ASN1(ctx,
754 "*** setup_pki: (D)TLS: %s: Unable to configure " 755 "Server Certificate\n",
762 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
769 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
773 "*** setup_pki: (D)TLS: %s: Unable to configure " 774 "Server Private Key\n",
781 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
791 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
793 "*** setup_pki: (D)TLS: %s: Unable to configure " 799 st = SSL_CTX_get_cert_store(ctx);
800 add_ca_to_cert_store(st, x509);
806 "*** setup_pki: (D)TLS: Unknown key type %d\n",
816 setup_pki_ssl(SSL *ssl,
823 if (!(SSL_use_certificate_file(ssl,
825 SSL_FILETYPE_PEM))) {
827 "*** setup_pki: (D)TLS: %s: Unable to configure " 838 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
844 if (!(SSL_use_PrivateKey_file(ssl,
846 SSL_FILETYPE_PEM))) {
848 "*** setup_pki: (D)TLS: %s: Unable to configure " 849 "Client Private Key\n",
858 "*** setup_pki: (D)TLS: No %s Private Key defined\n",
868 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
873 if (cert_names != NULL)
874 SSL_set_client_CA_list(ssl, cert_names);
877 "*** setup_pki: (D)TLS: %s: Unable to configure " 886 in = BIO_new(BIO_s_file());
889 if (!BIO_read_filename(in, rw_var)) {
894 st = SSL_CTX_get_cert_store(ctx);
896 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
898 add_ca_to_cert_store(st, x);
908 if (!(SSL_use_certificate_ASN1(ssl,
912 "*** setup_pki: (D)TLS: %s: Unable to configure " 923 "*** setup_pki: (D)TLS: No %s Certificate defined\n",
930 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
934 "*** setup_pki: (D)TLS: %s: Unable to configure " 945 "*** setup_pki: (D)TLS: No %s Private Key defined",
955 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
958 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
960 "*** setup_pki: (D)TLS: %s: Unable to configure " 969 st = SSL_CTX_get_cert_store(ctx);
970 add_ca_to_cert_store(st, x509);
976 "*** setup_pki: (D)TLS: Unknown key type %d\n",
984 get_common_name_from_cert(X509* x509) {
988 STACK_OF(GENERAL_NAME) *san_list;
991 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
993 int san_count = sk_GENERAL_NAME_num(san_list);
995 for (n = 0; n < san_count; n++) {
996 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
998 if (name->type == GEN_DNS) {
999 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
1002 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
1004 cn = OPENSSL_strdup(dns_name);
1005 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1009 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
1012 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
1015 n = strlen(buffer) - 3;
1018 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1019 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1028 char * ecn = strchr(cn,
'/');
1030 return OPENSSL_strndup(cn, ecn-cn);
1033 return OPENSSL_strdup(cn);
1041 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1042 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1043 SSL_get_ex_data_X509_STORE_CTX_idx());
1045 coap_openssl_context_t *context =
1048 int depth = X509_STORE_CTX_get_error_depth(ctx);
1049 int err = X509_STORE_CTX_get_error(ctx);
1050 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1051 char *cn = get_common_name_from_cert(x509);
1052 int keep_preverify_ok = preverify_ok;
1054 if (!preverify_ok) {
1056 case X509_V_ERR_CERT_NOT_YET_VALID:
1057 case X509_V_ERR_CERT_HAS_EXPIRED:
1061 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1065 case X509_V_ERR_UNABLE_TO_GET_CRL:
1069 case X509_V_ERR_CRL_NOT_YET_VALID:
1070 case X509_V_ERR_CRL_HAS_EXPIRED:
1077 if (!preverify_ok) {
1079 " %s: %s: '%s' depth=%d\n",
1081 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1083 keep_preverify_ok = 1;
1087 " %s: %s: overridden: '%s' depth=%d\n",
1089 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1094 int length = i2d_X509(x509, NULL);
1096 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1099 i2d_X509(x509, &base_buf2);
1101 depth, preverify_ok,
1104 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1107 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1111 OPENSSL_free(base_buf);
1114 return preverify_ok;
1117 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1126 tls_secret_call_back(SSL *ssl,
1127 void *secret UNUSED,
1128 int *secretlen UNUSED,
1129 STACK_OF(SSL_CIPHER) *peer_ciphers,
1130 const SSL_CIPHER **cipher UNUSED,
1134 int psk_requested = 0;
1140 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1141 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1143 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1149 if (!psk_requested) {
1161 SSL_VERIFY_CLIENT_ONCE |
1162 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1163 tls_verify_call_back);
1168 SSL_VERIFY_CLIENT_ONCE,
1169 tls_verify_call_back);
1173 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1182 X509_VERIFY_PARAM *param;
1184 param = X509_VERIFY_PARAM_new();
1185 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1186 SSL_set1_param(ssl, param);
1187 X509_VERIFY_PARAM_free(param);
1205 SSL_set_cipher_list (ssl,
"PSK:!NULL");
1206 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1224 tls_server_name_call_back(SSL *ssl,
1231 return SSL_TLSEXT_ERR_NOACK;
1237 coap_openssl_context_t *context =
1239 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1242 if (!sni || !sni[0]) {
1245 for (i = 0; i < context->sni_count; i++) {
1246 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1250 if (i == context->sni_count) {
1256 return SSL_TLSEXT_ERR_ALERT_FATAL;
1261 ctx = SSL_CTX_new(DTLS_method());
1264 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1265 SSL_CTX_set_app_data(ctx, &context->dtls);
1266 SSL_CTX_set_read_ahead(ctx, 1);
1267 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1268 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1269 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1270 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1271 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1275 ctx = SSL_CTX_new(TLS_method());
1278 SSL_CTX_set_app_data(ctx, &context->tls);
1279 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1280 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1281 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1282 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1284 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1288 setup_pki_server(ctx, &sni_setup_data);
1290 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1291 (context->sni_count+1)*
sizeof(sni_entry));
1292 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1293 context->sni_entry_list[context->sni_count].ctx =
ctx;
1294 context->sni_count++;
1296 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1297 SSL_clear_options (ssl, 0xFFFFFFFFL);
1298 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1305 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1306 return SSL_TLSEXT_ERR_OK;
1309 return SSL_TLSEXT_ERR_ALERT_WARNING;
1321 tls_client_hello_call_back(SSL *ssl,
1326 coap_openssl_context_t *dtls_context = (coap_openssl_context_t *)session->
context->
dtls_context;
1328 int psk_requested = 0;
1329 const unsigned char *out;
1333 *al = SSL_AD_INTERNAL_ERROR;
1334 return SSL_CLIENT_HELLO_ERROR;
1341 int len = SSL_client_hello_get0_ciphers(ssl, &out);
1342 STACK_OF(SSL_CIPHER) *peer_ciphers = NULL;
1343 STACK_OF(SSL_CIPHER) *scsvc = NULL;
1345 if (len && SSL_bytes_to_cipher_list(ssl, out, len,
1346 SSL_client_hello_isv2(ssl),
1347 &peer_ciphers, &scsvc)) {
1349 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1350 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1352 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1358 sk_SSL_CIPHER_free(peer_ciphers);
1359 sk_SSL_CIPHER_free(scsvc);
1362 if (psk_requested) {
1373 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1379 return SSL_CLIENT_HELLO_SUCCESS;
1389 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1392 for (ii = 0; ii < outlen; ii++) {
1408 *al = SSL_AD_UNSUPPORTED_EXTENSION;
1409 return SSL_CLIENT_HELLO_ERROR;
1418 coap_openssl_context_t *context =
1420 const char *sni =
"";
1421 char *sni_tmp = NULL;
1424 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1426 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1427 out[2] == TLSEXT_NAMETYPE_host_name &&
1428 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1432 sni_tmp = OPENSSL_malloc(outlen+1);
1433 sni_tmp[outlen] =
'\000';
1434 memcpy(sni_tmp, out, outlen);
1438 for (i = 0; i < context->sni_count; i++) {
1439 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1443 if (i == context->sni_count) {
1450 *al = SSL_AD_UNRECOGNIZED_NAME;
1451 return SSL_CLIENT_HELLO_ERROR;
1455 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1456 (context->sni_count+1)*
sizeof(sni_entry));
1457 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1458 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1459 context->sni_count++;
1462 OPENSSL_free(sni_tmp);
1464 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1465 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
1466 setup_pki_ssl(ssl, &sni_setup_data, 1);
1469 setup_pki_ssl(ssl, setup_data, 1);
1483 SSL_VERIFY_CLIENT_ONCE |
1484 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1485 tls_verify_call_back);
1490 SSL_VERIFY_CLIENT_ONCE,
1491 tls_verify_call_back);
1495 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1504 X509_VERIFY_PARAM *param;
1506 param = X509_VERIFY_PARAM_new();
1507 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1508 SSL_set1_param(ssl, param);
1509 X509_VERIFY_PARAM_free(param);
1516 return SSL_CLIENT_HELLO_SUCCESS;
1525 coap_openssl_context_t *context =
1530 context->setup_data = *setup_data;
1532 if (context->dtls.ctx) {
1534 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1535 if (!setup_pki_server(context->dtls.ctx, setup_data))
1544 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1545 if (SSLeay() >= 0x10101000L) {
1547 "OpenSSL compiled with %lux, linked with %lux, so " 1548 "no certificate checking\n",
1549 OPENSSL_VERSION_NUMBER, SSLeay());
1551 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1552 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1553 tls_server_name_call_back);
1555 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1556 tls_client_hello_call_back,
1560 if (context->tls.ctx) {
1562 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1563 if (!setup_pki_server(context->tls.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->tls.ctx, &context->setup_data);
1580 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1581 tls_server_name_call_back);
1583 SSL_CTX_set_client_hello_cb(context->tls.ctx,
1584 tls_client_hello_call_back,
1588 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1592 if (!context->dtls.ssl) {
1594 context->dtls.ssl = SSL_new(context->dtls.ctx);
1595 if (!context->dtls.ssl)
1597 bio = BIO_new(context->dtls.meth);
1599 SSL_free (context->dtls.ssl);
1600 context->dtls.ssl = NULL;
1603 SSL_set_bio(context->dtls.ssl, bio, bio);
1604 SSL_set_app_data(context->dtls.ssl, NULL);
1605 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1608 context->psk_pki_enabled |= IS_PKI;
1614 const char *ca_file,
1617 coap_openssl_context_t *context =
1619 if (context->dtls.ctx) {
1620 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1622 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1626 if (context->tls.ctx) {
1627 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1629 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1639 coap_openssl_context_t *context =
1641 return context->psk_pki_enabled ? 1 : 0;
1647 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1649 if (context->dtls.ssl)
1650 SSL_free(context->dtls.ssl);
1651 if (context->dtls.ctx)
1652 SSL_CTX_free(context->dtls.ctx);
1653 if (context->dtls.cookie_hmac)
1654 HMAC_CTX_free(context->dtls.cookie_hmac);
1655 if (context->dtls.meth)
1656 BIO_meth_free(context->dtls.meth);
1657 if (context->dtls.bio_addr)
1658 BIO_ADDR_free(context->dtls.bio_addr);
1659 if ( context->tls.ctx )
1660 SSL_CTX_free( context->tls.ctx );
1661 if ( context->tls.meth )
1662 BIO_meth_free( context->tls.meth );
1663 for (i = 0; i < context->sni_count; i++) {
1664 OPENSSL_free(context->sni_entry_list[i].sni);
1665 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1666 SSL_CTX_free(context->sni_entry_list[i].ctx);
1669 if (context->sni_count)
1670 OPENSSL_free(context->sni_entry_list);
1676 SSL *nssl = NULL, *ssl = NULL;
1677 coap_ssl_data *data;
1681 nssl = SSL_new(dtls->
ctx);
1684 nbio = BIO_new(dtls->meth);
1687 SSL_set_bio(nssl, nbio, nbio);
1688 SSL_set_app_data(nssl, NULL);
1689 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1690 SSL_set_mtu(nssl, session->
mtu);
1694 SSL_set_app_data(ssl, session);
1696 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1697 data->session = session;
1700 char hint[128] =
"";
1702 if (hint_len > 0 && hint_len <
sizeof(hint)) {
1704 SSL_use_psk_identity_hint(ssl, hint);
1708 r = SSL_accept(ssl);
1710 int err = SSL_get_error(ssl, r);
1711 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1731 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1733 if (context->psk_pki_enabled & IS_PSK) {
1734 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1735 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1736 SSL_set_cipher_list(ssl,
"PSK:!NULL");
1738 if (context->psk_pki_enabled & IS_PKI) {
1740 if (!setup_pki_ssl(ssl, setup_data, 0))
1744 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1748 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
1754 X509_VERIFY_PARAM *param;
1756 param = X509_VERIFY_PARAM_new();
1757 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1758 SSL_set1_param(ssl, param);
1759 X509_VERIFY_PARAM_free(param);
1764 SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1766 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1779 coap_ssl_data *data;
1781 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1784 ssl = SSL_new(dtls->
ctx);
1787 bio = BIO_new(dtls->meth);
1790 data = (coap_ssl_data *)BIO_get_data(bio);
1791 data->session = session;
1792 SSL_set_bio(ssl, bio, bio);
1793 SSL_set_app_data(ssl, session);
1794 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1795 SSL_set_mtu(ssl, session->
mtu);
1797 if (!setup_client_ssl_session(session, ssl))
1802 r = SSL_connect(ssl);
1804 int ret = SSL_get_error(ssl, r);
1805 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1821 SSL *ssl = (SSL *)session->
tls;
1823 SSL_set_mtu(ssl, session->
mtu);
1827 SSL *ssl = (SSL *)session->
tls;
1829 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1830 int r = SSL_shutdown(ssl);
1831 if (r == 0) r = SSL_shutdown(ssl);
1834 session->
tls = NULL;
1839 const uint8_t *data,
size_t data_len) {
1841 SSL *ssl = (SSL *)session->
tls;
1846 r = SSL_write(ssl, data, (
int)data_len);
1849 int err = SSL_get_error(ssl, r);
1850 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1854 if (err == SSL_ERROR_ZERO_RETURN)
1856 else if (err == SSL_ERROR_SSL)
1884 SSL *ssl = (SSL *)session->
tls;
1885 coap_ssl_data *ssl_data;
1888 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1889 return ssl_data->timeout;
1893 SSL *ssl = (SSL *)session->
tls;
1898 (DTLSv1_handle_timeout(ssl) < 0)) {
1905 const uint8_t *data,
size_t data_len) {
1907 coap_ssl_data *ssl_data;
1910 SSL_set_mtu(dtls->ssl, session->
mtu);
1911 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1912 ssl_data->session = session;
1913 ssl_data->pdu = data;
1914 ssl_data->pdu_len = (unsigned)data_len;
1915 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1917 int err = SSL_get_error(dtls->ssl, r);
1918 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1931 const uint8_t *data,
size_t data_len) {
1932 coap_ssl_data *ssl_data;
1933 SSL *ssl = (SSL *)session->
tls;
1938 int in_init = SSL_in_init(ssl);
1940 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1941 ssl_data->pdu = data;
1942 ssl_data->pdu_len = (unsigned)data_len;
1945 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
1949 int err = SSL_get_error(ssl, r);
1950 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1951 if (in_init && SSL_is_init_finished(ssl)) {
1957 if (err == SSL_ERROR_ZERO_RETURN)
1959 else if (err == SSL_ERROR_SSL)
1977 unsigned int overhead = 37;
1978 const SSL_CIPHER *s_ciph = NULL;
1979 if (session->
tls != NULL)
1980 s_ciph = SSL_get_current_cipher(session->
tls);
1982 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
1984 const EVP_CIPHER *e_ciph;
1988 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
1990 switch (EVP_CIPHER_mode(e_ciph)) {
1991 case EVP_CIPH_GCM_MODE:
1992 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
1993 maclen = EVP_GCM_TLS_TAG_LEN;
1996 case EVP_CIPH_CCM_MODE:
1997 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
1998 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
1999 if (strstr(cipher,
"CCM8"))
2005 case EVP_CIPH_CBC_MODE:
2006 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
2007 blocksize = EVP_CIPHER_block_size(e_ciph);
2008 ivlen = EVP_CIPHER_iv_length(e_ciph);
2010 maclen = EVP_MD_size(e_md);
2013 case EVP_CIPH_STREAM_CIPHER:
2020 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2027 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
2036 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2037 coap_tls_context_t *tls = &context->tls;
2040 ssl = SSL_new(tls->ctx);
2043 bio = BIO_new(tls->meth);
2046 BIO_set_data(bio, session);
2047 SSL_set_bio(ssl, bio, bio);
2048 SSL_set_app_data(ssl, session);
2050 if (!setup_client_ssl_session(session, ssl))
2053 r = SSL_connect(ssl);
2055 int ret = SSL_get_error(ssl, r);
2056 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2058 if (ret == SSL_ERROR_WANT_READ)
2060 if (ret == SSL_ERROR_WANT_WRITE)
2067 *connected = SSL_is_init_finished(ssl);
2080 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
2084 ssl = SSL_new(tls->ctx);
2087 bio = BIO_new(tls->meth);
2090 BIO_set_data(bio, session);
2091 SSL_set_bio(ssl, bio, bio);
2092 SSL_set_app_data(ssl, session);
2095 char hint[128] =
"";
2097 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2099 SSL_use_psk_identity_hint(ssl, hint);
2103 r = SSL_accept(ssl);
2105 int err = SSL_get_error(ssl, r);
2106 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2108 if (err == SSL_ERROR_WANT_READ)
2110 if (err == SSL_ERROR_WANT_WRITE)
2117 *connected = SSL_is_init_finished(ssl);
2128 SSL *ssl = (SSL *)session->
tls;
2130 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2131 int r = SSL_shutdown(ssl);
2132 if (r == 0) r = SSL_shutdown(ssl);
2135 session->
tls = NULL;
2143 SSL *ssl = (SSL *)session->
tls;
2149 in_init = !SSL_is_init_finished(ssl);
2151 r = SSL_write(ssl, data, (
int)data_len);
2154 int err = SSL_get_error(ssl, r);
2155 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2156 if (in_init && SSL_is_init_finished(ssl)) {
2160 if (err == SSL_ERROR_WANT_READ)
2162 if (err == SSL_ERROR_WANT_WRITE)
2168 if (err == SSL_ERROR_ZERO_RETURN)
2170 else if (err == SSL_ERROR_SSL)
2174 }
else if (in_init && SSL_is_init_finished(ssl)) {
2195 SSL *ssl = (SSL *)session->
tls;
2201 in_init = !SSL_is_init_finished(ssl);
2203 r = SSL_read(ssl, data, (
int)data_len);
2205 int err = SSL_get_error(ssl, r);
2206 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2207 if (in_init && SSL_is_init_finished(ssl)) {
2211 if (err == SSL_ERROR_WANT_READ)
2213 if (err == SSL_ERROR_WANT_WRITE)
2217 if (err == SSL_ERROR_ZERO_RETURN)
2219 else if (err == SSL_ERROR_SSL)
2223 }
else if (in_init && SSL_is_init_finished(ssl)) {
2246 #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_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)
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)
int coap_dtls_get_log_level(void)
Returns the current log level.
#define COAP_TLS_LIBRARY_OPENSSL
Using OpenSSL library.
void * coap_dtls_new_client_session(coap_session_t *session UNUSED)
Internal function invoked for server.
int coap_dtls_is_supported(void)
Check whether DTLS is available.
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_dtls_free_session(coap_dtls_session_t *session UNUSED)
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)
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_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
void coap_dtls_free_context(struct coap_dtls_context_t *dtls_context)
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.
struct coap_dtls_context_t * coap_dtls_new_context(struct coap_context_t *coap_context UNUSED)
uint8_t cert_chain_verify_depth
recommended depth is 3
coap_tick_t coap_dtls_get_timeout(coap_session_t *session UNUSED)
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.
int coap_dtls_send(struct coap_context_t *coap_context UNUSED, struct coap_dtls_session_t *session UNUSED, const unsigned char *data UNUSED, size_t data_len UNUSED)
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.
coap_pki_key_asn1_t asn1
for ASN.1 (DER) keys
#define COAP_SOCKET_WANT_WRITE
non blocking socket is waiting for writing