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 " 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,
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
Addtional Security call-back handler that is invoked when libcoap has done the standerd,...
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