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();
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) {
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 " 828 "Client Certificate\n",
835 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
840 if (!(SSL_use_PrivateKey_file(ssl,
842 SSL_FILETYPE_PEM))) {
844 "*** setup_pki: (D)TLS: %s: Unable to configure " 845 "Client Private Key\n",
852 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
861 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
866 if (cert_names != NULL)
867 SSL_set_client_CA_list(ssl, cert_names);
870 "*** setup_pki: (D)TLS: %s: Unable to configure " 878 in = BIO_new(BIO_s_file());
881 if (!BIO_read_filename(in, rw_var)) {
886 st = SSL_CTX_get_cert_store(ctx);
888 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
890 add_ca_to_cert_store(st, x);
900 if (!(SSL_use_certificate_ASN1(ssl,
904 "*** setup_pki: (D)TLS: %s: Unable to configure " 905 "Client Certificate\n",
912 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
918 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
922 "*** setup_pki: (D)TLS: %s: Unable to configure " 923 "Client Private Key\n",
930 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
939 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
942 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
944 "*** setup_pki: (D)TLS: %s: Unable to configure " 953 st = SSL_CTX_get_cert_store(ctx);
954 add_ca_to_cert_store(st, x509);
960 "*** setup_pki: (D)TLS: Unknown key type %d\n",
968 get_common_name_from_cert(X509* x509) {
972 STACK_OF(GENERAL_NAME) *san_list;
975 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
977 int san_count = sk_GENERAL_NAME_num(san_list);
979 for (n = 0; n < san_count; n++) {
980 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
982 if (name->type == GEN_DNS) {
983 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
986 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
988 cn = OPENSSL_strdup(dns_name);
989 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
993 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
996 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
999 n = strlen(buffer) - 3;
1002 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
1003 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
1012 char * ecn = strchr(cn,
'/');
1014 return OPENSSL_strndup(cn, ecn-cn);
1017 return OPENSSL_strdup(cn);
1025 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1026 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1027 SSL_get_ex_data_X509_STORE_CTX_idx());
1029 coap_openssl_context_t *context =
1032 int depth = X509_STORE_CTX_get_error_depth(ctx);
1033 int err = X509_STORE_CTX_get_error(ctx);
1034 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1035 char *cn = get_common_name_from_cert(x509);
1036 int keep_preverify_ok = preverify_ok;
1038 if (!preverify_ok) {
1040 case X509_V_ERR_CERT_NOT_YET_VALID:
1041 case X509_V_ERR_CERT_HAS_EXPIRED:
1045 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1049 case X509_V_ERR_UNABLE_TO_GET_CRL:
1053 case X509_V_ERR_CRL_NOT_YET_VALID:
1054 case X509_V_ERR_CRL_HAS_EXPIRED:
1061 if (!preverify_ok) {
1063 " %s: %s: '%s' depth=%d\n",
1065 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1067 keep_preverify_ok = 1;
1071 " %s: %s: overridden: '%s' depth=%d\n",
1073 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1078 int length = i2d_X509(x509, NULL);
1080 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1083 i2d_X509(x509, &base_buf2);
1085 depth, preverify_ok,
1088 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1091 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1095 OPENSSL_free(base_buf);
1098 return preverify_ok;
1101 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1110 tls_secret_call_back(SSL *ssl,
1111 void *secret UNUSED,
1112 int *secretlen UNUSED,
1113 STACK_OF(SSL_CIPHER) *peer_ciphers,
1114 const SSL_CIPHER **cipher UNUSED,
1118 int psk_requested = 0;
1124 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1125 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1127 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1133 if (!psk_requested) {
1145 SSL_VERIFY_CLIENT_ONCE |
1146 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1147 tls_verify_call_back);
1152 SSL_VERIFY_CLIENT_ONCE,
1153 tls_verify_call_back);
1157 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1166 X509_VERIFY_PARAM *param;
1168 param = X509_VERIFY_PARAM_new();
1169 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1170 SSL_set1_param(ssl, param);
1171 X509_VERIFY_PARAM_free(param);
1189 SSL_set_cipher_list (ssl,
"PSK:!NULL");
1190 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1208 tls_server_name_call_back(SSL *ssl,
1215 return SSL_TLSEXT_ERR_NOACK;
1221 coap_openssl_context_t *context =
1223 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1226 if (!sni || !sni[0]) {
1229 for (i = 0; i < context->sni_count; i++) {
1230 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1234 if (i == context->sni_count) {
1240 return SSL_TLSEXT_ERR_ALERT_FATAL;
1245 ctx = SSL_CTX_new(DTLS_method());
1248 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1249 SSL_CTX_set_app_data(ctx, &context->dtls);
1250 SSL_CTX_set_read_ahead(ctx, 1);
1251 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1252 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1253 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1254 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1255 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1259 ctx = SSL_CTX_new(TLS_method());
1262 SSL_CTX_set_app_data(ctx, &context->tls);
1263 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1264 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1265 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1266 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1268 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1272 setup_pki_server(ctx, &sni_setup_data);
1274 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1275 (context->sni_count+1)*
sizeof(sni_entry));
1276 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1277 context->sni_entry_list[context->sni_count].ctx = ctx;
1278 context->sni_count++;
1280 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1281 SSL_clear_options (ssl, 0xFFFFFFFFL);
1282 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1289 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1290 return SSL_TLSEXT_ERR_OK;
1293 return SSL_TLSEXT_ERR_ALERT_WARNING;
1305 tls_client_hello_call_back(SSL *ssl,
1310 coap_openssl_context_t *dtls_context = (coap_openssl_context_t *)session->
context->
dtls_context;
1312 int psk_requested = 0;
1313 const unsigned char *out;
1317 *al = SSL_AD_INTERNAL_ERROR;
1318 return SSL_CLIENT_HELLO_ERROR;
1325 int len = SSL_client_hello_get0_ciphers(ssl, &out);
1326 STACK_OF(SSL_CIPHER) *peer_ciphers;
1327 STACK_OF(SSL_CIPHER) *scsvc;
1330 len = SSL_bytes_to_cipher_list(ssl, out, len,
1331 SSL_client_hello_isv2(ssl),
1332 &peer_ciphers, &scsvc);
1333 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1334 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1336 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1341 sk_SSL_CIPHER_free(peer_ciphers);
1342 sk_SSL_CIPHER_free(scsvc);
1345 if (psk_requested) {
1356 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1362 return SSL_CLIENT_HELLO_SUCCESS;
1372 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1375 for (ii = 0; ii < outlen; ii++) {
1391 *al = SSL_AD_UNSUPPORTED_EXTENSION;
1392 return SSL_CLIENT_HELLO_ERROR;
1401 coap_openssl_context_t *context =
1403 const char *sni =
"";
1404 char *sni_tmp = NULL;
1407 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1409 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1410 out[2] == TLSEXT_NAMETYPE_host_name &&
1411 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1415 sni_tmp = OPENSSL_malloc(outlen+1);
1416 sni_tmp[outlen] =
'\000';
1417 memcpy(sni_tmp, out, outlen);
1421 for (i = 0; i < context->sni_count; i++) {
1422 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1426 if (i == context->sni_count) {
1433 *al = SSL_AD_UNRECOGNIZED_NAME;
1434 return SSL_CLIENT_HELLO_ERROR;
1438 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1439 (context->sni_count+1)*
sizeof(sni_entry));
1440 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1441 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1442 context->sni_count++;
1445 OPENSSL_free(sni_tmp);
1447 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1448 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
1449 setup_pki_ssl(ssl, &sni_setup_data, 1);
1452 setup_pki_ssl(ssl, setup_data, 1);
1466 SSL_VERIFY_CLIENT_ONCE |
1467 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1468 tls_verify_call_back);
1473 SSL_VERIFY_CLIENT_ONCE,
1474 tls_verify_call_back);
1478 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1487 X509_VERIFY_PARAM *param;
1489 param = X509_VERIFY_PARAM_new();
1490 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1491 SSL_set1_param(ssl, param);
1492 X509_VERIFY_PARAM_free(param);
1499 return SSL_CLIENT_HELLO_SUCCESS;
1508 coap_openssl_context_t *context =
1513 context->setup_data = *setup_data;
1515 if (context->dtls.ctx) {
1517 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1518 if (!setup_pki_server(context->dtls.ctx, setup_data))
1527 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1528 if (SSLeay() >= 0x10101000L) {
1530 "OpenSSL compiled with %lux, linked with %lux, so " 1531 "no certificate checking\n",
1532 OPENSSL_VERSION_NUMBER, SSLeay());
1534 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1535 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1536 tls_server_name_call_back);
1538 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1539 tls_client_hello_call_back,
1543 if (context->tls.ctx) {
1545 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1546 if (!setup_pki_server(context->tls.ctx, setup_data))
1555 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1556 if (SSLeay() >= 0x10101000L) {
1558 "OpenSSL compiled with %lux, linked with %lux, so " 1559 "no certificate checking\n",
1560 OPENSSL_VERSION_NUMBER, SSLeay());
1562 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
1563 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1564 tls_server_name_call_back);
1566 SSL_CTX_set_client_hello_cb(context->tls.ctx,
1567 tls_client_hello_call_back,
1571 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1575 if (!context->dtls.ssl) {
1577 context->dtls.ssl = SSL_new(context->dtls.ctx);
1578 if (!context->dtls.ssl)
1580 bio = BIO_new(context->dtls.meth);
1582 SSL_free (context->dtls.ssl);
1583 context->dtls.ssl = NULL;
1586 SSL_set_bio(context->dtls.ssl, bio, bio);
1587 SSL_set_app_data(context->dtls.ssl, NULL);
1588 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1591 context->psk_pki_enabled |= IS_PKI;
1597 const char *ca_file,
1600 coap_openssl_context_t *context =
1602 if (context->dtls.ctx) {
1603 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1605 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1609 if (context->tls.ctx) {
1610 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1612 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1622 coap_openssl_context_t *context =
1624 return context->psk_pki_enabled ? 1 : 0;
1630 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1632 if (context->dtls.ssl)
1633 SSL_free(context->dtls.ssl);
1634 if (context->dtls.ctx)
1635 SSL_CTX_free(context->dtls.ctx);
1636 if (context->dtls.cookie_hmac)
1637 HMAC_CTX_free(context->dtls.cookie_hmac);
1638 if (context->dtls.meth)
1639 BIO_meth_free(context->dtls.meth);
1640 if (context->dtls.bio_addr)
1641 BIO_ADDR_free(context->dtls.bio_addr);
1642 if ( context->tls.ctx )
1643 SSL_CTX_free( context->tls.ctx );
1644 if ( context->tls.meth )
1645 BIO_meth_free( context->tls.meth );
1646 for (i = 0; i < context->sni_count; i++) {
1647 OPENSSL_free(context->sni_entry_list[i].sni);
1648 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1649 SSL_CTX_free(context->sni_entry_list[i].ctx);
1652 if (context->sni_count)
1653 OPENSSL_free(context->sni_entry_list);
1659 SSL *nssl = NULL, *ssl = NULL;
1660 coap_ssl_data *data;
1661 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1664 nssl = SSL_new(dtls->ctx);
1667 nbio = BIO_new(dtls->meth);
1670 SSL_set_bio(nssl, nbio, nbio);
1671 SSL_set_app_data(nssl, NULL);
1672 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1673 SSL_set_mtu(nssl, session->
mtu);
1677 SSL_set_app_data(ssl, session);
1679 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1680 data->session = session;
1683 char hint[128] =
"";
1685 if (hint_len > 0 && hint_len <
sizeof(hint)) {
1687 SSL_use_psk_identity_hint(ssl, hint);
1691 r = SSL_accept(ssl);
1693 int err = SSL_get_error(ssl, r);
1694 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1714 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1716 if (context->psk_pki_enabled & IS_PSK) {
1717 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1718 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1719 SSL_set_cipher_list(ssl,
"PSK:!NULL");
1721 if (context->psk_pki_enabled & IS_PKI) {
1723 if (!setup_pki_ssl(ssl, setup_data, 0))
1727 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1731 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
1737 X509_VERIFY_PARAM *param;
1739 param = X509_VERIFY_PARAM_new();
1740 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1741 SSL_set1_param(ssl, param);
1742 X509_VERIFY_PARAM_free(param);
1747 SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1749 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1762 coap_ssl_data *data;
1764 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1765 coap_dtls_context_t *dtls = &context->dtls;
1767 ssl = SSL_new(dtls->ctx);
1770 bio = BIO_new(dtls->meth);
1773 data = (coap_ssl_data *)BIO_get_data(bio);
1774 data->session = session;
1775 SSL_set_bio(ssl, bio, bio);
1776 SSL_set_app_data(ssl, session);
1777 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1778 SSL_set_mtu(ssl, session->
mtu);
1780 if (!setup_client_ssl_session(session, ssl))
1785 r = SSL_connect(ssl);
1787 int ret = SSL_get_error(ssl, r);
1788 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1804 SSL *ssl = (SSL *)session->
tls;
1806 SSL_set_mtu(ssl, session->
mtu);
1810 SSL *ssl = (SSL *)session->
tls;
1812 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1813 int r = SSL_shutdown(ssl);
1814 if (r == 0) r = SSL_shutdown(ssl);
1817 session->
tls = NULL;
1822 const uint8_t *data,
size_t data_len) {
1824 SSL *ssl = (SSL *)session->
tls;
1829 r = SSL_write(ssl, data, (
int)data_len);
1832 int err = SSL_get_error(ssl, r);
1833 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1837 if (err == SSL_ERROR_ZERO_RETURN)
1839 else if (err == SSL_ERROR_SSL)
1867 SSL *ssl = (SSL *)session->
tls;
1868 coap_ssl_data *ssl_data;
1871 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1872 return ssl_data->timeout;
1876 SSL *ssl = (SSL *)session->
tls;
1881 (DTLSv1_handle_timeout(ssl) < 0)) {
1888 const uint8_t *data,
size_t data_len) {
1889 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1890 coap_ssl_data *ssl_data;
1893 SSL_set_mtu(dtls->ssl, session->
mtu);
1894 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1895 ssl_data->session = session;
1896 ssl_data->pdu = data;
1897 ssl_data->pdu_len = (unsigned)data_len;
1898 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1900 int err = SSL_get_error(dtls->ssl, r);
1901 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1914 const uint8_t *data,
size_t data_len) {
1915 coap_ssl_data *ssl_data;
1916 SSL *ssl = (SSL *)session->
tls;
1921 int in_init = SSL_in_init(ssl);
1923 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1924 ssl_data->pdu = data;
1925 ssl_data->pdu_len = (unsigned)data_len;
1928 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
1932 int err = SSL_get_error(ssl, r);
1933 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1934 if (in_init && SSL_is_init_finished(ssl)) {
1940 if (err == SSL_ERROR_ZERO_RETURN)
1942 else if (err == SSL_ERROR_SSL)
1960 unsigned int overhead = 37;
1961 const SSL_CIPHER *s_ciph = NULL;
1962 if (session->
tls != NULL)
1963 s_ciph = SSL_get_current_cipher(session->
tls);
1965 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
1967 const EVP_CIPHER *e_ciph;
1971 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
1973 switch (EVP_CIPHER_mode(e_ciph)) {
1974 case EVP_CIPH_GCM_MODE:
1975 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
1976 maclen = EVP_GCM_TLS_TAG_LEN;
1979 case EVP_CIPH_CCM_MODE:
1980 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
1981 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
1982 if (strstr(cipher,
"CCM8"))
1988 case EVP_CIPH_CBC_MODE:
1989 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
1990 blocksize = EVP_CIPHER_block_size(e_ciph);
1991 ivlen = EVP_CIPHER_iv_length(e_ciph);
1993 maclen = EVP_MD_size(e_md);
1996 case EVP_CIPH_STREAM_CIPHER:
2003 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
2010 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
2019 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
2020 coap_tls_context_t *tls = &context->tls;
2023 ssl = SSL_new(tls->ctx);
2026 bio = BIO_new(tls->meth);
2029 BIO_set_data(bio, session);
2030 SSL_set_bio(ssl, bio, bio);
2031 SSL_set_app_data(ssl, session);
2033 if (!setup_client_ssl_session(session, ssl))
2036 r = SSL_connect(ssl);
2038 int ret = SSL_get_error(ssl, r);
2039 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2041 if (ret == SSL_ERROR_WANT_READ)
2043 if (ret == SSL_ERROR_WANT_WRITE)
2050 *connected = SSL_is_init_finished(ssl);
2063 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
2067 ssl = SSL_new(tls->ctx);
2070 bio = BIO_new(tls->meth);
2073 BIO_set_data(bio, session);
2074 SSL_set_bio(ssl, bio, bio);
2075 SSL_set_app_data(ssl, session);
2078 char hint[128] =
"";
2080 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2082 SSL_use_psk_identity_hint(ssl, hint);
2086 r = SSL_accept(ssl);
2088 int err = SSL_get_error(ssl, r);
2089 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2091 if (err == SSL_ERROR_WANT_READ)
2093 if (err == SSL_ERROR_WANT_WRITE)
2100 *connected = SSL_is_init_finished(ssl);
2111 SSL *ssl = (SSL *)session->
tls;
2113 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2114 int r = SSL_shutdown(ssl);
2115 if (r == 0) r = SSL_shutdown(ssl);
2118 session->
tls = NULL;
2126 SSL *ssl = (SSL *)session->
tls;
2132 in_init = !SSL_is_init_finished(ssl);
2134 r = SSL_write(ssl, data, (
int)data_len);
2137 int err = SSL_get_error(ssl, r);
2138 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2139 if (in_init && SSL_is_init_finished(ssl)) {
2143 if (err == SSL_ERROR_WANT_READ)
2145 if (err == SSL_ERROR_WANT_WRITE)
2151 if (err == SSL_ERROR_ZERO_RETURN)
2153 else if (err == SSL_ERROR_SSL)
2157 }
else if (in_init && SSL_is_init_finished(ssl)) {
2178 SSL *ssl = (SSL *)session->
tls;
2184 in_init = !SSL_is_init_finished(ssl);
2186 r = SSL_read(ssl, data, (
int)data_len);
2188 int err = SSL_get_error(ssl, r);
2189 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2190 if (in_init && SSL_is_init_finished(ssl)) {
2194 if (err == SSL_ERROR_WANT_READ)
2196 if (err == SSL_ERROR_WANT_WRITE)
2200 if (err == SSL_ERROR_ZERO_RETURN)
2202 else if (err == SSL_ERROR_SSL)
2206 }
else if (in_init && SSL_is_init_finished(ssl)) {
2229 #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 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, 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)
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