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 72 typedef struct coap_dtls_context_t {
75 HMAC_CTX *cookie_hmac;
78 } coap_dtls_context_t;
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 {
98 coap_dtls_context_t dtls;
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();
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) {
307 coap_dtls_context_t *dtls = (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl));
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,
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;
1678 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
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);
1782 coap_dtls_context_t *dtls = &context->dtls;
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) {
1906 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
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 (D)TLS logging level to the specified level.
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)
Get the current (D)TLS logging.
#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.
void coap_dtls_free_context(void *handle UNUSED)
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.
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,...
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)
void coap_dtls_free_session(coap_session_t *coap_session UNUSED)
#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.
int coap_dtls_send(coap_session_t *session UNUSED, const uint8_t *data UNUSED, size_t data_len 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.
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)
void * coap_dtls_new_context(struct coap_context_t *coap_context 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