2 * SSL/TLS interface functions for GnuTLS
3 * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <gnutls/gnutls.h>
11 #include <gnutls/x509.h>
13 #include <gnutls/pkcs12.h>
14 #endif /* PKCS12_FUNCS */
15 #if GNUTLS_VERSION_NUMBER >= 0x030103
16 #include <gnutls/ocsp.h>
20 #include "crypto/crypto.h"
24 static int tls_gnutls_ref_count = 0;
27 /* Data for session resumption */
29 size_t session_data_size;
34 gnutls_certificate_credentials_t xcred;
36 void (*event_cb)(void *ctx, enum tls_event ev,
37 union tls_event_data *data);
41 char *ocsp_stapling_response;
44 struct tls_connection {
45 struct tls_global *global;
46 gnutls_session_t session;
47 int read_alerts, write_alerts, failed;
49 u8 *pre_shared_secret;
50 size_t pre_shared_secret_len;
53 unsigned int disable_time_checks:1;
55 struct wpabuf *push_buf;
56 struct wpabuf *pull_buf;
57 const u8 *pull_buf_offset;
60 gnutls_certificate_credentials_t xcred;
68 static int tls_connection_verify_peer(gnutls_session_t session);
71 static void tls_log_func(int level, const char *msg)
74 if (level == 6 || level == 7) {
75 /* These levels seem to be mostly I/O debug and msg dumps */
84 while (*pos != '\0') {
91 wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG,
92 "gnutls<%d> %s", level, s);
97 void * tls_init(const struct tls_config *conf)
99 struct tls_global *global;
101 if (tls_gnutls_ref_count == 0) {
102 wpa_printf(MSG_DEBUG,
103 "GnuTLS: Library version %s (runtime) - %s (build)",
104 gnutls_check_version(NULL), GNUTLS_VERSION);
107 global = os_zalloc(sizeof(*global));
111 if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) {
115 tls_gnutls_ref_count++;
117 gnutls_global_set_log_function(tls_log_func);
118 if (wpa_debug_show_keys)
119 gnutls_global_set_log_level(11);
122 global->event_cb = conf->event_cb;
123 global->cb_ctx = conf->cb_ctx;
124 global->cert_in_cb = conf->cert_in_cb;
131 void tls_deinit(void *ssl_ctx)
133 struct tls_global *global = ssl_ctx;
135 if (global->params_set)
136 gnutls_certificate_free_credentials(global->xcred);
137 os_free(global->session_data);
138 os_free(global->ocsp_stapling_response);
142 tls_gnutls_ref_count--;
143 if (tls_gnutls_ref_count == 0)
144 gnutls_global_deinit();
148 int tls_get_errors(void *ssl_ctx)
154 static ssize_t tls_pull_func(gnutls_transport_ptr_t ptr, void *buf,
157 struct tls_connection *conn = (struct tls_connection *) ptr;
159 if (conn->pull_buf == NULL) {
164 end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf);
165 if ((size_t) (end - conn->pull_buf_offset) < len)
166 len = end - conn->pull_buf_offset;
167 os_memcpy(buf, conn->pull_buf_offset, len);
168 conn->pull_buf_offset += len;
169 if (conn->pull_buf_offset == end) {
170 wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__);
171 wpabuf_free(conn->pull_buf);
172 conn->pull_buf = NULL;
173 conn->pull_buf_offset = NULL;
175 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf",
177 (unsigned long) (end - conn->pull_buf_offset));
183 static ssize_t tls_push_func(gnutls_transport_ptr_t ptr, const void *buf,
186 struct tls_connection *conn = (struct tls_connection *) ptr;
188 if (wpabuf_resize(&conn->push_buf, len) < 0) {
192 wpabuf_put_data(conn->push_buf, buf, len);
198 static int tls_gnutls_init_session(struct tls_global *global,
199 struct tls_connection *conn)
204 ret = gnutls_init(&conn->session,
205 global->server ? GNUTLS_SERVER : GNUTLS_CLIENT);
207 wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS "
208 "connection: %s", gnutls_strerror(ret));
212 ret = gnutls_set_default_priority(conn->session);
216 ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0",
219 wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at "
224 gnutls_transport_set_pull_function(conn->session, tls_pull_func);
225 gnutls_transport_set_push_function(conn->session, tls_push_func);
226 gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn);
227 gnutls_session_set_ptr(conn->session, conn);
232 wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s",
233 gnutls_strerror(ret));
234 gnutls_deinit(conn->session);
239 struct tls_connection * tls_connection_init(void *ssl_ctx)
241 struct tls_global *global = ssl_ctx;
242 struct tls_connection *conn;
245 conn = os_zalloc(sizeof(*conn));
248 conn->global = global;
250 if (tls_gnutls_init_session(global, conn)) {
255 if (global->params_set) {
256 ret = gnutls_credentials_set(conn->session,
257 GNUTLS_CRD_CERTIFICATE,
260 wpa_printf(MSG_INFO, "Failed to configure "
261 "credentials: %s", gnutls_strerror(ret));
267 if (gnutls_certificate_allocate_credentials(&conn->xcred)) {
276 void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
281 gnutls_certificate_free_credentials(conn->xcred);
282 gnutls_deinit(conn->session);
283 os_free(conn->pre_shared_secret);
284 wpabuf_free(conn->push_buf);
285 wpabuf_free(conn->pull_buf);
286 os_free(conn->suffix_match);
287 os_free(conn->domain_match);
292 int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
294 return conn ? conn->established : 0;
298 char * tls_connection_peer_serial_num(void *tls_ctx,
299 struct tls_connection *conn)
306 int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
308 struct tls_global *global = ssl_ctx;
314 /* Shutdown previous TLS connection without notifying the peer
315 * because the connection was already terminated in practice
316 * and "close notify" shutdown alert would confuse AS. */
317 gnutls_bye(conn->session, GNUTLS_SHUT_RDWR);
318 wpabuf_free(conn->push_buf);
319 conn->push_buf = NULL;
320 conn->established = 0;
322 gnutls_deinit(conn->session);
323 if (tls_gnutls_init_session(global, conn)) {
324 wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session "
325 "for session resumption use");
329 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
330 conn->params_set ? conn->xcred :
333 wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials "
334 "for session resumption: %s", gnutls_strerror(ret));
338 if (global->session_data) {
339 ret = gnutls_session_set_data(conn->session,
340 global->session_data,
341 global->session_data_size);
343 wpa_printf(MSG_INFO, "GnuTLS: Failed to set session "
344 "data: %s", gnutls_strerror(ret));
353 int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
354 const struct tls_connection_params *params)
359 const char *prio = NULL;
361 if (conn == NULL || params == NULL)
364 if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) {
366 "GnuTLS: ocsp=3 not supported");
370 if (params->flags & TLS_CONN_EXT_CERT_CHECK) {
372 "GnuTLS: tls_ext_cert_check=1 not supported");
376 if (params->subject_match) {
377 wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported");
381 if (params->altsubject_match) {
382 wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported");
386 os_free(conn->suffix_match);
387 conn->suffix_match = NULL;
388 if (params->suffix_match) {
389 conn->suffix_match = os_strdup(params->suffix_match);
390 if (conn->suffix_match == NULL)
394 #if GNUTLS_VERSION_NUMBER >= 0x030300
395 os_free(conn->domain_match);
396 conn->domain_match = NULL;
397 if (params->domain_match) {
398 conn->domain_match = os_strdup(params->domain_match);
399 if (conn->domain_match == NULL)
403 if (params->domain_match) {
404 wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported");
407 #endif /* >= 3.3.0 */
409 conn->flags = params->flags;
411 if (params->flags & (TLS_CONN_DISABLE_TLSv1_0 |
412 TLS_CONN_DISABLE_TLSv1_1 |
413 TLS_CONN_DISABLE_TLSv1_2)) {
414 os_snprintf(prio_buf, sizeof(prio_buf),
415 "NORMAL:-VERS-SSL3.0%s%s%s",
416 params->flags & TLS_CONN_DISABLE_TLSv1_0 ?
417 ":-VERS-TLS1.0" : "",
418 params->flags & TLS_CONN_DISABLE_TLSv1_1 ?
419 ":-VERS-TLS1.1" : "",
420 params->flags & TLS_CONN_DISABLE_TLSv1_2 ?
421 ":-VERS-TLS1.2" : "");
425 if (params->openssl_ciphers) {
426 if (os_strcmp(params->openssl_ciphers, "SUITEB128") == 0) {
428 } else if (os_strcmp(params->openssl_ciphers,
431 } else if ((params->flags & TLS_CONN_SUITEB) &&
432 os_strcmp(params->openssl_ciphers,
433 "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
434 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
435 } else if (os_strcmp(params->openssl_ciphers,
436 "ECDHE-RSA-AES256-GCM-SHA384") == 0) {
437 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
438 } else if (os_strcmp(params->openssl_ciphers,
439 "DHE-RSA-AES256-GCM-SHA384") == 0) {
440 prio = "NONE:+VERS-TLS1.2:+AEAD:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
441 } else if (os_strcmp(params->openssl_ciphers,
442 "ECDHE-ECDSA-AES256-GCM-SHA384") == 0) {
443 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL";
446 "GnuTLS: openssl_ciphers not supported");
449 } else if (params->flags & TLS_CONN_SUITEB) {
450 prio = "NONE:+VERS-TLS1.2:+AEAD:+ECDHE-ECDSA:+ECDHE-RSA:+DHE-RSA:+AES-256-GCM:+SIGN-RSA-SHA384:+CURVE-SECP384R1:+COMP-NULL:%PROFILE_HIGH";
454 wpa_printf(MSG_DEBUG, "GnuTLS: Set priority string: %s", prio);
455 ret = gnutls_priority_set_direct(conn->session, prio, &err);
457 wpa_printf(MSG_ERROR,
458 "GnuTLS: Priority string failure at '%s'",
464 /* TODO: gnutls_certificate_set_verify_flags(xcred, flags);
465 * to force peer validation(?) */
467 if (params->ca_cert) {
468 wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format",
470 ret = gnutls_certificate_set_x509_trust_file(
471 conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
473 wpa_printf(MSG_DEBUG,
474 "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format",
476 gnutls_strerror(ret));
477 ret = gnutls_certificate_set_x509_trust_file(
478 conn->xcred, params->ca_cert,
479 GNUTLS_X509_FMT_PEM);
481 wpa_printf(MSG_DEBUG,
482 "Failed to read CA cert '%s' in PEM format: %s",
484 gnutls_strerror(ret));
487 wpa_printf(MSG_DEBUG,
488 "GnuTLS: Successfully read CA cert '%s' in PEM format",
491 wpa_printf(MSG_DEBUG,
492 "GnuTLS: Successfully read CA cert '%s' in DER format",
495 } else if (params->ca_cert_blob) {
498 ca.data = (unsigned char *) params->ca_cert_blob;
499 ca.size = params->ca_cert_blob_len;
501 ret = gnutls_certificate_set_x509_trust_mem(
502 conn->xcred, &ca, GNUTLS_X509_FMT_DER);
504 wpa_printf(MSG_DEBUG,
505 "Failed to parse CA cert in DER format: %s",
506 gnutls_strerror(ret));
507 ret = gnutls_certificate_set_x509_trust_mem(
508 conn->xcred, &ca, GNUTLS_X509_FMT_PEM);
510 wpa_printf(MSG_DEBUG,
511 "Failed to parse CA cert in PEM format: %s",
512 gnutls_strerror(ret));
516 } else if (params->ca_path) {
517 wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported");
521 conn->disable_time_checks = 0;
522 if (params->ca_cert || params->ca_cert_blob) {
523 conn->verify_peer = 1;
524 gnutls_certificate_set_verify_function(
525 conn->xcred, tls_connection_verify_peer);
527 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
528 gnutls_certificate_set_verify_flags(
529 conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
532 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
533 conn->disable_time_checks = 1;
534 gnutls_certificate_set_verify_flags(
536 GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
540 if (params->client_cert && params->private_key) {
541 wpa_printf(MSG_DEBUG,
542 "GnuTLS: Try to parse client cert '%s' and key '%s' in DER format",
543 params->client_cert, params->private_key);
544 #if GNUTLS_VERSION_NUMBER >= 0x03010b
545 ret = gnutls_certificate_set_x509_key_file2(
546 conn->xcred, params->client_cert, params->private_key,
547 GNUTLS_X509_FMT_DER, params->private_key_passwd, 0);
549 /* private_key_passwd not (easily) supported here */
550 ret = gnutls_certificate_set_x509_key_file(
551 conn->xcred, params->client_cert, params->private_key,
552 GNUTLS_X509_FMT_DER);
555 wpa_printf(MSG_DEBUG,
556 "GnuTLS: Failed to read client cert/key in DER format (%s) - try in PEM format",
557 gnutls_strerror(ret));
558 #if GNUTLS_VERSION_NUMBER >= 0x03010b
559 ret = gnutls_certificate_set_x509_key_file2(
560 conn->xcred, params->client_cert,
561 params->private_key, GNUTLS_X509_FMT_PEM,
562 params->private_key_passwd, 0);
564 ret = gnutls_certificate_set_x509_key_file(
565 conn->xcred, params->client_cert,
566 params->private_key, GNUTLS_X509_FMT_PEM);
569 wpa_printf(MSG_DEBUG, "Failed to read client "
570 "cert/key in PEM format: %s",
571 gnutls_strerror(ret));
574 wpa_printf(MSG_DEBUG,
575 "GnuTLS: Successfully read client cert/key in PEM format");
577 wpa_printf(MSG_DEBUG,
578 "GnuTLS: Successfully read client cert/key in DER format");
580 } else if (params->private_key) {
583 /* Try to load in PKCS#12 format */
584 wpa_printf(MSG_DEBUG,
585 "GnuTLS: Try to parse client cert/key '%s'in PKCS#12 DER format",
586 params->private_key);
587 ret = gnutls_certificate_set_x509_simple_pkcs12_file(
588 conn->xcred, params->private_key, GNUTLS_X509_FMT_DER,
589 params->private_key_passwd);
591 wpa_printf(MSG_DEBUG, "Failed to load private_key in "
592 "PKCS#12 format: %s", gnutls_strerror(ret));
596 #endif /* PKCS12_FUNCS */
599 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
603 } else if (params->client_cert_blob && params->private_key_blob) {
604 gnutls_datum_t cert, key;
606 cert.data = (unsigned char *) params->client_cert_blob;
607 cert.size = params->client_cert_blob_len;
608 key.data = (unsigned char *) params->private_key_blob;
609 key.size = params->private_key_blob_len;
611 #if GNUTLS_VERSION_NUMBER >= 0x03010b
612 ret = gnutls_certificate_set_x509_key_mem2(
613 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER,
614 params->private_key_passwd, 0);
616 /* private_key_passwd not (easily) supported here */
617 ret = gnutls_certificate_set_x509_key_mem(
618 conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER);
621 wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
622 "in DER format: %s", gnutls_strerror(ret));
623 #if GNUTLS_VERSION_NUMBER >= 0x03010b
624 ret = gnutls_certificate_set_x509_key_mem2(
625 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM,
626 params->private_key_passwd, 0);
628 /* private_key_passwd not (easily) supported here */
629 ret = gnutls_certificate_set_x509_key_mem(
630 conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM);
633 wpa_printf(MSG_DEBUG, "Failed to read client "
634 "cert/key in PEM format: %s",
635 gnutls_strerror(ret));
639 } else if (params->private_key_blob) {
643 key.data = (unsigned char *) params->private_key_blob;
644 key.size = params->private_key_blob_len;
646 /* Try to load in PKCS#12 format */
647 ret = gnutls_certificate_set_x509_simple_pkcs12_mem(
648 conn->xcred, &key, GNUTLS_X509_FMT_DER,
649 params->private_key_passwd);
651 wpa_printf(MSG_DEBUG, "Failed to load private_key in "
652 "PKCS#12 format: %s", gnutls_strerror(ret));
655 #else /* PKCS12_FUNCS */
656 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included");
658 #endif /* PKCS12_FUNCS */
661 #if GNUTLS_VERSION_NUMBER >= 0x030103
662 if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) {
663 ret = gnutls_ocsp_status_request_enable_client(conn->session,
665 if (ret != GNUTLS_E_SUCCESS) {
667 "GnuTLS: Failed to enable OCSP client");
672 if (params->flags & TLS_CONN_REQUIRE_OCSP) {
674 "GnuTLS: OCSP not supported by this version of GnuTLS");
679 conn->params_set = 1;
681 ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE,
684 wpa_printf(MSG_INFO, "Failed to configure credentials: %s",
685 gnutls_strerror(ret));
692 #if GNUTLS_VERSION_NUMBER >= 0x030103
693 static int server_ocsp_status_req(gnutls_session_t session, void *ptr,
694 gnutls_datum_t *resp)
696 struct tls_global *global = ptr;
700 if (!global->ocsp_stapling_response) {
701 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured");
702 return GNUTLS_E_NO_CERTIFICATE_STATUS;
705 cached = os_readfile(global->ocsp_stapling_response, &len);
707 wpa_printf(MSG_DEBUG,
708 "GnuTLS: OCSP status callback - could not read response file (%s)",
709 global->ocsp_stapling_response);
710 return GNUTLS_E_NO_CERTIFICATE_STATUS;
713 wpa_printf(MSG_DEBUG,
714 "GnuTLS: OCSP status callback - send cached response");
715 resp->data = gnutls_malloc(len);
718 return GNUTLS_E_MEMORY_ERROR;
721 os_memcpy(resp->data, cached, len);
725 return GNUTLS_E_SUCCESS;
730 int tls_global_set_params(void *tls_ctx,
731 const struct tls_connection_params *params)
733 struct tls_global *global = tls_ctx;
736 /* Currently, global parameters are only set when running in server
740 if (global->params_set) {
741 gnutls_certificate_free_credentials(global->xcred);
742 global->params_set = 0;
745 ret = gnutls_certificate_allocate_credentials(&global->xcred);
747 wpa_printf(MSG_DEBUG, "Failed to allocate global credentials "
748 "%s", gnutls_strerror(ret));
752 if (params->ca_cert) {
753 ret = gnutls_certificate_set_x509_trust_file(
754 global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER);
756 wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' "
757 "in DER format: %s", params->ca_cert,
758 gnutls_strerror(ret));
759 ret = gnutls_certificate_set_x509_trust_file(
760 global->xcred, params->ca_cert,
761 GNUTLS_X509_FMT_PEM);
763 wpa_printf(MSG_DEBUG, "Failed to read CA cert "
764 "'%s' in PEM format: %s",
766 gnutls_strerror(ret));
771 if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) {
772 gnutls_certificate_set_verify_flags(
774 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5);
777 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) {
778 gnutls_certificate_set_verify_flags(
780 GNUTLS_VERIFY_DISABLE_TIME_CHECKS);
784 if (params->client_cert && params->private_key) {
785 /* TODO: private_key_passwd? */
786 ret = gnutls_certificate_set_x509_key_file(
787 global->xcred, params->client_cert,
788 params->private_key, GNUTLS_X509_FMT_DER);
790 wpa_printf(MSG_DEBUG, "Failed to read client cert/key "
791 "in DER format: %s", gnutls_strerror(ret));
792 ret = gnutls_certificate_set_x509_key_file(
793 global->xcred, params->client_cert,
794 params->private_key, GNUTLS_X509_FMT_PEM);
796 wpa_printf(MSG_DEBUG, "Failed to read client "
797 "cert/key in PEM format: %s",
798 gnutls_strerror(ret));
802 } else if (params->private_key) {
805 /* Try to load in PKCS#12 format */
806 ret = gnutls_certificate_set_x509_simple_pkcs12_file(
807 global->xcred, params->private_key,
808 GNUTLS_X509_FMT_DER, params->private_key_passwd);
810 wpa_printf(MSG_DEBUG, "Failed to load private_key in "
811 "PKCS#12 format: %s", gnutls_strerror(ret));
815 #endif /* PKCS12_FUNCS */
818 wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not "
824 #if GNUTLS_VERSION_NUMBER >= 0x030103
825 os_free(global->ocsp_stapling_response);
826 if (params->ocsp_stapling_response)
827 global->ocsp_stapling_response =
828 os_strdup(params->ocsp_stapling_response);
830 global->ocsp_stapling_response = NULL;
831 gnutls_certificate_set_ocsp_status_request_function(
832 global->xcred, server_ocsp_status_req, global);
835 global->params_set = 1;
840 gnutls_certificate_free_credentials(global->xcred);
845 int tls_global_set_verify(void *ssl_ctx, int check_crl)
852 int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
853 int verify_peer, unsigned int flags,
854 const u8 *session_ctx, size_t session_ctx_len)
856 if (conn == NULL || conn->session == NULL)
859 conn->verify_peer = verify_peer;
860 gnutls_certificate_server_set_request(conn->session,
861 verify_peer ? GNUTLS_CERT_REQUIRE
862 : GNUTLS_CERT_REQUEST);
868 int tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn,
869 struct tls_random *keys)
871 #if GNUTLS_VERSION_NUMBER >= 0x030012
872 gnutls_datum_t client, server;
874 if (conn == NULL || conn->session == NULL || keys == NULL)
877 os_memset(keys, 0, sizeof(*keys));
878 gnutls_session_get_random(conn->session, &client, &server);
879 keys->client_random = client.data;
880 keys->server_random = server.data;
881 keys->client_random_len = client.size;
882 keys->server_random_len = client.size;
891 int tls_connection_export_key(void *tls_ctx, struct tls_connection *conn,
892 const char *label, u8 *out, size_t out_len)
894 if (conn == NULL || conn->session == NULL)
897 return gnutls_prf(conn->session, os_strlen(label), label,
898 0 /* client_random first */, 0, NULL, out_len,
903 int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
904 u8 *out, size_t out_len)
910 static void gnutls_tls_fail_event(struct tls_connection *conn,
911 const gnutls_datum_t *cert, int depth,
912 const char *subject, const char *err_str,
913 enum tls_fail_reason reason)
915 union tls_event_data ev;
916 struct tls_global *global = conn->global;
917 struct wpabuf *cert_buf = NULL;
919 if (global->event_cb == NULL)
922 os_memset(&ev, 0, sizeof(ev));
923 ev.cert_fail.depth = depth;
924 ev.cert_fail.subject = subject ? subject : "";
925 ev.cert_fail.reason = reason;
926 ev.cert_fail.reason_txt = err_str;
928 cert_buf = wpabuf_alloc_copy(cert->data, cert->size);
929 ev.cert_fail.cert = cert_buf;
931 global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev);
932 wpabuf_free(cert_buf);
936 #if GNUTLS_VERSION_NUMBER < 0x030300
937 static int server_eku_purpose(gnutls_x509_crt_t cert)
943 size_t oid_size = sizeof(oid);
946 res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid,
948 if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
950 /* No EKU - assume any use allowed */
957 wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU");
961 wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid);
962 if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 ||
963 os_strcmp(oid, GNUTLS_KP_ANY) == 0)
972 static int check_ocsp(struct tls_connection *conn, gnutls_session_t session,
973 gnutls_alert_description_t *err)
975 #if GNUTLS_VERSION_NUMBER >= 0x030103
976 gnutls_datum_t response, buf;
977 gnutls_ocsp_resp_t resp;
978 unsigned int cert_status;
981 if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)))
984 if (!gnutls_ocsp_status_request_is_checked(session, 0)) {
985 if (conn->flags & TLS_CONN_REQUIRE_OCSP) {
987 "GnuTLS: No valid OCSP response received");
991 wpa_printf(MSG_DEBUG,
992 "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required");
997 * GnuTLS has already verified the OCSP response in
998 * check_ocsp_response() and rejected handshake if the certificate was
999 * found to be revoked. However, if the response indicates that the
1000 * status is unknown, handshake continues and reaches here. We need to
1001 * re-import the OCSP response to check for unknown certificate status,
1002 * but we do not need to repeat gnutls_ocsp_resp_check_crt() and
1003 * gnutls_ocsp_resp_verify_direct() calls.
1006 res = gnutls_ocsp_status_request_get(session, &response);
1007 if (res != GNUTLS_E_SUCCESS) {
1008 wpa_printf(MSG_INFO,
1009 "GnuTLS: OCSP response was received, but it was not valid");
1013 if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS)
1016 res = gnutls_ocsp_resp_import(resp, &response);
1017 if (res != GNUTLS_E_SUCCESS) {
1018 wpa_printf(MSG_INFO,
1019 "GnuTLS: Could not parse received OCSP response: %s",
1020 gnutls_strerror(res));
1021 gnutls_ocsp_resp_deinit(resp);
1025 res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf);
1026 if (res == GNUTLS_E_SUCCESS) {
1027 wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data);
1028 gnutls_free(buf.data);
1031 res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL,
1032 NULL, &cert_status, NULL,
1034 gnutls_ocsp_resp_deinit(resp);
1035 if (res != GNUTLS_E_SUCCESS) {
1036 wpa_printf(MSG_INFO,
1037 "GnuTLS: Failed to extract OCSP information: %s",
1038 gnutls_strerror(res));
1042 if (cert_status == GNUTLS_OCSP_CERT_GOOD) {
1043 wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good");
1044 } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) {
1045 wpa_printf(MSG_DEBUG,
1046 "GnuTLS: OCSP cert status: revoked");
1049 wpa_printf(MSG_DEBUG,
1050 "GnuTLS: OCSP cert status: unknown");
1051 if (conn->flags & TLS_CONN_REQUIRE_OCSP)
1053 wpa_printf(MSG_DEBUG,
1054 "GnuTLS: OCSP was not required, so allow connection to continue");
1060 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1061 "bad certificate status response",
1063 *err = GNUTLS_A_CERTIFICATE_REVOKED;
1065 #else /* GnuTLS 3.1.3 or newer */
1067 #endif /* GnuTLS 3.1.3 or newer */
1071 static int tls_connection_verify_peer(gnutls_session_t session)
1073 struct tls_connection *conn;
1074 unsigned int status, num_certs, i;
1076 const gnutls_datum_t *certs;
1077 gnutls_x509_crt_t cert;
1078 gnutls_alert_description_t err;
1081 conn = gnutls_session_get_ptr(session);
1082 if (!conn->verify_peer) {
1083 wpa_printf(MSG_DEBUG,
1084 "GnuTLS: No peer certificate verification enabled");
1088 wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate");
1090 #if GNUTLS_VERSION_NUMBER >= 0x030300
1092 gnutls_typed_vdata_st data[1];
1093 unsigned int elements = 0;
1095 os_memset(data, 0, sizeof(data));
1096 if (!conn->global->server) {
1097 data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID;
1098 data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER;
1101 res = gnutls_certificate_verify_peers(session, data, 1,
1105 res = gnutls_certificate_verify_peers2(session, &status);
1108 wpa_printf(MSG_INFO, "TLS: Failed to verify peer "
1109 "certificate chain");
1110 err = GNUTLS_A_INTERNAL_ERROR;
1114 #if GNUTLS_VERSION_NUMBER >= 0x030104
1116 gnutls_datum_t info;
1119 type = gnutls_certificate_type_get(session);
1120 ret = gnutls_certificate_verification_status_print(status, type,
1123 wpa_printf(MSG_DEBUG,
1124 "GnuTLS: Failed to print verification status");
1125 err = GNUTLS_A_INTERNAL_ERROR;
1128 wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data);
1129 gnutls_free(info.data);
1131 #endif /* GnuTLS 3.1.4 or newer */
1133 certs = gnutls_certificate_get_peers(session, &num_certs);
1134 if (certs == NULL || num_certs == 0) {
1135 wpa_printf(MSG_INFO, "TLS: No peer certificate chain received");
1136 err = GNUTLS_A_UNKNOWN_CA;
1140 if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) {
1141 wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted");
1142 if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
1143 wpa_printf(MSG_INFO, "TLS: Certificate uses insecure "
1145 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1146 "certificate uses insecure algorithm",
1147 TLS_FAIL_BAD_CERTIFICATE);
1148 err = GNUTLS_A_INSUFFICIENT_SECURITY;
1151 if (status & GNUTLS_CERT_NOT_ACTIVATED) {
1152 wpa_printf(MSG_INFO, "TLS: Certificate not yet "
1154 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1155 "certificate not yet valid",
1156 TLS_FAIL_NOT_YET_VALID);
1157 err = GNUTLS_A_CERTIFICATE_EXPIRED;
1160 if (status & GNUTLS_CERT_EXPIRED) {
1161 wpa_printf(MSG_INFO, "TLS: Certificate expired");
1162 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1163 "certificate has expired",
1165 err = GNUTLS_A_CERTIFICATE_EXPIRED;
1168 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1169 "untrusted certificate",
1170 TLS_FAIL_UNTRUSTED);
1171 err = GNUTLS_A_INTERNAL_ERROR;
1175 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
1176 wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a "
1178 gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found",
1179 TLS_FAIL_UNTRUSTED);
1180 err = GNUTLS_A_UNKNOWN_CA;
1184 if (status & GNUTLS_CERT_REVOKED) {
1185 wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked");
1186 gnutls_tls_fail_event(conn, NULL, 0, NULL,
1187 "certificate revoked",
1189 err = GNUTLS_A_CERTIFICATE_REVOKED;
1194 wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d",
1196 err = GNUTLS_A_INTERNAL_ERROR;
1200 if (check_ocsp(conn, session, &err))
1205 for (i = 0; i < num_certs; i++) {
1208 if (gnutls_x509_crt_init(&cert) < 0) {
1209 wpa_printf(MSG_INFO, "TLS: Certificate initialization "
1211 err = GNUTLS_A_BAD_CERTIFICATE;
1215 if (gnutls_x509_crt_import(cert, &certs[i],
1216 GNUTLS_X509_FMT_DER) < 0) {
1217 wpa_printf(MSG_INFO, "TLS: Could not parse peer "
1218 "certificate %d/%d", i + 1, num_certs);
1219 gnutls_x509_crt_deinit(cert);
1220 err = GNUTLS_A_BAD_CERTIFICATE;
1224 gnutls_x509_crt_get_dn(cert, NULL, &len);
1226 buf = os_malloc(len + 1);
1228 buf[0] = buf[len] = '\0';
1229 gnutls_x509_crt_get_dn(cert, buf, &len);
1231 wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s",
1232 i + 1, num_certs, buf);
1234 if (conn->global->event_cb) {
1235 struct wpabuf *cert_buf = NULL;
1236 union tls_event_data ev;
1237 #ifdef CONFIG_SHA256
1241 #endif /* CONFIG_SHA256 */
1243 os_memset(&ev, 0, sizeof(ev));
1244 if (conn->global->cert_in_cb) {
1245 cert_buf = wpabuf_alloc_copy(certs[i].data,
1247 ev.peer_cert.cert = cert_buf;
1249 #ifdef CONFIG_SHA256
1250 _addr[0] = certs[i].data;
1251 _len[0] = certs[i].size;
1252 if (sha256_vector(1, _addr, _len, hash) == 0) {
1253 ev.peer_cert.hash = hash;
1254 ev.peer_cert.hash_len = sizeof(hash);
1256 #endif /* CONFIG_SHA256 */
1257 ev.peer_cert.depth = i;
1258 ev.peer_cert.subject = buf;
1259 conn->global->event_cb(conn->global->cb_ctx,
1260 TLS_PEER_CERTIFICATE, &ev);
1261 wpabuf_free(cert_buf);
1265 if (conn->suffix_match &&
1266 !gnutls_x509_crt_check_hostname(
1267 cert, conn->suffix_match)) {
1268 wpa_printf(MSG_WARNING,
1269 "TLS: Domain suffix match '%s' not found",
1270 conn->suffix_match);
1271 gnutls_tls_fail_event(
1272 conn, &certs[i], i, buf,
1273 "Domain suffix mismatch",
1274 TLS_FAIL_DOMAIN_SUFFIX_MISMATCH);
1275 err = GNUTLS_A_BAD_CERTIFICATE;
1276 gnutls_x509_crt_deinit(cert);
1281 #if GNUTLS_VERSION_NUMBER >= 0x030300
1282 if (conn->domain_match &&
1283 !gnutls_x509_crt_check_hostname2(
1284 cert, conn->domain_match,
1285 GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) {
1286 wpa_printf(MSG_WARNING,
1287 "TLS: Domain match '%s' not found",
1288 conn->domain_match);
1289 gnutls_tls_fail_event(
1290 conn, &certs[i], i, buf,
1292 TLS_FAIL_DOMAIN_MISMATCH);
1293 err = GNUTLS_A_BAD_CERTIFICATE;
1294 gnutls_x509_crt_deinit(cert);
1298 #endif /* >= 3.3.0 */
1300 /* TODO: validate altsubject_match.
1301 * For now, any such configuration is rejected in
1302 * tls_connection_set_params() */
1304 #if GNUTLS_VERSION_NUMBER < 0x030300
1306 * gnutls_certificate_verify_peers() not available, so
1307 * need to check EKU separately.
1309 if (!conn->global->server &&
1310 !server_eku_purpose(cert)) {
1311 wpa_printf(MSG_WARNING,
1312 "GnuTLS: No server EKU");
1313 gnutls_tls_fail_event(
1314 conn, &certs[i], i, buf,
1316 TLS_FAIL_BAD_CERTIFICATE);
1317 err = GNUTLS_A_BAD_CERTIFICATE;
1318 gnutls_x509_crt_deinit(cert);
1322 #endif /* < 3.3.0 */
1325 if (!conn->disable_time_checks &&
1326 (gnutls_x509_crt_get_expiration_time(cert) < now.sec ||
1327 gnutls_x509_crt_get_activation_time(cert) > now.sec)) {
1328 wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is "
1329 "not valid at this time",
1331 gnutls_tls_fail_event(
1332 conn, &certs[i], i, buf,
1333 "Certificate is not valid at this time",
1335 gnutls_x509_crt_deinit(cert);
1337 err = GNUTLS_A_CERTIFICATE_EXPIRED;
1343 gnutls_x509_crt_deinit(cert);
1346 if (conn->global->event_cb != NULL)
1347 conn->global->event_cb(conn->global->cb_ctx,
1348 TLS_CERT_CHAIN_SUCCESS, NULL);
1354 gnutls_alert_send(session, GNUTLS_AL_FATAL, err);
1355 return GNUTLS_E_CERTIFICATE_ERROR;
1359 static struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn)
1363 wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data");
1364 ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3);
1368 res = gnutls_record_recv(conn->session, wpabuf_mhead(ad),
1370 wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res);
1372 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
1373 "(%s)", __func__, (int) res,
1374 gnutls_strerror(res));
1379 wpabuf_put(ad, res);
1380 wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data",
1386 struct wpabuf * tls_connection_handshake(void *tls_ctx,
1387 struct tls_connection *conn,
1388 const struct wpabuf *in_data,
1389 struct wpabuf **appl_data)
1391 struct tls_global *global = tls_ctx;
1392 struct wpabuf *out_data;
1398 if (in_data && wpabuf_len(in_data) > 0) {
1399 if (conn->pull_buf) {
1400 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
1401 "pull_buf", __func__,
1402 (unsigned long) wpabuf_len(conn->pull_buf));
1403 wpabuf_free(conn->pull_buf);
1405 conn->pull_buf = wpabuf_dup(in_data);
1406 if (conn->pull_buf == NULL)
1408 conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1411 ret = gnutls_handshake(conn->session);
1413 gnutls_alert_description_t alert;
1414 union tls_event_data ev;
1417 case GNUTLS_E_AGAIN:
1418 if (global->server && conn->established &&
1419 conn->push_buf == NULL) {
1420 /* Need to return something to trigger
1421 * completion of EAP-TLS. */
1422 conn->push_buf = wpabuf_alloc(0);
1425 case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
1426 wpa_printf(MSG_DEBUG, "GnuTLS: Unacceptable DH prime");
1427 if (conn->global->event_cb) {
1428 os_memset(&ev, 0, sizeof(ev));
1429 ev.alert.is_local = 1;
1430 ev.alert.type = "fatal";
1431 ev.alert.description = "insufficient security";
1432 conn->global->event_cb(conn->global->cb_ctx,
1436 * Could send a TLS Alert to the server, but for now,
1437 * simply terminate handshake.
1440 conn->write_alerts++;
1442 case GNUTLS_E_FATAL_ALERT_RECEIVED:
1443 alert = gnutls_alert_get(conn->session);
1444 wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert",
1445 __func__, gnutls_alert_get_name(alert));
1446 conn->read_alerts++;
1447 if (conn->global->event_cb != NULL) {
1448 os_memset(&ev, 0, sizeof(ev));
1449 ev.alert.is_local = 0;
1450 ev.alert.type = gnutls_alert_get_name(alert);
1451 ev.alert.description = ev.alert.type;
1452 conn->global->event_cb(conn->global->cb_ctx,
1457 wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed "
1458 "-> %s", __func__, gnutls_strerror(ret));
1464 wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully");
1466 #if GNUTLS_VERSION_NUMBER >= 0x03010a
1470 desc = gnutls_session_get_desc(conn->session);
1472 wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc);
1476 #endif /* GnuTLS 3.1.10 or newer */
1478 conn->established = 1;
1479 if (conn->push_buf == NULL) {
1480 /* Need to return something to get final TLS ACK. */
1481 conn->push_buf = wpabuf_alloc(0);
1484 gnutls_session_get_data(conn->session, NULL, &size);
1485 if (global->session_data == NULL ||
1486 global->session_data_size < size) {
1487 os_free(global->session_data);
1488 global->session_data = os_malloc(size);
1490 if (global->session_data) {
1491 global->session_data_size = size;
1492 gnutls_session_get_data(conn->session,
1493 global->session_data,
1494 &global->session_data_size);
1497 if (conn->pull_buf && appl_data)
1498 *appl_data = gnutls_get_appl_data(conn);
1501 out_data = conn->push_buf;
1502 conn->push_buf = NULL;
1507 struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
1508 struct tls_connection *conn,
1509 const struct wpabuf *in_data,
1510 struct wpabuf **appl_data)
1512 return tls_connection_handshake(tls_ctx, conn, in_data, appl_data);
1516 struct wpabuf * tls_connection_encrypt(void *tls_ctx,
1517 struct tls_connection *conn,
1518 const struct wpabuf *in_data)
1523 res = gnutls_record_send(conn->session, wpabuf_head(in_data),
1524 wpabuf_len(in_data));
1526 wpa_printf(MSG_INFO, "%s: Encryption failed: %s",
1527 __func__, gnutls_strerror(res));
1531 buf = conn->push_buf;
1532 conn->push_buf = NULL;
1537 struct wpabuf * tls_connection_decrypt(void *tls_ctx,
1538 struct tls_connection *conn,
1539 const struct wpabuf *in_data)
1544 if (conn->pull_buf) {
1545 wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in "
1546 "pull_buf", __func__,
1547 (unsigned long) wpabuf_len(conn->pull_buf));
1548 wpabuf_free(conn->pull_buf);
1550 conn->pull_buf = wpabuf_dup(in_data);
1551 if (conn->pull_buf == NULL)
1553 conn->pull_buf_offset = wpabuf_head(conn->pull_buf);
1556 * Even though we try to disable TLS compression, it is possible that
1557 * this cannot be done with all TLS libraries. Add extra buffer space
1558 * to handle the possibility of the decrypted data being longer than
1561 out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3);
1565 res = gnutls_record_recv(conn->session, wpabuf_mhead(out),
1568 wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d "
1569 "(%s)", __func__, (int) res, gnutls_strerror(res));
1573 wpabuf_put(out, res);
1579 int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
1583 return gnutls_session_is_resumed(conn->session);
1587 int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
1595 int tls_get_version(void *ssl_ctx, struct tls_connection *conn,
1596 char *buf, size_t buflen)
1598 gnutls_protocol_t ver;
1600 ver = gnutls_protocol_get_version(conn->session);
1601 if (ver == GNUTLS_TLS1_0)
1602 os_strlcpy(buf, "TLSv1", buflen);
1603 else if (ver == GNUTLS_TLS1_1)
1604 os_strlcpy(buf, "TLSv1.1", buflen);
1605 else if (ver == GNUTLS_TLS1_2)
1606 os_strlcpy(buf, "TLSv1.2", buflen);
1613 int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
1614 char *buf, size_t buflen)
1616 gnutls_cipher_algorithm_t cipher;
1617 gnutls_kx_algorithm_t kx;
1618 gnutls_mac_algorithm_t mac;
1619 const char *kx_str, *cipher_str, *mac_str;
1622 cipher = gnutls_cipher_get(conn->session);
1623 cipher_str = gnutls_cipher_get_name(cipher);
1627 kx = gnutls_kx_get(conn->session);
1628 kx_str = gnutls_kx_get_name(kx);
1632 mac = gnutls_mac_get(conn->session);
1633 mac_str = gnutls_mac_get_name(mac);
1637 if (kx == GNUTLS_KX_RSA)
1638 res = os_snprintf(buf, buflen, "%s-%s", cipher_str, mac_str);
1640 res = os_snprintf(buf, buflen, "%s-%s-%s",
1641 kx_str, cipher_str, mac_str);
1642 if (os_snprintf_error(buflen, res))
1649 int tls_connection_enable_workaround(void *ssl_ctx,
1650 struct tls_connection *conn)
1652 gnutls_record_disable_padding(conn->session);
1657 int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
1658 int ext_type, const u8 *data,
1666 int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
1670 return conn->failed;
1674 int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
1678 return conn->read_alerts;
1682 int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
1686 return conn->write_alerts;
1690 int tls_connection_set_session_ticket_cb(void *tls_ctx,
1691 struct tls_connection *conn,
1692 tls_session_ticket_cb cb, void *ctx)
1698 int tls_get_library_version(char *buf, size_t buf_len)
1700 return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s",
1701 GNUTLS_VERSION, gnutls_check_version(NULL));
1705 void tls_connection_set_success_data(struct tls_connection *conn,
1706 struct wpabuf *data)
1711 void tls_connection_set_success_data_resumed(struct tls_connection *conn)
1716 const struct wpabuf *
1717 tls_connection_get_success_data(struct tls_connection *conn)
1723 void tls_connection_remove_session(struct tls_connection *conn)