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);
361 static void coap_dtls_info_callback(
const SSL *ssl,
int where,
int ret) {
364 int w = where &~SSL_ST_MASK;
366 if (w & SSL_ST_CONNECT)
367 pstr =
"SSL_connect";
368 else if (w & SSL_ST_ACCEPT)
373 if (where & SSL_CB_LOOP) {
376 }
else if (where & SSL_CB_ALERT) {
377 pstr = (where & SSL_CB_READ) ?
"read" :
"write";
382 SSL_alert_type_string_long(ret),
383 SSL_alert_desc_string_long(ret));
384 if ((where & (SSL_CB_WRITE|SSL_CB_READ)) && (ret >> 8) == SSL3_AL_FATAL)
386 }
else if (where & SSL_CB_EXIT) {
391 while ((e = ERR_get_error()))
394 }
else if (ret < 0) {
396 int err = SSL_get_error(ssl, ret);
397 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) {
400 while ((e = ERR_get_error()))
407 if (where == SSL_CB_HANDSHAKE_START && SSL_get_state(ssl) == TLS_ST_OK)
411 static int coap_sock_create(BIO *a) {
416 static int coap_sock_destroy(BIO *a) {
421 static int coap_sock_read(BIO *a,
char *out,
int outl) {
428 BIO_set_retry_read(a);
431 BIO_clear_retry_flags(a);
437 static int coap_sock_write(BIO *a,
const char *in,
int inl) {
442 BIO_clear_retry_flags(a);
444 BIO_set_retry_read(a);
447 BIO_clear_retry_flags(a);
452 static int coap_sock_puts(BIO *a,
const char *pstr) {
453 return coap_sock_write(a, pstr, (
int)strlen(pstr));
456 static long coap_sock_ctrl(BIO *a,
int cmd,
long num,
void *ptr) {
467 case BIO_CTRL_SET_CLOSE:
473 case BIO_CTRL_GET_CLOSE:
481 coap_openssl_context_t *context;
484 context = (coap_openssl_context_t *)
coap_malloc(
sizeof(coap_openssl_context_t));
488 memset(context, 0,
sizeof(coap_openssl_context_t));
491 context->dtls.ctx = SSL_CTX_new(DTLS_method());
492 if (!context->dtls.ctx)
494 SSL_CTX_set_min_proto_version(context->dtls.ctx, DTLS1_2_VERSION);
495 SSL_CTX_set_app_data(context->dtls.ctx, &context->dtls);
496 SSL_CTX_set_read_ahead(context->dtls.ctx, 1);
497 SSL_CTX_set_cipher_list(context->dtls.ctx,
"TLSv1.2:TLSv1.0");
498 if (!RAND_bytes(cookie_secret, (
int)
sizeof(cookie_secret))) {
501 prng(cookie_secret,
sizeof(cookie_secret));
503 context->dtls.cookie_hmac = HMAC_CTX_new();
504 if (!HMAC_Init_ex(context->dtls.cookie_hmac, cookie_secret, (
int)
sizeof(cookie_secret), EVP_sha256(), NULL))
506 SSL_CTX_set_cookie_generate_cb(context->dtls.ctx, coap_dtls_generate_cookie);
507 SSL_CTX_set_cookie_verify_cb(context->dtls.ctx, coap_dtls_verify_cookie);
508 SSL_CTX_set_info_callback(context->dtls.ctx, coap_dtls_info_callback);
509 SSL_CTX_set_options(context->dtls.ctx, SSL_OP_NO_QUERY_MTU);
510 context->dtls.meth = BIO_meth_new(BIO_TYPE_DGRAM,
"coapdgram");
511 if (!context->dtls.meth)
513 context->dtls.bio_addr = BIO_ADDR_new();
514 if (!context->dtls.bio_addr)
516 BIO_meth_set_write(context->dtls.meth, coap_dgram_write);
517 BIO_meth_set_read(context->dtls.meth, coap_dgram_read);
518 BIO_meth_set_puts(context->dtls.meth, coap_dgram_puts);
519 BIO_meth_set_ctrl(context->dtls.meth, coap_dgram_ctrl);
520 BIO_meth_set_create(context->dtls.meth, coap_dgram_create);
521 BIO_meth_set_destroy(context->dtls.meth, coap_dgram_destroy);
524 context->tls.ctx = SSL_CTX_new(TLS_method());
525 if (!context->tls.ctx)
527 SSL_CTX_set_app_data(context->tls.ctx, &context->tls);
528 SSL_CTX_set_min_proto_version(context->tls.ctx, TLS1_VERSION);
529 SSL_CTX_set_cipher_list(context->tls.ctx,
"TLSv1.2:TLSv1.0");
530 SSL_CTX_set_info_callback(context->tls.ctx, coap_dtls_info_callback);
531 context->tls.meth = BIO_meth_new(BIO_TYPE_SOCKET,
"coapsock");
532 if (!context->tls.meth)
534 BIO_meth_set_write(context->tls.meth, coap_sock_write);
535 BIO_meth_set_read(context->tls.meth, coap_sock_read);
536 BIO_meth_set_puts(context->tls.meth, coap_sock_puts);
537 BIO_meth_set_ctrl(context->tls.meth, coap_sock_ctrl);
538 BIO_meth_set_create(context->tls.meth, coap_sock_create);
539 BIO_meth_set_destroy(context->tls.meth, coap_sock_destroy);
551 const char *identity_hint,
554 coap_openssl_context_t *context = ((coap_openssl_context_t *)ctx->
dtls_context);
558 SSL_CTX_set_psk_server_callback(context->dtls.ctx, coap_dtls_psk_server_callback);
559 SSL_CTX_set_psk_server_callback(context->tls.ctx, coap_dtls_psk_server_callback);
560 SSL_CTX_use_psk_identity_hint(context->dtls.ctx, identity_hint ? identity_hint :
"");
561 SSL_CTX_use_psk_identity_hint(context->tls.ctx, identity_hint ? identity_hint :
"");
563 if (!context->dtls.ssl) {
565 context->dtls.ssl = SSL_new(context->dtls.ctx);
566 if (!context->dtls.ssl)
568 bio = BIO_new(context->dtls.meth);
570 SSL_free (context->dtls.ssl);
571 context->dtls.ssl = NULL;
574 SSL_set_bio(context->dtls.ssl, bio, bio);
575 SSL_set_app_data(context->dtls.ssl, NULL);
576 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
579 context->psk_pki_enabled |= IS_PSK;
584 map_key_type(
int asn1_private_key_type
586 switch (asn1_private_key_type) {
604 "*** setup_pki: DTLS: Unknown Private Key type %d for ASN1\n",
605 asn1_private_key_type);
610 static uint8_t coap_alpn[] = { 4,
'c',
'o',
'a',
'p' };
613 server_alpn_callback (SSL *ssl
UNUSED,
614 const unsigned char **out,
615 unsigned char *outlen,
616 const unsigned char *in,
620 unsigned char *tout = NULL;
623 return SSL_TLSEXT_ERR_NOACK;
624 ret = SSL_select_next_proto(&tout,
631 return (ret != OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_NOACK : SSL_TLSEXT_ERR_OK;
635 add_ca_to_cert_store(X509_STORE *st, X509 *x509)
640 while ((e = ERR_get_error()) != 0) {
643 if (!X509_STORE_add_cert(st, x509)) {
644 while ((e = ERR_get_error()) != 0) {
645 int r = ERR_GET_REASON(e);
646 if (r != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
649 ERR_reason_error_string(e),
650 ERR_lib_error_string(e),
651 ERR_func_error_string(e));
657 #if OPENSSL_VERSION_NUMBER < 0x10101000L 659 setup_pki_server(SSL_CTX *ctx,
666 if (!(SSL_CTX_use_certificate_file(ctx,
668 SSL_FILETYPE_PEM))) {
670 "*** setup_pki: (D)TLS: %s: Unable to configure Server Certificate\n",
677 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
683 if (!(SSL_CTX_use_PrivateKey_file(ctx,
685 SSL_FILETYPE_PEM))) {
687 "*** setup_pki: (D)TLS: %s: Unable to configure Server Private Key\n",
694 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
700 STACK_OF(X509_NAME) *cert_names;
706 if (cert_names != NULL)
707 SSL_CTX_set_client_CA_list(ctx, cert_names);
710 "*** setup_pki: (D)TLS: %s: Unable to configure client CA File\n",
714 st = SSL_CTX_get_cert_store(ctx);
715 in = BIO_new(BIO_s_file());
718 if (!BIO_read_filename(in, rw_var)) {
725 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
727 add_ca_to_cert_store(st, x);
737 if (!(SSL_CTX_use_certificate_ASN1(ctx,
741 "*** setup_pki: (D)TLS: %s: Unable to configure Server Certificate\n",
748 "*** setup_pki: (D)TLS: No Server Certificate defined\n");
755 if (!(SSL_CTX_use_PrivateKey_ASN1(pkey_type, ctx,
759 "*** setup_pki: (D)TLS: %s: Unable to configure Server Private Key\n",
766 "*** setup_pki: (D)TLS: No Server Private Key defined\n");
776 if (!x509 || !SSL_CTX_add_client_CA(ctx, x509)) {
778 "*** setup_pki: (D)TLS: %s: Unable to configure client CA File\n",
783 st = SSL_CTX_get_cert_store(ctx);
784 add_ca_to_cert_store(st, x509);
790 "*** setup_pki: (D)TLS: Unknown key type %d\n",
800 setup_pki_ssl(SSL *ssl,
807 if (!(SSL_use_certificate_file(ssl,
809 SSL_FILETYPE_PEM))) {
811 "*** setup_pki: (D)TLS: %s: Unable to configure Client Certificate\n",
818 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
823 if (!(SSL_use_PrivateKey_file(ssl,
825 SSL_FILETYPE_PEM))) {
827 "*** setup_pki: (D)TLS: %s: Unable to configure Client Private Key\n",
834 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
843 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
848 if (cert_names != NULL)
849 SSL_set_client_CA_list(ssl, cert_names);
852 "*** setup_pki: (D)TLS: %s: Unable to configure client CA File\n",
859 in = BIO_new(BIO_s_file());
862 if (!BIO_read_filename(in, rw_var)) {
867 st = SSL_CTX_get_cert_store(ctx);
869 if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL)
871 add_ca_to_cert_store(st, x);
881 if (!(SSL_use_certificate_ASN1(ssl,
885 "*** setup_pki: (D)TLS: %s: Unable to configure Client Certificate\n",
892 "*** setup_pki: (D)TLS: No Client Certificate defined\n");
898 if (!(SSL_use_PrivateKey_ASN1(pkey_type, ssl,
902 "*** setup_pki: (D)TLS: %s: Unable to configure Client Private Key\n",
909 "*** setup_pki: (D)TLS: No Client Private Key defined\n");
918 SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
921 if (!x509 || !SSL_add_client_CA(ssl, x509)) {
923 "*** setup_pki: (D)TLS: %s: Unable to configure client CA File\n",
931 st = SSL_CTX_get_cert_store(ctx);
932 add_ca_to_cert_store(st, x509);
938 "*** setup_pki: (D)TLS: Unknown key type %d\n",
946 get_common_name_from_cert(X509* x509) {
950 STACK_OF(GENERAL_NAME) *san_list;
953 san_list = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
955 int san_count = sk_GENERAL_NAME_num(san_list);
957 for (n = 0; n < san_count; n++) {
958 const GENERAL_NAME * name = sk_GENERAL_NAME_value (san_list, n);
960 if (name->type == GEN_DNS) {
961 const char *dns_name = (
const char *)ASN1_STRING_get0_data(name->d.dNSName);
964 if (ASN1_STRING_length(name->d.dNSName) != (int)strlen (dns_name))
966 cn = OPENSSL_strdup(dns_name);
967 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
971 sk_GENERAL_NAME_pop_free(san_list, GENERAL_NAME_free);
974 X509_NAME_oneline(X509_get_subject_name(x509), buffer,
sizeof(buffer));
977 n = strlen(buffer) - 3;
980 if (((cn[0] ==
'C') || (cn[0] ==
'c')) &&
981 ((cn[1] ==
'N') || (cn[1] ==
'n')) &&
990 char * ecn = strchr(cn,
'/');
992 return OPENSSL_strndup(cn, ecn-cn);
995 return OPENSSL_strdup(cn);
1003 tls_verify_call_back(
int preverify_ok, X509_STORE_CTX *ctx) {
1004 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
1005 SSL_get_ex_data_X509_STORE_CTX_idx());
1007 coap_openssl_context_t *context =
1010 int depth = X509_STORE_CTX_get_error_depth(ctx);
1011 int err = X509_STORE_CTX_get_error(ctx);
1012 X509 *x509 = X509_STORE_CTX_get_current_cert(ctx);
1013 char *cn = get_common_name_from_cert(x509);
1014 int keep_preverify_ok = preverify_ok;
1016 if (!preverify_ok) {
1018 case X509_V_ERR_CERT_NOT_YET_VALID:
1019 case X509_V_ERR_CERT_HAS_EXPIRED:
1023 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
1027 case X509_V_ERR_UNABLE_TO_GET_CRL:
1031 case X509_V_ERR_CRL_NOT_YET_VALID:
1032 case X509_V_ERR_CRL_HAS_EXPIRED:
1039 if (!preverify_ok) {
1041 " %s: %s: '%s' depth=%d\n",
1043 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1045 keep_preverify_ok = 1;
1049 " %s: %s: overridden: '%s' depth=%d\n",
1051 X509_verify_cert_error_string(err), cn ? cn :
"?", depth);
1056 int length = i2d_X509(x509, NULL);
1058 uint8_t *base_buf2 = base_buf = OPENSSL_malloc(length);
1061 i2d_X509(x509, &base_buf2);
1063 depth, preverify_ok,
1066 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED);
1069 X509_STORE_CTX_set_error(ctx, X509_V_ERR_INVALID_CA);
1073 OPENSSL_free(base_buf);
1076 return preverify_ok;
1079 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1088 tls_secret_call_back(SSL *ssl,
1089 void *secret UNUSED,
1090 int *secretlen UNUSED,
1091 STACK_OF(SSL_CIPHER) *peer_ciphers,
1092 const SSL_CIPHER **cipher UNUSED,
1096 int psk_requested = 0;
1102 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1103 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1105 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1111 if (!psk_requested) {
1123 SSL_VERIFY_CLIENT_ONCE |
1124 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1125 tls_verify_call_back);
1130 SSL_VERIFY_CLIENT_ONCE,
1131 tls_verify_call_back);
1135 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1144 X509_VERIFY_PARAM *param;
1146 param = X509_VERIFY_PARAM_new();
1147 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1148 SSL_set1_param(ssl, param);
1149 X509_VERIFY_PARAM_free(param);
1167 SSL_set_cipher_list (ssl,
"PSK:!NULL");
1168 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1186 tls_server_name_call_back(SSL *ssl,
1193 return SSL_TLSEXT_ERR_NOACK;
1199 coap_openssl_context_t *context =
1201 const char *sni = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
1204 if (!sni || !sni[0]) {
1207 for (i = 0; i < context->sni_count; i++) {
1208 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1212 if (i == context->sni_count) {
1218 return SSL_TLSEXT_ERR_ALERT_FATAL;
1223 ctx = SSL_CTX_new(DTLS_method());
1226 SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION);
1227 SSL_CTX_set_app_data(ctx, &context->dtls);
1228 SSL_CTX_set_read_ahead(ctx, 1);
1229 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1230 SSL_CTX_set_cookie_generate_cb(ctx, coap_dtls_generate_cookie);
1231 SSL_CTX_set_cookie_verify_cb(ctx, coap_dtls_verify_cookie);
1232 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1233 SSL_CTX_set_options(ctx, SSL_OP_NO_QUERY_MTU);
1237 ctx = SSL_CTX_new(TLS_method());
1240 SSL_CTX_set_app_data(ctx, &context->tls);
1241 SSL_CTX_set_min_proto_version(ctx, TLS1_VERSION);
1242 SSL_CTX_set_cipher_list(ctx,
"TLSv1.2:TLSv1.0");
1243 SSL_CTX_set_info_callback(ctx, coap_dtls_info_callback);
1244 SSL_CTX_set_alpn_select_cb(ctx, server_alpn_callback, NULL);
1246 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1250 setup_pki_server(ctx, &sni_setup_data);
1252 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1253 (context->sni_count+1)*
sizeof(sni_entry));
1254 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1255 context->sni_entry_list[context->sni_count].ctx = ctx;
1256 context->sni_count++;
1258 SSL_set_SSL_CTX (ssl, context->sni_entry_list[i].ctx);
1259 SSL_clear_options (ssl, 0xFFFFFFFFL);
1260 SSL_set_options (ssl, SSL_CTX_get_options (context->sni_entry_list[i].ctx));
1267 SSL_set_session_secret_cb(ssl, tls_secret_call_back, arg);
1268 return SSL_TLSEXT_ERR_OK;
1271 return SSL_TLSEXT_ERR_ALERT_WARNING;
1283 tls_client_hello_call_back(SSL *ssl,
1288 coap_openssl_context_t *dtls_context = (coap_openssl_context_t *)session->
context->
dtls_context;
1290 int psk_requested = 0;
1291 const unsigned char *out;
1295 *al = SSL_AD_INTERNAL_ERROR;
1296 return SSL_CLIENT_HELLO_ERROR;
1303 int len = SSL_client_hello_get0_ciphers(ssl, &out);
1304 STACK_OF(SSL_CIPHER) *peer_ciphers;
1305 STACK_OF(SSL_CIPHER) *scsvc;
1308 len = SSL_bytes_to_cipher_list(ssl, out, len,
1309 SSL_client_hello_isv2(ssl),
1310 &peer_ciphers, &scsvc);
1311 for (ii = 0; ii < sk_SSL_CIPHER_num (peer_ciphers); ii++) {
1312 const SSL_CIPHER *peer_cipher = sk_SSL_CIPHER_value(peer_ciphers, ii);
1314 if (strstr (SSL_CIPHER_get_name (peer_cipher),
"PSK")) {
1319 sk_SSL_CIPHER_free(peer_ciphers);
1320 sk_SSL_CIPHER_free(scsvc);
1323 if (psk_requested) {
1334 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1340 return SSL_CLIENT_HELLO_SUCCESS;
1350 if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_client_certificate_type,
1353 for (ii = 0; ii < outlen; ii++) {
1369 *al = SSL_AD_UNSUPPORTED_EXTENSION;
1370 return SSL_CLIENT_HELLO_ERROR;
1379 coap_openssl_context_t *context =
1381 const char *sni =
"";
1382 char *sni_tmp = NULL;
1385 if (SSL_client_hello_get0_ext (ssl, TLSEXT_TYPE_server_name, &out, &outlen) &&
1387 (((out[0]<<8) + out[1] +2) == (int)outlen) &&
1388 out[2] == TLSEXT_NAMETYPE_host_name &&
1389 (((out[3]<<8) + out[4] +2 +3) == (int)outlen)) {
1393 sni_tmp = OPENSSL_malloc(outlen+1);
1394 sni_tmp[outlen] =
'\000';
1395 memcpy(sni_tmp, out, outlen);
1399 for (i = 0; i < context->sni_count; i++) {
1400 if (!strcmp(sni, context->sni_entry_list[i].sni)) {
1404 if (i == context->sni_count) {
1411 *al = SSL_AD_UNRECOGNIZED_NAME;
1412 return SSL_CLIENT_HELLO_ERROR;
1416 context->sni_entry_list = OPENSSL_realloc(context->sni_entry_list,
1417 (context->sni_count+1)*
sizeof(sni_entry));
1418 context->sni_entry_list[context->sni_count].sni = OPENSSL_strdup(sni);
1419 context->sni_entry_list[context->sni_count].pki_key = *new_entry;
1420 context->sni_count++;
1423 OPENSSL_free(sni_tmp);
1425 memset(&sni_setup_data, 0,
sizeof(sni_setup_data));
1426 sni_setup_data.
pki_key = context->sni_entry_list[i].pki_key;
1427 setup_pki_ssl(ssl, &sni_setup_data, 1);
1430 setup_pki_ssl(ssl, setup_data, 1);
1444 SSL_VERIFY_CLIENT_ONCE |
1445 SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1446 tls_verify_call_back);
1451 SSL_VERIFY_CLIENT_ONCE,
1452 tls_verify_call_back);
1456 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1465 X509_VERIFY_PARAM *param;
1467 param = X509_VERIFY_PARAM_new();
1468 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1469 SSL_set1_param(ssl, param);
1470 X509_VERIFY_PARAM_free(param);
1477 return SSL_CLIENT_HELLO_SUCCESS;
1486 coap_openssl_context_t *context =
1491 context->setup_data = *setup_data;
1493 if (context->dtls.ctx) {
1495 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1496 if (!setup_pki_server(context->dtls.ctx, setup_data))
1505 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1506 if (SSLeay() >= 0x10101000L) {
1508 "OpenSSL compiled with %lux, linked with %lux, so no certificate checking\n",
1509 OPENSSL_VERSION_NUMBER, SSLeay());
1511 SSL_CTX_set_tlsext_servername_arg(context->dtls.ctx, &context->setup_data);
1512 SSL_CTX_set_tlsext_servername_callback(context->dtls.ctx,
1513 tls_server_name_call_back);
1515 SSL_CTX_set_client_hello_cb(context->dtls.ctx,
1516 tls_client_hello_call_back,
1520 if (context->tls.ctx) {
1522 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1523 if (!setup_pki_server(context->tls.ctx, setup_data))
1532 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1533 if (SSLeay() >= 0x10101000L) {
1535 "OpenSSL compiled with %lux, linked with %lux, so no certificate checking\n",
1536 OPENSSL_VERSION_NUMBER, SSLeay());
1538 SSL_CTX_set_tlsext_servername_arg(context->tls.ctx, &context->setup_data);
1539 SSL_CTX_set_tlsext_servername_callback(context->tls.ctx,
1540 tls_server_name_call_back);
1542 SSL_CTX_set_client_hello_cb(context->tls.ctx,
1543 tls_client_hello_call_back,
1547 SSL_CTX_set_alpn_select_cb(context->tls.ctx, server_alpn_callback, NULL);
1551 if (!context->dtls.ssl) {
1553 context->dtls.ssl = SSL_new(context->dtls.ctx);
1554 if (!context->dtls.ssl)
1556 bio = BIO_new(context->dtls.meth);
1558 SSL_free (context->dtls.ssl);
1559 context->dtls.ssl = NULL;
1562 SSL_set_bio(context->dtls.ssl, bio, bio);
1563 SSL_set_app_data(context->dtls.ssl, NULL);
1564 SSL_set_options(context->dtls.ssl, SSL_OP_COOKIE_EXCHANGE);
1567 context->psk_pki_enabled |= IS_PKI;
1573 const char *ca_file,
1576 coap_openssl_context_t *context =
1578 if (context->dtls.ctx) {
1579 if (!SSL_CTX_load_verify_locations(context->dtls.ctx, ca_file, ca_dir)) {
1581 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1585 if (context->tls.ctx) {
1586 if (!SSL_CTX_load_verify_locations(context->tls.ctx, ca_file, ca_dir)) {
1588 ca_file ? ca_file :
"NULL", ca_dir ? ca_dir :
"NULL");
1598 coap_openssl_context_t *context =
1600 return context->psk_pki_enabled ? 1 : 0;
1606 coap_openssl_context_t *context = (coap_openssl_context_t *)handle;
1608 if (context->dtls.ssl)
1609 SSL_free(context->dtls.ssl);
1610 if (context->dtls.ctx)
1611 SSL_CTX_free(context->dtls.ctx);
1612 if (context->dtls.cookie_hmac)
1613 HMAC_CTX_free(context->dtls.cookie_hmac);
1614 if (context->dtls.meth)
1615 BIO_meth_free(context->dtls.meth);
1616 if (context->dtls.bio_addr)
1617 BIO_ADDR_free(context->dtls.bio_addr);
1618 if ( context->tls.ctx )
1619 SSL_CTX_free( context->tls.ctx );
1620 if ( context->tls.meth )
1621 BIO_meth_free( context->tls.meth );
1622 for (i = 0; i < context->sni_count; i++) {
1623 OPENSSL_free(context->sni_entry_list[i].sni);
1624 #if OPENSSL_VERSION_NUMBER < 0x10101000L 1625 SSL_CTX_free(context->sni_entry_list[i].ctx);
1628 if (context->sni_count)
1629 OPENSSL_free(context->sni_entry_list);
1635 SSL *nssl = NULL, *ssl = NULL;
1636 coap_ssl_data *data;
1637 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1640 nssl = SSL_new(dtls->ctx);
1643 nbio = BIO_new(dtls->meth);
1646 SSL_set_bio(nssl, nbio, nbio);
1647 SSL_set_app_data(nssl, NULL);
1648 SSL_set_options(nssl, SSL_OP_COOKIE_EXCHANGE);
1649 SSL_set_mtu(nssl, session->
mtu);
1653 SSL_set_app_data(ssl, session);
1655 data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1656 data->session = session;
1659 char hint[128] =
"";
1661 if (hint_len > 0 && hint_len <
sizeof(hint)) {
1663 SSL_use_psk_identity_hint(ssl, hint);
1667 r = SSL_accept(ssl);
1669 int err = SSL_get_error(ssl, r);
1670 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
1690 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1692 if (context->psk_pki_enabled & IS_PSK) {
1693 SSL_set_psk_client_callback(ssl, coap_dtls_psk_client_callback);
1694 SSL_set_psk_server_callback(ssl, coap_dtls_psk_server_callback);
1695 SSL_set_cipher_list(ssl,
"PSK:!NULL");
1697 if (context->psk_pki_enabled & IS_PKI) {
1699 if (!setup_pki_ssl(ssl, setup_data, 0))
1703 SSL_set_alpn_protos(ssl, coap_alpn,
sizeof(coap_alpn));
1707 SSL_set_tlsext_host_name (ssl, setup_data->
client_sni) != 1) {
1713 X509_VERIFY_PARAM *param;
1715 param = X509_VERIFY_PARAM_new();
1716 X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK);
1717 SSL_set1_param(ssl, param);
1718 X509_VERIFY_PARAM_free(param);
1723 SSL_set_verify(ssl, SSL_VERIFY_PEER, tls_verify_call_back);
1725 SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
1738 coap_ssl_data *data;
1740 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1741 coap_dtls_context_t *dtls = &context->dtls;
1743 ssl = SSL_new(dtls->ctx);
1746 bio = BIO_new(dtls->meth);
1749 data = (coap_ssl_data *)BIO_get_data(bio);
1750 data->session = session;
1751 SSL_set_bio(ssl, bio, bio);
1752 SSL_set_app_data(ssl, session);
1753 SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE);
1754 SSL_set_mtu(ssl, session->
mtu);
1756 if (!setup_client_ssl_session(session, ssl))
1761 r = SSL_connect(ssl);
1763 int ret = SSL_get_error(ssl, r);
1764 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
1780 SSL *ssl = (SSL *)session->
tls;
1782 SSL_set_mtu(ssl, session->
mtu);
1786 SSL *ssl = (SSL *)session->
tls;
1788 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
1789 int r = SSL_shutdown(ssl);
1790 if (r == 0) r = SSL_shutdown(ssl);
1793 session->
tls = NULL;
1798 const uint8_t *data,
size_t data_len) {
1800 SSL *ssl = (SSL *)session->
tls;
1805 r = SSL_write(ssl, data, (
int)data_len);
1808 int err = SSL_get_error(ssl, r);
1809 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1813 if (err == SSL_ERROR_ZERO_RETURN)
1815 else if (err == SSL_ERROR_SSL)
1843 SSL *ssl = (SSL *)session->
tls;
1844 coap_ssl_data *ssl_data;
1847 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1848 return ssl_data->timeout;
1852 SSL *ssl = (SSL *)session->
tls;
1857 (DTLSv1_handle_timeout(ssl) < 0)) {
1864 const uint8_t *data,
size_t data_len) {
1865 coap_dtls_context_t *dtls = &((coap_openssl_context_t *)session->
context->
dtls_context)->dtls;
1866 coap_ssl_data *ssl_data;
1869 SSL_set_mtu(dtls->ssl, session->
mtu);
1870 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(dtls->ssl));
1871 ssl_data->session = session;
1872 ssl_data->pdu = data;
1873 ssl_data->pdu_len = (unsigned)data_len;
1874 r = DTLSv1_listen(dtls->ssl, dtls->bio_addr);
1876 int err = SSL_get_error(dtls->ssl, r);
1877 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1890 const uint8_t *data,
size_t data_len) {
1891 coap_ssl_data *ssl_data;
1892 SSL *ssl = (SSL *)session->
tls;
1897 int in_init = SSL_in_init(ssl);
1899 ssl_data = (coap_ssl_data*)BIO_get_data(SSL_get_rbio(ssl));
1900 ssl_data->pdu = data;
1901 ssl_data->pdu_len = (unsigned)data_len;
1904 r = SSL_read(ssl, pdu, (
int)
sizeof(pdu));
1908 int err = SSL_get_error(ssl, r);
1909 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
1910 if (in_init && SSL_is_init_finished(ssl)) {
1916 if (err == SSL_ERROR_ZERO_RETURN)
1918 else if (err == SSL_ERROR_SSL)
1936 unsigned int overhead = 37;
1937 const SSL_CIPHER *s_ciph = NULL;
1938 if (session->
tls != NULL)
1939 s_ciph = SSL_get_current_cipher(session->
tls);
1941 unsigned int ivlen, maclen, blocksize = 1, pad = 0;
1943 const EVP_CIPHER *e_ciph;
1947 e_ciph = EVP_get_cipherbynid(SSL_CIPHER_get_cipher_nid(s_ciph));
1949 switch (EVP_CIPHER_mode(e_ciph)) {
1950 case EVP_CIPH_GCM_MODE:
1951 ivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
1952 maclen = EVP_GCM_TLS_TAG_LEN;
1955 case EVP_CIPH_CCM_MODE:
1956 ivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
1957 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
1958 if (strstr(cipher,
"CCM8"))
1964 case EVP_CIPH_CBC_MODE:
1965 e_md = EVP_get_digestbynid(SSL_CIPHER_get_digest_nid(s_ciph));
1966 blocksize = EVP_CIPHER_block_size(e_ciph);
1967 ivlen = EVP_CIPHER_iv_length(e_ciph);
1969 maclen = EVP_MD_size(e_md);
1972 case EVP_CIPH_STREAM_CIPHER:
1979 SSL_CIPHER_description(s_ciph, cipher,
sizeof(cipher));
1985 overhead = DTLS1_RT_HEADER_LENGTH + ivlen + maclen + blocksize - 1 + pad;
1994 coap_openssl_context_t *context = ((coap_openssl_context_t *)session->
context->
dtls_context);
1995 coap_tls_context_t *tls = &context->tls;
1998 ssl = SSL_new(tls->ctx);
2001 bio = BIO_new(tls->meth);
2004 BIO_set_data(bio, session);
2005 SSL_set_bio(ssl, bio, bio);
2006 SSL_set_app_data(ssl, session);
2008 if (!setup_client_ssl_session(session, ssl))
2011 r = SSL_connect(ssl);
2013 int ret = SSL_get_error(ssl, r);
2014 if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
2016 if (ret == SSL_ERROR_WANT_READ)
2018 if (ret == SSL_ERROR_WANT_WRITE)
2025 *connected = SSL_is_init_finished(ssl);
2038 coap_tls_context_t *tls = &((coap_openssl_context_t *)session->
context->
dtls_context)->tls;
2042 ssl = SSL_new(tls->ctx);
2045 bio = BIO_new(tls->meth);
2048 BIO_set_data(bio, session);
2049 SSL_set_bio(ssl, bio, bio);
2050 SSL_set_app_data(ssl, session);
2053 char hint[128] =
"";
2055 if (hint_len > 0 && hint_len <
sizeof(hint)) {
2057 SSL_use_psk_identity_hint(ssl, hint);
2061 r = SSL_accept(ssl);
2063 int err = SSL_get_error(ssl, r);
2064 if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE)
2066 if (err == SSL_ERROR_WANT_READ)
2068 if (err == SSL_ERROR_WANT_WRITE)
2075 *connected = SSL_is_init_finished(ssl);
2086 SSL *ssl = (SSL *)session->
tls;
2088 if (!SSL_in_init(ssl) && !(SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
2089 int r = SSL_shutdown(ssl);
2090 if (r == 0) r = SSL_shutdown(ssl);
2093 session->
tls = NULL;
2101 SSL *ssl = (SSL *)session->
tls;
2107 in_init = !SSL_is_init_finished(ssl);
2109 r = SSL_write(ssl, data, (
int)data_len);
2112 int err = SSL_get_error(ssl, r);
2113 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2114 if (in_init && SSL_is_init_finished(ssl)) {
2118 if (err == SSL_ERROR_WANT_READ)
2120 if (err == SSL_ERROR_WANT_WRITE)
2125 if (err == SSL_ERROR_ZERO_RETURN)
2127 else if (err == SSL_ERROR_SSL)
2131 }
else if (in_init && SSL_is_init_finished(ssl)) {
2152 SSL *ssl = (SSL *)session->
tls;
2158 in_init = !SSL_is_init_finished(ssl);
2160 r = SSL_read(ssl, data, (
int)data_len);
2162 int err = SSL_get_error(ssl, r);
2163 if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2164 if (in_init && SSL_is_init_finished(ssl)) {
2168 if (err == SSL_ERROR_WANT_READ)
2170 if (err == SSL_ERROR_WANT_WRITE)
2174 if (err == SSL_ERROR_ZERO_RETURN)
2176 else if (err == SSL_ERROR_SSL)
2180 }
else if (in_init && SSL_is_init_finished(ssl)) {
2203 #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