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) {
150 SSL_load_error_strings();
157 dtls_log_level = level;
164 typedef struct coap_ssl_st {
172 static int coap_dgram_create(BIO *a) {
173 coap_ssl_data *data = NULL;
174 data = malloc(
sizeof(coap_ssl_data));
178 BIO_set_data(a, data);
179 memset(data, 0x00,
sizeof(coap_ssl_data));
183 static int coap_dgram_destroy(BIO *a) {
187 data = (coap_ssl_data *)BIO_get_data(a);
193 static int coap_dgram_read(BIO *a,
char *out,
int outl) {
195 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
198 if (data != NULL && data->pdu_len > 0) {
199 if (outl < (
int)data->pdu_len) {
200 memcpy(out, data->pdu, outl);
203 memcpy(out, data->pdu, data->pdu_len);
204 ret = (int)data->pdu_len;
206 if (!data->peekmode) {
213 BIO_clear_retry_flags(a);
215 BIO_set_retry_read(a);
220 static int coap_dgram_write(BIO *a,
const char *in,
int inl) {
222 coap_ssl_data *data = (coap_ssl_data *)BIO_get_data(a);
225 if (data->session->sock.flags ==
COAP_SOCKET_EMPTY && data->session->endpoint == NULL) {
227 BIO_clear_retry_flags(a);
231 BIO_clear_retry_flags(a);
233 BIO_set_retry_write(a);
235 BIO_clear_retry_flags(a);
241 static int coap_dgram_puts(BIO *a,
const char *pstr) {
242 return coap_dgram_write(a, pstr, (
int)strlen(pstr));
245 static long coap_dgram_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
247 coap_ssl_data *data = BIO_get_data(a);
252 case BIO_CTRL_GET_CLOSE:
253 ret = BIO_get_shutdown(a);
255 case BIO_CTRL_SET_CLOSE:
256 BIO_set_shutdown(a, (
int)num);
259 case BIO_CTRL_DGRAM_SET_PEEK_MODE:
260 data->peekmode = (unsigned)num;
262 case BIO_CTRL_DGRAM_CONNECT:
265 case BIO_CTRL_DGRAM_SET_DONT_FRAG:
266 case BIO_CTRL_DGRAM_GET_MTU:
267 case BIO_CTRL_DGRAM_SET_MTU:
268 case BIO_CTRL_DGRAM_QUERY_MTU:
269 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
274 case BIO_CTRL_DGRAM_MTU_DISCOVER:
275 case BIO_CTRL_DGRAM_SET_CONNECTED:
278 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
279 data->timeout =
coap_ticks_from_rt_us((uint64_t)((
struct timeval*)ptr)->tv_sec * 1000000 + ((
struct timeval*)ptr)->tv_usec);
283 case BIO_C_FILE_SEEK:
284 case BIO_C_FILE_TELL:
286 case BIO_CTRL_PENDING:
287 case BIO_CTRL_WPENDING:
288 case BIO_CTRL_DGRAM_GET_PEER:
289 case BIO_CTRL_DGRAM_SET_PEER:
290 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
291 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
292 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
293 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
294 case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP:
295 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
296 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
297 case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD:
305 static int coap_dtls_generate_cookie(SSL *ssl,
unsigned char *cookie,
unsigned int *cookie_len) {
306 coap_dtls_context_t *dtls = (coap_dtls_context_t *)SSL_CTX_get_app_data(SSL_get_SSL_CTX(ssl));
307 coap_ssl_data *data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
308 int r = HMAC_Init_ex(dtls->cookie_hmac, NULL, 0, NULL, NULL);
309 r &= HMAC_Update(dtls->cookie_hmac, (
const uint8_t*)&data->session->local_addr.addr, (
size_t)data->session->local_addr.size);
310 r &= HMAC_Update(dtls->cookie_hmac, (
const uint8_t*)&data->session->remote_addr.addr, (
size_t)data->session->remote_addr.size);
311 r &= HMAC_Final(dtls->cookie_hmac, cookie, cookie_len);
315 static int coap_dtls_verify_cookie(SSL *ssl,
const uint8_t *cookie,
unsigned int cookie_len) {
318 if (coap_dtls_generate_cookie(ssl, hmac, &len) && cookie_len == len && memcmp(cookie, hmac, len) == 0)
324 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) {
325 size_t hint_len = 0, identity_len = 0, psk_len;
329 hint_len = strlen(hint);
339 if (identity_len < max_identity_len)
340 identity[identity_len] = 0;
341 return (
unsigned)psk_len;
344 static unsigned coap_dtls_psk_server_callback(SSL *ssl,
const char *identity,
unsigned char *buf,
unsigned max_len) {
345 size_t identity_len = 0;
349 identity_len = strlen(identity);
354 (
int)identity_len, identity);
362 static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
365 int w = where &~SSL_ST_MASK;
367 if (w & SSL_ST_CONNECT)
368 pstr =
"SSL_connect";
369 else if (w & SSL_ST_ACCEPT)
374 if (where & SSL_CB_LOOP) {
378 }
else if (where & SSL_CB_ALERT) {
379 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
384 SSL_alert_type_string_long(ret),
385 SSL_alert_desc_string_long(ret));
386 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL)
388 }
else if (where & SSL_CB_EXIT) {
394 while ((e = ERR_get_error()))
397 ERR_lib_error_string(e), ERR_func_error_string(e));
399 }
else if (ret < 0) {
401 int err = SSL_get_error(ssl, ret);
402 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) {
406 while ((e = ERR_get_error()))
409 ERR_lib_error_string(e), ERR_func_error_string(e));
415 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
419 static int coap_sock_create(BIO *a) {
424 static int coap_sock_destroy(BIO *a) {
429 static int coap_sock_read(BIO *a,
char *out,
int outl) {
436 BIO_set_retry_read(a);
439 BIO_clear_retry_flags(a);
445 static int coap_sock_write(BIO *a,
const char *in,
int inl) {
450 BIO_clear_retry_flags(a);
452 BIO_set_retry_read(a);
455 BIO_clear_retry_flags(a);
460 static int coap_sock_puts(BIO *a,
const char *pstr) {
461 return coap_sock_write(a, pstr, (
int)strlen(pstr));
464 static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
475 case BIO_CTRL_SET_CLOSE:
481 case BIO_CTRL_GET_CLOSE:
489 coap_openssl_context_t *context;
492 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
496 memset(context, 0,
sizeof(coap_openssl_context_t));
499 context->dtls.ctx = SSL_CTX_new(DTLS_method());
500 if (!context->dtls.ctx)
502 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
503 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
504 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
505 SSL_CTX_set_cipher_list(context->dtls.ctx,
"TLSv1.2:TLSv1.0");
506 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
509 "Insufficient entropy for random cookie generation");
510 prng(cookie_secret,
sizeof(cookie_secret));
512 context->dtls.cookie_hmac = HMAC_CTX_new();
513 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
515 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
516 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
517 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
518 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
519 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
520 if (!context->dtls.meth)
522 context->dtls.bio_addr = BIO_ADDR_new();
523 if (!context->dtls.bio_addr)
525 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
526 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
527 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
528 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
529 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
530 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
533 context->tls.ctx = SSL_CTX_new(TLS_method());
534 if (!context->tls.ctx)
536 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
537 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
538 SSL_CTX_set_cipher_list(context->tls.ctx,
"TLSv1.2:TLSv1.0");
539 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
540 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
541 if (!context->tls.meth)
543 BIO_meth_set_write(context->tls.meth, coap_sock_write);
544 BIO_meth_set_read(context->tls.meth, coap_sock_read);
545 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
546 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
547 BIO_meth_set_create(context->tls.meth, coap_sock_create);
548 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
560 const char *identity_hint,
563 coap_openssl_context_t *context = ((coap_openssl_context_t *)ctx->
dtls_context);
567 SSL_CTX_set_psk_server_callback(context->dtls.ctx, coap_dtls_psk_server_callback);
568 SSL_CTX_set_psk_server_callback(context->tls.ctx, coap_dtls_psk_server_callback);
569 SSL_CTX_use_psk_identity_hint(context->dtls.ctx, identity_hint ? identity_hint :
"");
570 SSL_CTX_use_psk_identity_hint(context->tls.ctx, identity_hint ? identity_hint :
"");
572 if (!context->dtls.ssl) {
574 context->dtls.ssl = SSL_new(context->dtls.ctx);
575 if (!context->dtls.ssl)
577 bio = BIO_new(context->dtls.meth);
579 SSL_free (context->dtls.ssl);
580 context->dtls.ssl = NULL;
583 SSL_set_bio(context->dtls.ssl, bio, bio);
584 SSL_set_app_data(context->dtls.ssl, NULL);
585 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
588 context->psk_pki_enabled |= IS_PSK;
593 map_key_type(
int asn1_private_key_type
595 switch (asn1_private_key_type) {
613 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
614 asn1_private_key_type);
619 static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
622 server_alpn_callback (SSL *ssl
UNUSED,
623 const unsigned char **out,
624 unsigned char *outlen,
625 const unsigned char *in,
629 unsigned char *tout = NULL;
632 return SSL_TLSEXT_ERR_NOACK;
633 ret = SSL_select_next_proto(&tout,
640 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
644 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
649 while ((e = ERR_get_error()) != 0) {
652 if (!X509_STORE_add_cert(st, x509)) {
653 while ((e = ERR_get_error()) != 0) {
654 int r = ERR_GET_REASON(e);
655 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
658 ERR_reason_error_string(e),
659 ERR_lib_error_string(e),
660 ERR_func_error_string(e));
666 #if OPENSSL_VERSION_NUMBER < 0x10101000L 668 setup_pki_server(SSL_CTX *ctx,
675 if (!(SSL_CTX_use_certificate_file(ctx,
677 SSL_FILETYPE_PEM))) {
679 "*** setup_pki: (D)TLS: %s: Unable to configure " 680 "Server Certificate\n",
687 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
693 if (!(SSL_CTX_use_PrivateKey_file(ctx,
695 SSL_FILETYPE_PEM))) {
697 "*** setup_pki: (D)TLS: %s: Unable to configure " 698 "Server Private Key\n",
705 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
711 STACK_OF(X509_NAME) *cert_names;
717 if (cert_names != NULL)
718 SSL_CTX_set_client_CA_list(ctx, cert_names);
721 "*** setup_pki: (D)TLS: %s: Unable to configure " 726 st = SSL_CTX_get_cert_store(ctx);
727 in = BIO_new(BIO_s_file());
730 if (!BIO_read_filename(in, rw_var)) {
737 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
739 add_ca_to_cert_store(st, x);
749 if (!(SSL_CTX_use_certificate_ASN1(ctx,
753 "*** setup_pki: (D)TLS: %s: Unable to configure " 754 "Server Certificate\n",
761 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
768 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
772 "*** setup_pki: (D)TLS: %s: Unable to configure " 773 "Server Private Key\n",
780 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
790 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
792 "*** setup_pki: (D)TLS: %s: Unable to configure " 798 st = SSL_CTX_get_cert_store(ctx);
799 add_ca_to_cert_store(st, x509);
805 "*** setup_pki: (D)TLS: Unknown key type %d\n",
815 setup_pki_ssl(SSL *ssl,
822 if (!(SSL_use_certificate_file(ssl,
824 SSL_FILETYPE_PEM))) {
826 "*** setup_pki: (D)TLS: %s: Unable to configure " 827 "Client Certificate\n",
834 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
839 if (!(SSL_use_PrivateKey_file(ssl,
841 SSL_FILETYPE_PEM))) {
843 "*** setup_pki: (D)TLS: %s: Unable to configure " 844 "Client Private Key\n",
851 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
860 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
865 if (cert_names != NULL)
866 SSL_set_client_CA_list(ssl, cert_names);
869 "*** setup_pki: (D)TLS: %s: Unable to configure " 877 in = BIO_new(BIO_s_file());
880 if (!BIO_read_filename(in, rw_var)) {
885 st = SSL_CTX_get_cert_store(ctx);
887 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
889 add_ca_to_cert_store(st, x);
899 if (!(SSL_use_certificate_ASN1(ssl,
903 "*** setup_pki: (D)TLS: %s: Unable to configure " 904 "Client Certificate\n",
911 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
917 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
921 "*** setup_pki: (D)TLS: %s: Unable to configure " 922 "Client Private Key\n",
929 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
938 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
941 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
943 "*** setup_pki: (D)TLS: %s: Unable to configure " 952 st = SSL_CTX_get_cert_store(ctx);
953 add_ca_to_cert_store(st, x509);
959 "*** setup_pki: (D)TLS: Unknown key type %d\n",
967 get_common_name_from_cert(X509* x509) {
971 STACK_OF(GENERAL_NAME) *san_list;
974 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
976 int san_count = sk_GENERAL_NAME_num(san_list);
978 for (n = 0; n < san_count; n++) {
979 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
981 if (name->type == GEN_DNS) {
982 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
985 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
987 cn = OPENSSL_strdup(dns_name);
988 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
992 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
995 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
998 n = strlen(buffer) - 3;
1001 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1002 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1011 char * ecn = strchr(cn,
'/');
1013 return OPENSSL_strndup(cn, ecn-cn);
1016 return OPENSSL_strdup(cn);
1024 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1025 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1026 SSL_get_ex_data_X509_STORE_CTX_idx());
1028 coap_openssl_context_t *context =
1031 int depth = X509_STORE_CTX_get_error_depth(ctx);
1032 int err = X509_STORE_CTX_get_error(ctx);
1033 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1034 char *cn = get_common_name_from_cert(x509);
1035 int keep_preverify_ok = preverify_ok;
1037 if (!preverify_ok) {
1039 case X509_V_ERR_CERT_NOT_YET_VALID:
1040 case X509_V_ERR_CERT_HAS_EXPIRED:
1044 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1048 case X509_V_ERR_UNABLE_TO_GET_CRL:
1052 case X509_V_ERR_CRL_NOT_YET_VALID:
1053 case X509_V_ERR_CRL_HAS_EXPIRED:
1060 if (!preverify_ok) {
1062 " %s: %s: '%s' depth=%d\n",
1064 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1066 keep_preverify_ok = 1;
1070 " %s: %s: overridden: '%s' depth=%d\n",
1072 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1077 int length = i2d_X509(x509, NULL);
1079 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1082 i2d_X509(x509, &base_buf2);
1084 depth, preverify_ok,
1087 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1090 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1094 OPENSSL_free(base_buf);
1097 return preverify_ok;
1100 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1109 tls_secret_call_back(SSL *ssl,
1110 void *secret UNUSED,
1111 int *secretlen UNUSED,
1112 STACK_OF(SSL_CIPHER) *peer_ciphers,
1113 const SSL_CIPHER **cipher UNUSED,
1117 int psk_requested = 0;
1123 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1124 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1126 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1132 if (!psk_requested) {
1144 SSL_VERIFY_CLIENT_ONCE |
1145 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1146 tls_verify_call_back);
1151 SSL_VERIFY_CLIENT_ONCE,
1152 tls_verify_call_back);
1156 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1165 X509_VERIFY_PARAM *param;
1167 param = X509_VERIFY_PARAM_new();
1168 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1169 SSL_set1_param(ssl, param);
1170 X509_VERIFY_PARAM_free(param);
1188 SSL_set_cipher_list (ssl,
"PSK:!NULL");
1189 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1207 tls_server_name_call_back(SSL *ssl,
1214 return SSL_TLSEXT_ERR_NOACK;
1220 coap_openssl_context_t *context =
1222 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1225 if (!sni || !sni[0]) {
1228 for (i = 0; i < context->sni_count; i++) {
1229 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1233 if (i == context->sni_count) {
1239 return SSL_TLSEXT_ERR_ALERT_FATAL;
1244 ctx = SSL_CTX_new(DTLS_method());
1247 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1248 SSL_CTX_set_app_data(ctx, &context->dtls);
1249 SSL_CTX_set_read_ahead(ctx, 1);
1250 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1251 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1252 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1253 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1254 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1258 ctx = SSL_CTX_new(TLS_method());
1261 SSL_CTX_set_app_data(ctx, &context->tls);
1262 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1263 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1264 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1265 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1267 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1271 setup_pki_server(ctx, &sni_setup_data);
1273 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1274 (context->sni_count+1)*
sizeof(sni_entry));
1275 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1276 context->sni_entry_list[context->sni_count].ctx = ctx;
1277 context->sni_count++;
1279 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1280 SSL_clear_options (ssl, 0xFFFFFFFFL);
1281 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1288 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1289 return SSL_TLSEXT_ERR_OK;
1292 return SSL_TLSEXT_ERR_ALERT_WARNING;
1304 tls_client_hello_call_back(SSL *ssl,
1309 coap_openssl_context_t *dtls_context = (coap_openssl_context_t *)session->
context->
dtls_context;
1311 int psk_requested = 0;
1312 const unsigned char *out;
1316 *al = SSL_AD_INTERNAL_ERROR;
1317 return SSL_CLIENT_HELLO_ERROR;
1324 int len = SSL_client_hello_get0_ciphers(ssl, &out);
1325 STACK_OF(SSL_CIPHER) *peer_ciphers;
1326 STACK_OF(SSL_CIPHER) *scsvc;
1329 len = SSL_bytes_to_cipher_list(ssl, out, len,
1330 SSL_client_hello_isv2(ssl),
1331 &peer_ciphers, &scsvc);
1332 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1333 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1335 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1340 sk_SSL_CIPHER_free(peer_ciphers);
1341 sk_SSL_CIPHER_free(scsvc);
1344 if (psk_requested) {
1355 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1361 return SSL_CLIENT_HELLO_SUCCESS;
1371 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1374 for (ii = 0; ii < outlen; ii++) {
1390 *al = SSL_AD_UNSUPPORTED_EXTENSION;
1391 return SSL_CLIENT_HELLO_ERROR;
1400 coap_openssl_context_t *context =
1402 const char *sni =
"";
1403 char *sni_tmp = NULL;
1406 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1408 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1409 out[2] == TLSEXT_NAMETYPE_host_name &&
1410 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1414 sni_tmp = OPENSSL_malloc(outlen+1);
1415 sni_tmp[outlen] =
'\000';
1416 memcpy(sni_tmp, out, outlen);
1420 for (i = 0; i < context->sni_count; i++) {
1421 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1425 if (i == context->sni_count) {
1432 *al = SSL_AD_UNRECOGNIZED_NAME;
1433 return SSL_CLIENT_HELLO_ERROR;
1437 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1438 (context->sni_count+1)*
sizeof(sni_entry));
1439 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1440 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1441 context->sni_count++;
1444 OPENSSL_free(sni_tmp);
1446 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1447 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
1448 setup_pki_ssl(ssl, &sni_setup_data, 1);
1451 setup_pki_ssl(ssl, setup_data, 1);
1465 SSL_VERIFY_CLIENT_ONCE |
1466 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1467 tls_verify_call_back);
1472 SSL_VERIFY_CLIENT_ONCE,
1473 tls_verify_call_back);
1477 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1486 X509_VERIFY_PARAM *param;
1488 param = X509_VERIFY_PARAM_new();
1489 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1490 SSL_set1_param(ssl, param);
1491 X509_VERIFY_PARAM_free(param);
1498 return SSL_CLIENT_HELLO_SUCCESS;
1507 coap_openssl_context_t *context =
1512 context->setup_data = *setup_data;
1514 if (context->dtls.ctx) {
1516 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1517 if (!setup_pki_server(context->dtls.ctx, setup_data))
1526 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1527 if (SSLeay() >= 0x10101000L) {
1529 "OpenSSL compiled with %lux, linked with %lux, so " 1530 "no certificate checking\n",
1531 OPENSSL_VERSION_NUMBER, SSLeay());
1533 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1534 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1535 tls_server_name_call_back);
1537 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1538 tls_client_hello_call_back,
1542 if (context->tls.ctx) {
1544 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1545 if (!setup_pki_server(context->tls.ctx, setup_data))
1554 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1555 if (SSLeay() >= 0x10101000L) {
1557 "OpenSSL compiled with %lux, linked with %lux, so " 1558 "no certificate checking\n",
1559 OPENSSL_VERSION_NUMBER, SSLeay());
1561 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
1562 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1563 tls_server_name_call_back);
1565 SSL_CTX_set_client_hello_cb(context->tls.ctx,
1566 tls_client_hello_call_back,
1570 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1574 if (!context->dtls.ssl) {
1576 context->dtls.ssl = SSL_new(context->dtls.ctx);
1577 if (!context->dtls.ssl)
1579 bio = BIO_new(context->dtls.meth);
1581 SSL_free (context->dtls.ssl);
1582 context->dtls.ssl = NULL;
1585 SSL_set_bio(context->dtls.ssl, bio, bio);
1586 SSL_set_app_data(context->dtls.ssl, NULL);
1587 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1590 context->psk_pki_enabled |= IS_PKI;
1596 const char *ca_file,
1599 coap_openssl_context_t *context =
1601 if (context->dtls.ctx) {
1602 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1604 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1608 if (context->tls.ctx) {
1609 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1611 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1621 coap_openssl_context_t *context =
1623 return context->psk_pki_enabled ? 1 : 0;
1629 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1631 if (context->dtls.ssl)
1632 SSL_free(context->dtls.ssl);
1633 if (context->dtls.ctx)
1634 SSL_CTX_free(context->dtls.ctx);
1635 if (context->dtls.cookie_hmac)
1636 HMAC_CTX_free(context->dtls.cookie_hmac);
1637 if (context->dtls.meth)
1638 BIO_meth_free(context->dtls.meth);
1639 if (context->dtls.bio_addr)
1640 BIO_ADDR_free(context->dtls.bio_addr);
1641 if ( context->tls.ctx )
1642 SSL_CTX_free( context->tls.ctx );
1643 if ( context->tls.meth )
1644 BIO_meth_free( context->tls.meth );
1645 for (i = 0; i < context->sni_count; i++) {
1646 OPENSSL_free(context->sni_entry_list[i].sni);
1647 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1648 SSL_CTX_free(context->sni_entry_list[i].ctx);
1651 if (context->sni_count)
1652 OPENSSL_free(context->sni_entry_list);
1658 SSL *nssl = NULL, *ssl = NULL;
1659 coap_ssl_data *data;
1660 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1663 nssl = SSL_new(dtls->ctx);
1666 nbio = BIO_new(dtls->meth);
1669 SSL_set_bio(nssl, nbio, nbio);
1670 SSL_set_app_data(nssl, NULL);
1671 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1672 SSL_set_mtu(nssl, session->
mtu);
1676 SSL_set_app_data(ssl, session);
1678 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1679 data->session = session;
1682 char hint[128] =
"";
1684 if (hint_len > 0 && hint_len <
sizeof(hint)) {
1686 SSL_use_psk_identity_hint(ssl, hint);
1690 r = SSL_accept(ssl);
1692 int err = SSL_get_error(ssl, r);
1693 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1713 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1715 if (context->psk_pki_enabled & IS_PSK) {
1716 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1717 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1718 SSL_set_cipher_list(ssl,
"PSK:!NULL");
1720 if (context->psk_pki_enabled & IS_PKI) {
1722 if (!setup_pki_ssl(ssl, setup_data, 0))
1726 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1730 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
1736 X509_VERIFY_PARAM *param;
1738 param = X509_VERIFY_PARAM_new();
1739 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1740 SSL_set1_param(ssl, param);
1741 X509_VERIFY_PARAM_free(param);
1746 SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1748 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1761 coap_ssl_data *data;
1763 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1764 coap_dtls_context_t *dtls = &context->dtls;
1766 ssl = SSL_new(dtls->ctx);
1769 bio = BIO_new(dtls->meth);
1772 data = (coap_ssl_data *)BIO_get_data(bio);
1773 data->session = session;
1774 SSL_set_bio(ssl, bio, bio);
1775 SSL_set_app_data(ssl, session);
1776 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1777 SSL_set_mtu(ssl, session->
mtu);
1779 if (!setup_client_ssl_session(session, ssl))
1784 r = SSL_connect(ssl);
1786 int ret = SSL_get_error(ssl, r);
1787 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1803 SSL *ssl = (SSL *)session->
tls;
1805 SSL_set_mtu(ssl, session->
mtu);
1809 SSL *ssl = (SSL *)session->
tls;
1811 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1812 int r = SSL_shutdown(ssl);
1813 if (r == 0) r = SSL_shutdown(ssl);
1816 session->
tls = NULL;
1821 const uint8_t *data,
size_t data_len) {
1823 SSL *ssl = (SSL *)session->
tls;
1828 r = SSL_write(ssl, data, (
int)data_len);
1831 int err = SSL_get_error(ssl, r);
1832 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1836 if (err == SSL_ERROR_ZERO_RETURN)
1838 else if (err == SSL_ERROR_SSL)
1866 SSL *ssl = (SSL *)session->
tls;
1867 coap_ssl_data *ssl_data;
1870 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1871 return ssl_data->timeout;
1875 SSL *ssl = (SSL *)session->
tls;
1880 (DTLSv1_handle_timeout(ssl) < 0)) {
1887 const uint8_t *data,
size_t data_len) {
1888 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1889 coap_ssl_data *ssl_data;
1892 SSL_set_mtu(dtls->ssl, session->
mtu);
1893 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1894 ssl_data->session = session;
1895 ssl_data->pdu = data;
1896 ssl_data->pdu_len = (unsigned)data_len;
1897 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1899 int err = SSL_get_error(dtls->ssl, r);
1900 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1913 const uint8_t *data,
size_t data_len) {
1914 coap_ssl_data *ssl_data;
1915 SSL *ssl = (SSL *)session->
tls;
1920 int in_init = SSL_in_init(ssl);
1922 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1923 ssl_data->pdu = data;
1924 ssl_data->pdu_len = (unsigned)data_len;
1927 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
1931 int err = SSL_get_error(ssl, r);
1932 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1933 if (in_init && SSL_is_init_finished(ssl)) {
1939 if (err == SSL_ERROR_ZERO_RETURN)
1941 else if (err == SSL_ERROR_SSL)
1959 unsigned int overhead = 37;
1960 const SSL_CIPHER *s_ciph = NULL;
1961 if (session->
tls != NULL)
1962 s_ciph = SSL_get_current_cipher(session->
tls);
1964 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
1966 const EVP_CIPHER *e_ciph;
1970 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
1972 switch (EVP_CIPHER_mode(e_ciph)) {
1973 case EVP_CIPH_GCM_MODE:
1974 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
1975 maclen = EVP_GCM_TLS_TAG_LEN;
1978 case EVP_CIPH_CCM_MODE:
1979 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
1980 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
1981 if (strstr(cipher,
"CCM8"))
1987 case EVP_CIPH_CBC_MODE:
1988 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
1989 blocksize = EVP_CIPHER_block_size(e_ciph);
1990 ivlen = EVP_CIPHER_iv_length(e_ciph);
1992 maclen = EVP_MD_size(e_md);
1995 case EVP_CIPH_STREAM_CIPHER:
2002 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2009 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
2018 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2019 coap_tls_context_t *tls = &context->tls;
2022 ssl = SSL_new(tls->ctx);
2025 bio = BIO_new(tls->meth);
2028 BIO_set_data(bio, session);
2029 SSL_set_bio(ssl, bio, bio);
2030 SSL_set_app_data(ssl, session);
2032 if (!setup_client_ssl_session(session, ssl))
2035 r = SSL_connect(ssl);
2037 int ret = SSL_get_error(ssl, r);
2038 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2040 if (ret == SSL_ERROR_WANT_READ)
2042 if (ret == SSL_ERROR_WANT_WRITE)
2049 *connected = SSL_is_init_finished(ssl);
2062 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
2066 ssl = SSL_new(tls->ctx);
2069 bio = BIO_new(tls->meth);
2072 BIO_set_data(bio, session);
2073 SSL_set_bio(ssl, bio, bio);
2074 SSL_set_app_data(ssl, session);
2077 char hint[128] =
"";
2079 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2081 SSL_use_psk_identity_hint(ssl, hint);
2085 r = SSL_accept(ssl);
2087 int err = SSL_get_error(ssl, r);
2088 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2090 if (err == SSL_ERROR_WANT_READ)
2092 if (err == SSL_ERROR_WANT_WRITE)
2099 *connected = SSL_is_init_finished(ssl);
2110 SSL *ssl = (SSL *)session->
tls;
2112 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2113 int r = SSL_shutdown(ssl);
2114 if (r == 0) r = SSL_shutdown(ssl);
2117 session->
tls = NULL;
2125 SSL *ssl = (SSL *)session->
tls;
2131 in_init = !SSL_is_init_finished(ssl);
2133 r = SSL_write(ssl, data, (
int)data_len);
2136 int err = SSL_get_error(ssl, r);
2137 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2138 if (in_init && SSL_is_init_finished(ssl)) {
2142 if (err == SSL_ERROR_WANT_READ)
2144 if (err == SSL_ERROR_WANT_WRITE)
2150 if (err == SSL_ERROR_ZERO_RETURN)
2152 else if (err == SSL_ERROR_SSL)
2156 }
else if (in_init && SSL_is_init_finished(ssl)) {
2177 SSL *ssl = (SSL *)session->
tls;
2183 in_init = !SSL_is_init_finished(ssl);
2185 r = SSL_read(ssl, data, (
int)data_len);
2187 int err = SSL_get_error(ssl, r);
2188 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2189 if (in_init && SSL_is_init_finished(ssl)) {
2193 if (err == SSL_ERROR_WANT_READ)
2195 if (err == SSL_ERROR_WANT_WRITE)
2199 if (err == SSL_ERROR_ZERO_RETURN)
2201 else if (err == SSL_ERROR_SSL)
2205 }
else if (in_init && SSL_is_init_finished(ssl)) {
2228 #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)
int coap_dtls_is_supported(void)
Check whether DTLS is available.
void coap_dtls_free_context(void *handle 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 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
Addtional 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.
int coap_dtls_context_set_pki(coap_context_t *ctx UNUSED, coap_dtls_pki_t *setup_data UNUSED, int server UNUSED)
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.
#define COAP_DTLS_ROLE_SERVER
Internal function invoked for server.
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.
int coap_dtls_context_set_psk(coap_context_t *ctx UNUSED, const char *hint UNUSED, int server UNUSED)
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.
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)
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