18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SSL/TLS interface functions for GnuTLS 31f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <gnutls/gnutls.h> 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <gnutls/x509.h> 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <gnutls/pkcs12.h> 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 15ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030103 16ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#include <gnutls/ocsp.h> 17ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* 3.1.3 */ 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 20ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#include "crypto/crypto.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tls.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_gnutls_ref_count = 0; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_global { 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Data for session resumption */ 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void *session_data; 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t session_data_size; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int server; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int params_set; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_credentials_t xcred; 35ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 36ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt void (*event_cb)(void *ctx, enum tls_event ev, 37ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt union tls_event_data *data); 38ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt void *cb_ctx; 39ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int cert_in_cb; 40d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 41d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt char *ocsp_stapling_response; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 45ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct tls_global *global; 466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt gnutls_session_t session; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int read_alerts, write_alerts, failed; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pre_shared_secret; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t pre_shared_secret_len; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int established; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verify_peer; 53ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt unsigned int disable_time_checks:1; 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *push_buf; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *pull_buf; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pull_buf_offset; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int params_set; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_credentials_t xcred; 61ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 62ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt char *suffix_match; 632f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt char *domain_match; 64ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt unsigned int flags; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int tls_connection_verify_peer(gnutls_session_t session); 69ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 70ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void tls_log_func(int level, const char *msg) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *s, *pos; 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (level == 6 || level == 7) { 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* These levels seem to be mostly I/O debug and msg dumps */ 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt s = os_strdup(msg); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (s == NULL) 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = s; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (*pos != '\0') { 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*pos == '\n') { 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos = '\0'; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos++; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(level > 3 ? MSG_MSGDUMP : MSG_DEBUG, 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "gnutls<%d> %s", level, s); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(s); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 101ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (tls_gnutls_ref_count == 0) { 102ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 103ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Library version %s (runtime) - %s (build)", 104ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_check_version(NULL), GNUTLS_VERSION); 105ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = os_zalloc(sizeof(*global)); 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global == NULL) 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_gnutls_ref_count == 0 && gnutls_global_init() < 0) { 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global); 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_gnutls_ref_count++; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_global_set_log_function(tls_log_func); 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_debug_show_keys) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_global_set_log_level(11); 120ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 121ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conf) { 122ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt global->event_cb = conf->event_cb; 123ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt global->cb_ctx = conf->cb_ctx; 124ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt global->cert_in_cb = conf->cert_in_cb; 125ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 126ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return global; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = ssl_ctx; 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global) { 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->params_set) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_free_credentials(global->xcred); 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global->session_data); 138d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(global->ocsp_stapling_response); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global); 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_gnutls_ref_count--; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_gnutls_ref_count == 0) 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_global_deinit(); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic ssize_t tls_pull_func(gnutls_transport_ptr_t ptr, void *buf, 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = (struct tls_connection *) ptr; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end; 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf == NULL) { 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errno = EWOULDBLOCK; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = wpabuf_head_u8(conn->pull_buf) + wpabuf_len(conn->pull_buf); 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if ((size_t) (end - conn->pull_buf_offset) < len) 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = end - conn->pull_buf_offset; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(buf, conn->pull_buf_offset, len); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf_offset += len; 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf_offset == end) { 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - pull_buf consumed", __func__); 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->pull_buf); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf = NULL; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf_offset = NULL; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in pull_buf", 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) (end - conn->pull_buf_offset)); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtstatic ssize_t tls_push_func(gnutls_transport_ptr_t ptr, const void *buf, 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len) 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn = (struct tls_connection *) ptr; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_resize(&conn->push_buf, len) < 0) { 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt errno = ENOMEM; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(conn->push_buf, buf, len); 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_gnutls_init_session(struct tls_global *global, 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt const char *err; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_init(&conn->session, 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->server ? GNUTLS_SERVER : GNUTLS_CLIENT); 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to initialize new TLS " 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection: %s", gnutls_strerror(ret)); 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_set_default_priority(conn->session); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt ret = gnutls_priority_set_direct(conn->session, "NORMAL:-VERS-SSL3.0", 2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt &err); 2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (ret < 0) { 2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_ERROR, "GnuTLS: Priority string failure at " 2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt "'%s'", err); 2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt goto fail; 2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_transport_set_pull_function(conn->session, tls_pull_func); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_transport_set_push_function(conn->session, tls_push_func); 2266c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt gnutls_transport_set_ptr(conn->session, (gnutls_transport_ptr_t) conn); 227ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_session_set_ptr(conn->session, conn); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to setup new TLS connection: %s", 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_deinit(conn->session); 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = ssl_ctx; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 248ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->global = global; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_gnutls_init_session(global, conn)) { 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->params_set) { 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_credentials_set(conn->session, 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_CRD_CERTIFICATE, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to configure " 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "credentials: %s", gnutls_strerror(ret)); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gnutls_certificate_allocate_credentials(&conn->xcred)) { 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_free_credentials(conn->xcred); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_deinit(conn->session); 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn->pre_shared_secret); 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->push_buf); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->pull_buf); 286ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(conn->suffix_match); 2872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? conn->established : 0; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = ssl_ctx; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Shutdown previous TLS connection without notifying the peer 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * because the connection was already terminated in practice 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and "close notify" shutdown alert would confuse AS. */ 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_bye(conn->session, GNUTLS_SHUT_RDWR); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->push_buf); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf = NULL; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->established = 0; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_deinit(conn->session); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_gnutls_init_session(global, conn)) { 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: Failed to preparare new session " 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for session resumption use"); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->params_set ? conn->xcred : 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred); 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: Failed to configure credentials " 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for session resumption: %s", gnutls_strerror(ret)); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->session_data) { 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_session_set_data(conn->session, 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data, 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data_size); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: Failed to set session " 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data: %s", gnutls_strerror(ret)); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || params == NULL) 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 353d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP_ALL) { 354d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_INFO, 355d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt "GnuTLS: ocsp=3 not supported"); 356d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return -1; 357d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 358d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 3591b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (params->flags & TLS_CONN_EXT_CERT_CHECK) { 3601b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt wpa_printf(MSG_INFO, 3611b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt "GnuTLS: tls_ext_cert_check=1 not supported"); 3621b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt return -1; 3631b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt } 3641b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->subject_match) { 366ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported"); 367ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->altsubject_match) { 371ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: altsubject_match not supported"); 372ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 373ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 374ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 375ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(conn->suffix_match); 376ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->suffix_match = NULL; 377ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (params->suffix_match) { 378ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->suffix_match = os_strdup(params->suffix_match); 379ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->suffix_match == NULL) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3832f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030300 3842f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(conn->domain_match); 3852f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = NULL; 3862f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (params->domain_match) { 3872f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match = os_strdup(params->domain_match); 3882f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (conn->domain_match == NULL) 3892f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 3902f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 3912f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#else /* < 3.3.0 */ 3922f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (params->domain_match) { 3932f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: domain_match not supported"); 3942f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt return -1; 3952f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 3962f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#endif /* >= 3.3.0 */ 3972f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 398ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->flags = params->flags; 399ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 400ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (params->openssl_ciphers) { 401ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: openssl_ciphers not supported"); 402ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 403ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 404ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 405293335998d38c497293b1c41f7ad8342b507d458Dmitry Shmidt /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to force peer validation(?) */ 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->ca_cert) { 409ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: Try to parse %s in DER format", 410ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->ca_cert); 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_trust_file( 412ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 414ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 415ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Failed to read CA cert '%s' in DER format (%s) - try in PEM format", 416ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->ca_cert, 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_trust_file( 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, params->ca_cert, 420ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt GNUTLS_X509_FMT_PEM); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 422ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 423ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "Failed to read CA cert '%s' in PEM format: %s", 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert, 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 429ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (params->ca_cert_blob) { 430ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t ca; 431ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 432ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ca.data = (unsigned char *) params->ca_cert_blob; 433ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ca.size = params->ca_cert_blob_len; 434ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 435ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_trust_mem( 436ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &ca, GNUTLS_X509_FMT_DER); 437ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret < 0) { 438ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 439ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "Failed to parse CA cert in DER format: %s", 440ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_strerror(ret)); 441ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_trust_mem( 442ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &ca, GNUTLS_X509_FMT_PEM); 443ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret < 0) { 444ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 445ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "Failed to parse CA cert in PEM format: %s", 446ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_strerror(ret)); 447ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 448ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 449ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 450ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (params->ca_path) { 451ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: ca_path not supported"); 452ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 453ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 454ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 455ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->disable_time_checks = 0; 456ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (params->ca_cert || params->ca_cert_blob) { 457ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->verify_peer = 1; 458ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_certificate_set_verify_function( 459ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, tls_connection_verify_peer); 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_set_verify_flags( 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 467ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->disable_time_checks = 1; 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_set_verify_flags( 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->client_cert && params->private_key) { 4756c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x03010b 4766c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = gnutls_certificate_set_x509_key_file2( 4776c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conn->xcred, params->client_cert, params->private_key, 478ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt GNUTLS_X509_FMT_DER, params->private_key_passwd, 0); 4796c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#else 4806c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* private_key_passwd not (easily) supported here */ 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_key_file( 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, params->client_cert, params->private_key, 483ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt GNUTLS_X509_FMT_DER); 4846c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 487ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "in DER format: %s", gnutls_strerror(ret)); 4886c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x03010b 4896c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt ret = gnutls_certificate_set_x509_key_file2( 4906c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt conn->xcred, params->client_cert, 491ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key, GNUTLS_X509_FMT_PEM, 4926c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->private_key_passwd, 0); 4936c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#else 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_key_file( 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, params->client_cert, 496ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key, GNUTLS_X509_FMT_PEM); 4976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt#endif 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client " 500ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "cert/key in PEM format: %s", 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (params->private_key) { 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pkcs12_ok = 0; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to load in PKCS#12 format */ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_simple_pkcs12_file( 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd); 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != 0) { 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to load private_key in " 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PKCS#12 format: %s", gnutls_strerror(ret)); 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs12_ok = 1; 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pkcs12_ok) { 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 525ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (params->client_cert_blob && params->private_key_blob) { 526ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t cert, key; 527ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 528ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt cert.data = (unsigned char *) params->client_cert_blob; 529ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt cert.size = params->client_cert_blob_len; 530ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt key.data = (unsigned char *) params->private_key_blob; 531ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt key.size = params->private_key_blob_len; 532ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 533ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x03010b 534ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_key_mem2( 535ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER, 536ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key_passwd, 0); 537ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else 538ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* private_key_passwd not (easily) supported here */ 539ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_key_mem( 540ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &cert, &key, GNUTLS_X509_FMT_DER); 541ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif 542ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret < 0) { 543ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 544ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "in DER format: %s", gnutls_strerror(ret)); 545ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x03010b 546ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_key_mem2( 547ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM, 548ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key_passwd, 0); 549ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else 550ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* private_key_passwd not (easily) supported here */ 551ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_key_mem( 552ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &cert, &key, GNUTLS_X509_FMT_PEM); 553ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif 554ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret < 0) { 555ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client " 556ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "cert/key in PEM format: %s", 557ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_strerror(ret)); 558ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return ret; 559ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 560ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 561ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (params->private_key_blob) { 562ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#ifdef PKCS12_FUNCS 563ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t key; 564ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 565ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt key.data = (unsigned char *) params->private_key_blob; 566ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt key.size = params->private_key_blob_len; 567ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 568ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* Try to load in PKCS#12 format */ 569ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_set_x509_simple_pkcs12_mem( 570ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->xcred, &key, GNUTLS_X509_FMT_DER, 571ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key_passwd); 572ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret != 0) { 573ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to load private_key in " 574ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "PKCS#12 format: %s", gnutls_strerror(ret)); 575ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 576ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 577ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else /* PKCS12_FUNCS */ 578ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not included"); 579ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 580ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* PKCS12_FUNCS */ 581ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 582ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 583ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030103 584ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (params->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP)) { 585ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_ocsp_status_request_enable_client(conn->session, 586ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt NULL, 0, NULL); 587ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret != GNUTLS_E_SUCCESS) { 588ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 589ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Failed to enable OCSP client"); 590ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 591ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 592ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 593ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else /* 3.1.3 */ 594ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (params->flags & TLS_CONN_REQUIRE_OCSP) { 595ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 596ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: OCSP not supported by this version of GnuTLS"); 597ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 599ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* 3.1.3 */ 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->params_set = 1; 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->xcred); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "Failed to configure credentials: %s", 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 614d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030103 615d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidtstatic int server_ocsp_status_req(gnutls_session_t session, void *ptr, 616d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt gnutls_datum_t *resp) 617d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt{ 618d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt struct tls_global *global = ptr; 619d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt char *cached; 620d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt size_t len; 621d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 622d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (!global->ocsp_stapling_response) { 623d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: OCSP status callback - no response configured"); 624d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return GNUTLS_E_NO_CERTIFICATE_STATUS; 625d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 626d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 627d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt cached = os_readfile(global->ocsp_stapling_response, &len); 628d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (!cached) { 629d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_DEBUG, 630d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt "GnuTLS: OCSP status callback - could not read response file (%s)", 631d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt global->ocsp_stapling_response); 632d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return GNUTLS_E_NO_CERTIFICATE_STATUS; 633d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 634d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 635d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt wpa_printf(MSG_DEBUG, 636d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt "GnuTLS: OCSP status callback - send cached response"); 637d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt resp->data = gnutls_malloc(len); 638d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (!resp->data) { 639d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(resp); 640d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return GNUTLS_E_MEMORY_ERROR; 641d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt } 642d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 643d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_memcpy(resp->data, cached, len); 644d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt resp->size = len; 645d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(cached); 646d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 647d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt return GNUTLS_E_SUCCESS; 648d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt} 649d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt#endif /* 3.1.3 */ 650d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 651d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Currently, global parameters are only set when running in server 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * mode. */ 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->server = 1; 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->params_set) { 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_free_credentials(global->xcred); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->params_set = 0; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_allocate_credentials(&global->xcred); 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) { 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%s", gnutls_strerror(ret)); 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->ca_cert) { 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_trust_file( 676ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " 679ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "in DER format: %s", params->ca_cert, 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_trust_file( 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, params->ca_cert, 683ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt GNUTLS_X509_FMT_PEM); 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read CA cert " 686ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "'%s' in PEM format: %s", 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert, 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_set_verify_flags( 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_set_verify_flags( 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_VERIFY_DISABLE_TIME_CHECKS); 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (params->client_cert && params->private_key) { 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: private_key_passwd? */ 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_key_file( 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, params->client_cert, 710ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key, GNUTLS_X509_FMT_DER); 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client cert/key " 713ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "in DER format: %s", gnutls_strerror(ret)); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_key_file( 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, params->client_cert, 716ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt params->private_key, GNUTLS_X509_FMT_PEM); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to read client " 719ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "cert/key in PEM format: %s", 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(ret)); 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (params->private_key) { 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int pkcs12_ok = 0; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef PKCS12_FUNCS 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Try to load in PKCS#12 format */ 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_certificate_set_x509_simple_pkcs12_file( 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->xcred, params->private_key, 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_X509_FMT_DER, params->private_key_passwd); 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret != 0) { 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to load private_key in " 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PKCS#12 format: %s", gnutls_strerror(ret)); 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pkcs12_ok = 1; 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* PKCS12_FUNCS */ 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!pkcs12_ok) { 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "included"); 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 746d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030103 747d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_free(global->ocsp_stapling_response); 748d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (params->ocsp_stapling_response) 749d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt global->ocsp_stapling_response = 750d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt os_strdup(params->ocsp_stapling_response); 751d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt else 752d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt global->ocsp_stapling_response = NULL; 753d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt gnutls_certificate_set_ocsp_status_request_function( 754d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt global->xcred, server_ocsp_status_req, global); 755d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt#endif /* 3.1.3 */ 756d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->params_set = 1; 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_free_credentials(global->xcred); 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 775d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int verify_peer, unsigned int flags, 776d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt const u8 *session_ctx, size_t session_ctx_len) 7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session == NULL) 7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->verify_peer = verify_peer; 7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_certificate_server_set_request(conn->session, 7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt verify_peer ? GNUTLS_CERT_REQUIRE 7848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt : GNUTLS_CERT_REQUEST); 7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 790d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_connection_get_random(void *ssl_ctx, struct tls_connection *conn, 791d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_random *keys) 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 793ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030012 794ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t client, server; 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || conn->session == NULL || keys == NULL) 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(keys, 0, sizeof(*keys)); 800ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_session_get_random(conn->session, &client, &server); 801ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt keys->client_random = client.data; 802ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt keys->server_random = server.data; 803ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt keys->client_random_len = client.size; 804ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt keys->server_random_len = client.size; 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 807ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else /* 3.0.18 */ 808ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return -1; 809ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* 3.0.18 */ 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 813849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_export_key(void *tls_ctx, struct tls_connection *conn, 814849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt const char *label, u8 *out, size_t out_len) 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 816849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (conn == NULL || conn->session == NULL) 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return gnutls_prf(conn->session, os_strlen(label), label, 820849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 0 /* client_random first */, 0, NULL, out_len, 821849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt (char *) out); 822849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt} 823849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 824849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt 825849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidtint tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn, 826849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt u8 *out, size_t out_len) 827849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt{ 828849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt return -1; 829ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 830ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 831ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 832ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic void gnutls_tls_fail_event(struct tls_connection *conn, 833ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt const gnutls_datum_t *cert, int depth, 834ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt const char *subject, const char *err_str, 835ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt enum tls_fail_reason reason) 836ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 837ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt union tls_event_data ev; 838ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct tls_global *global = conn->global; 839ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct wpabuf *cert_buf = NULL; 840ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 841ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (global->event_cb == NULL) 842ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return; 843ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 844ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 845ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.cert_fail.depth = depth; 846ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.cert_fail.subject = subject ? subject : ""; 847ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.cert_fail.reason = reason; 848ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.cert_fail.reason_txt = err_str; 849ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (cert) { 850ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt cert_buf = wpabuf_alloc_copy(cert->data, cert->size); 851ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.cert_fail.cert = cert_buf; 852ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 853ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt global->event_cb(global->cb_ctx, TLS_CERT_CHAIN_FAILURE, &ev); 854ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpabuf_free(cert_buf); 855ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 856ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 857ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 858ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER < 0x030300 859ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int server_eku_purpose(gnutls_x509_crt_t cert) 860ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 861ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt unsigned int i; 862ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 863ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt for (i = 0; ; i++) { 864ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt char oid[128]; 865ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt size_t oid_size = sizeof(oid); 866ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int res; 867ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 868ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_x509_crt_get_key_purpose_oid(cert, i, oid, 869ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt &oid_size, NULL); 870ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { 871ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i == 0) { 872ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* No EKU - assume any use allowed */ 873ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 1; 874ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 875ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt break; 876ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 877ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 878ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res < 0) { 879ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "GnuTLS: Failed to get EKU"); 880ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 881ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 882ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 883ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: Certificate purpose: %s", oid); 884ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (os_strcmp(oid, GNUTLS_KP_TLS_WWW_SERVER) == 0 || 885ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_strcmp(oid, GNUTLS_KP_ANY) == 0) 886ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 1; 887ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 888ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 889ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 890ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 891ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* < 3.3.0 */ 892ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 893ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 894ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int check_ocsp(struct tls_connection *conn, gnutls_session_t session, 895ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_alert_description_t *err) 896ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 897ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030103 898ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t response, buf; 899ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_ocsp_resp_t resp; 900ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt unsigned int cert_status; 901ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int res; 902ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 903ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!(conn->flags & (TLS_CONN_REQUEST_OCSP | TLS_CONN_REQUIRE_OCSP))) 904ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 905ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 906ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!gnutls_ocsp_status_request_is_checked(session, 0)) { 907ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->flags & TLS_CONN_REQUIRE_OCSP) { 908ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 909ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: No valid OCSP response received"); 910ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 911ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 912ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 913ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 914ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Valid OCSP response was not received - continue since OCSP was not required"); 915ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 916ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 917ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 918ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* 919ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * GnuTLS has already verified the OCSP response in 920ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * check_ocsp_response() and rejected handshake if the certificate was 921ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * found to be revoked. However, if the response indicates that the 922ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * status is unknown, handshake continues and reaches here. We need to 923ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * re-import the OCSP response to check for unknown certificate status, 924ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * but we do not need to repeat gnutls_ocsp_resp_check_crt() and 925ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * gnutls_ocsp_resp_verify_direct() calls. 926ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt */ 927ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 928ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_ocsp_status_request_get(session, &response); 929ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res != GNUTLS_E_SUCCESS) { 930ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 931ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: OCSP response was received, but it was not valid"); 932ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 933ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 934ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 935ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (gnutls_ocsp_resp_init(&resp) != GNUTLS_E_SUCCESS) 936ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 937ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 938ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_ocsp_resp_import(resp, &response); 939ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res != GNUTLS_E_SUCCESS) { 940ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 941ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Could not parse received OCSP response: %s", 942ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_strerror(res)); 943ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_ocsp_resp_deinit(resp); 944ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 945ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 946ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 947ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_ocsp_resp_print(resp, GNUTLS_OCSP_PRINT_FULL, &buf); 948ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res == GNUTLS_E_SUCCESS) { 949ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: %s", buf.data); 950ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_free(buf.data); 951ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 952ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 953ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_ocsp_resp_get_single(resp, 0, NULL, NULL, NULL, 954ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt NULL, &cert_status, NULL, 955ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt NULL, NULL, NULL); 956ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_ocsp_resp_deinit(resp); 957ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res != GNUTLS_E_SUCCESS) { 958ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, 959ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Failed to extract OCSP information: %s", 960ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_strerror(res)); 961ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 962ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 963ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 964ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (cert_status == GNUTLS_OCSP_CERT_GOOD) { 965ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: OCSP cert status: good"); 966ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else if (cert_status == GNUTLS_OCSP_CERT_REVOKED) { 967ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 968ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: OCSP cert status: revoked"); 969ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 970ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } else { 971ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 972ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: OCSP cert status: unknown"); 973ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->flags & TLS_CONN_REQUIRE_OCSP) 974ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto ocsp_error; 975ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 976ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: OCSP was not required, so allow connection to continue"); 977ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 978ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 979ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 980ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 981ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtocsp_error: 982ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 983ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "bad certificate status response", 984ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_REVOKED); 985ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt *err = GNUTLS_A_CERTIFICATE_REVOKED; 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 987ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else /* GnuTLS 3.1.3 or newer */ 988ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 989ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* GnuTLS 3.1.3 or newer */ 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 993ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtstatic int tls_connection_verify_peer(gnutls_session_t session) 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 995ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct tls_connection *conn; 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int status, num_certs, i; 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct os_time now; 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const gnutls_datum_t *certs; 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_t cert; 1000ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_alert_description_t err; 1001ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int res; 1002ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1003ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn = gnutls_session_get_ptr(session); 1004ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!conn->verify_peer) { 1005ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 1006ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: No peer certificate verification enabled"); 1007ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return 0; 1008ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1009ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1010ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTSL: Verifying peer certificate"); 1011ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1012ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030300 1013ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt { 1014ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_typed_vdata_st data[1]; 1015ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt unsigned int elements = 0; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1017ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(data, 0, sizeof(data)); 1018ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!conn->global->server) { 1019ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt data[elements].type = GNUTLS_DT_KEY_PURPOSE_OID; 1020ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt data[elements].data = (void *) GNUTLS_KP_TLS_WWW_SERVER; 1021ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt elements++; 1022ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1023ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_certificate_verify_peers(session, data, 1, 1024ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt &status); 1025ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1026ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#else /* < 3.3.0 */ 1027ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt res = gnutls_certificate_verify_peers2(session, &status); 1028ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif 1029ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (res < 0) { 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to verify peer " 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate chain"); 1032ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_INTERNAL_ERROR; 1033ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 1034ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1035ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1036ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030104 1037ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt { 1038ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_datum_t info; 1039ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt int ret, type; 1040ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1041ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt type = gnutls_certificate_type_get(session); 1042ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ret = gnutls_certificate_verification_status_print(status, type, 1043ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt &info, 0); 1044ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (ret < 0) { 1045ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, 1046ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: Failed to print verification status"); 1047ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_INTERNAL_ERROR; 1048ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 1049ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1050ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: %s", info.data); 1051ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_free(info.data); 1052ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1053ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* GnuTLS 3.1.4 or newer */ 1054ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1055ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt certs = gnutls_certificate_get_peers(session, &num_certs); 1056ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (certs == NULL || num_certs == 0) { 1057ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "TLS: No peer certificate chain received"); 1058ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_UNKNOWN_CA; 1059ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->verify_peer && (status & GNUTLS_CERT_INVALID)) { 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Peer certificate not trusted"); 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Certificate uses insecure " 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "algorithm"); 1067ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 1068ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "certificate uses insecure algorithm", 1069ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_BAD_CERTIFICATE); 1070ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_INSUFFICIENT_SECURITY; 1071ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status & GNUTLS_CERT_NOT_ACTIVATED) { 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Certificate not yet " 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "activated"); 1076ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 1077ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "certificate not yet valid", 1078ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_NOT_YET_VALID); 1079ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_CERTIFICATE_EXPIRED; 1080ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status & GNUTLS_CERT_EXPIRED) { 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Certificate expired"); 1084ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 1085ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "certificate has expired", 1086ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_EXPIRED); 1087ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_CERTIFICATE_EXPIRED; 1088ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1090ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 1091ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "untrusted certificate", 1092ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_UNTRUSTED); 1093ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_INTERNAL_ERROR; 1094ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Peer certificate does not have a " 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "known issuer"); 1100ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, "signed not found", 1101ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_UNTRUSTED); 1102ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_UNKNOWN_CA; 1103ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status & GNUTLS_CERT_REVOKED) { 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Peer certificate has been revoked"); 1108ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event(conn, NULL, 0, NULL, 1109ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "certificate revoked", 1110ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_REVOKED); 1111ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_CERTIFICATE_REVOKED; 1112ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1115ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (status != 0) { 1116ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_INFO, "TLS: Unknown verification status: %d", 1117ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt status); 1118ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_INTERNAL_ERROR; 1119ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 11208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1122ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (check_ocsp(conn, session, &err)) 1123ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 1124ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1125ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_get_time(&now); 1126ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 11278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_certs; i++) { 11288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf; 11298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 11308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gnutls_x509_crt_init(&cert) < 0) { 11318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Certificate initialization " 11328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed"); 1133ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_BAD_CERTIFICATE; 1134ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 11358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gnutls_x509_crt_import(cert, &certs[i], 11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt GNUTLS_X509_FMT_DER) < 0) { 11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Could not parse peer " 11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "certificate %d/%d", i + 1, num_certs); 11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_deinit(cert); 1142ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_BAD_CERTIFICATE; 1143ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_get_dn(cert, NULL, &len); 11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len++; 11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = os_malloc(len + 1); 11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf) { 11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = buf[len] = '\0'; 11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_get_dn(cert, buf, &len); 11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Peer cert chain %d/%d: %s", 11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i + 1, num_certs, buf); 11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1156ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->global->event_cb) { 1157ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt struct wpabuf *cert_buf = NULL; 1158ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt union tls_event_data ev; 1159ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#ifdef CONFIG_SHA256 1160ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt u8 hash[32]; 1161ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt const u8 *_addr[1]; 1162ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt size_t _len[1]; 1163ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* CONFIG_SHA256 */ 1164ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1165ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 1166ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->global->cert_in_cb) { 1167ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt cert_buf = wpabuf_alloc_copy(certs[i].data, 1168ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt certs[i].size); 1169ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.peer_cert.cert = cert_buf; 1170ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1171ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#ifdef CONFIG_SHA256 1172ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt _addr[0] = certs[i].data; 1173ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt _len[0] = certs[i].size; 1174ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (sha256_vector(1, _addr, _len, hash) == 0) { 1175ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.peer_cert.hash = hash; 1176ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.peer_cert.hash_len = sizeof(hash); 1177ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1178ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* CONFIG_SHA256 */ 1179ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.peer_cert.depth = i; 1180ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.peer_cert.subject = buf; 1181ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->global->event_cb(conn->global->cb_ctx, 1182ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_PEER_CERTIFICATE, &ev); 1183ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpabuf_free(cert_buf); 11848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1186ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (i == 0) { 1187ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->suffix_match && 1188ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt !gnutls_x509_crt_check_hostname( 1189ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt cert, conn->suffix_match)) { 1190ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_WARNING, 1191ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "TLS: Domain suffix match '%s' not found", 1192ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->suffix_match); 1193ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event( 1194ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn, &certs[i], i, buf, 1195ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "Domain suffix mismatch", 1196ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_DOMAIN_SUFFIX_MISMATCH); 1197ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_BAD_CERTIFICATE; 1198ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_x509_crt_deinit(cert); 1199ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(buf); 1200ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 1201ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1202ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 12032f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x030300 12042f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt if (conn->domain_match && 12052f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt !gnutls_x509_crt_check_hostname2( 12062f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt cert, conn->domain_match, 12072f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS)) { 12082f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt wpa_printf(MSG_WARNING, 12092f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "TLS: Domain match '%s' not found", 12102f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn->domain_match); 12112f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gnutls_tls_fail_event( 12122f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt conn, &certs[i], i, buf, 12132f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt "Domain mismatch", 12142f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt TLS_FAIL_DOMAIN_MISMATCH); 12152f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt err = GNUTLS_A_BAD_CERTIFICATE; 12162f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt gnutls_x509_crt_deinit(cert); 12172f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt os_free(buf); 12182f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt goto out; 12192f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt } 12202f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt#endif /* >= 3.3.0 */ 12212f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt 1222ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* TODO: validate altsubject_match. 1223ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * For now, any such configuration is rejected in 1224ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * tls_connection_set_params() */ 1225ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1226ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER < 0x030300 1227ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt /* 1228ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * gnutls_certificate_verify_peers() not available, so 1229ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt * need to check EKU separately. 1230ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt */ 1231ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!conn->global->server && 1232ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt !server_eku_purpose(cert)) { 1233ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_WARNING, 1234ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "GnuTLS: No server EKU"); 1235ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event( 1236ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn, &certs[i], i, buf, 1237ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "No server EKU", 1238ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_BAD_CERTIFICATE); 1239ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_BAD_CERTIFICATE; 1240ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_x509_crt_deinit(cert); 1241ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(buf); 1242ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 1243ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 1244ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* < 3.3.0 */ 1245ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 12468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1247ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (!conn->disable_time_checks && 1248ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt (gnutls_x509_crt_get_expiration_time(cert) < now.sec || 1249ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_x509_crt_get_activation_time(cert) > now.sec)) { 12508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Peer certificate %d/%d is " 12518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "not valid at this time", 12528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt i + 1, num_certs); 1253ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_tls_fail_event( 1254ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn, &certs[i], i, buf, 1255ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt "Certificate is not valid at this time", 1256ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_FAIL_EXPIRED); 12578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_deinit(cert); 1258ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(buf); 1259ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt err = GNUTLS_A_CERTIFICATE_EXPIRED; 1260ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt goto out; 12618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1263ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_free(buf); 1264ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 12658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_x509_crt_deinit(cert); 12668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 12678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->global->event_cb != NULL) 1269ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->global->event_cb(conn->global->cb_ctx, 1270ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_CERT_CHAIN_SUCCESS, NULL); 1271ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 12728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1273ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1274ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtout: 1275ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->failed++; 1276ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_alert_send(session, GNUTLS_AL_FATAL, err); 1277ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return GNUTLS_E_CERTIFICATE_ERROR; 12788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 12798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * gnutls_get_appl_data(struct tls_connection *conn) 12828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 12838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 12848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *ad; 12858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: Check for possible Application Data"); 12868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ad = wpabuf_alloc((wpabuf_len(conn->pull_buf) + 500) * 3); 12878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ad == NULL) 12888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 12908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gnutls_record_recv(conn->session, wpabuf_mhead(ad), 12918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(ad)); 12928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: gnutls_record_recv: %d", res); 12938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 12941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 12958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%s)", __func__, (int) res, 12968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_strerror(res)); 12978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(ad); 12988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 12998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(ad, res); 13028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: Received %d bytes of Application Data", 13038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res); 13048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ad; 13058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 13068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_handshake(void *tls_ctx, 13098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 13108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 13118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 13128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 13138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 13148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_data; 13158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 13168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 13188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 13198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data && wpabuf_len(in_data) > 0) { 13218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf) { 13228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 13238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pull_buf", __func__, 13248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(conn->pull_buf)); 13258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->pull_buf); 13268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf = wpabuf_dup(in_data); 13288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf == NULL) 13298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 13308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 13318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = gnutls_handshake(conn->session); 13348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 1335ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_alert_description_t alert; 1336ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 13378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (ret) { 13388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case GNUTLS_E_AGAIN: 13398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->server && conn->established && 13408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf == NULL) { 13418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Need to return something to trigger 13428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * completion of EAP-TLS. */ 13438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf = wpabuf_alloc(0); 13448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 13468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case GNUTLS_E_FATAL_ALERT_RECEIVED: 1347ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt alert = gnutls_alert_get(conn->session); 13488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", 1349ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt __func__, gnutls_alert_get_name(alert)); 13508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts++; 1351ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (conn->global->event_cb != NULL) { 1352ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt union tls_event_data ev; 1353ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1354ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt os_memset(&ev, 0, sizeof(ev)); 1355ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.alert.is_local = 0; 1356ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.alert.type = gnutls_alert_get_name(alert); 1357ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt ev.alert.description = ev.alert.type; 1358ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt conn->global->event_cb(conn->global->cb_ctx, 1359ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt TLS_ALERT, &ev); 1360ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 13618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* continue */ 13628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 13638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " 13648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "-> %s", __func__, gnutls_strerror(ret)); 13658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 13668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 13688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t size; 13698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1370ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); 1371ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1372ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#if GNUTLS_VERSION_NUMBER >= 0x03010a 1373ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt { 1374ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt char *desc; 1375ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1376ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt desc = gnutls_session_get_desc(conn->session); 1377ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt if (desc) { 1378ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt wpa_printf(MSG_DEBUG, "GnuTLS: %s", desc); 1379ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt gnutls_free(desc); 1380ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt } 13818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1382ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt#endif /* GnuTLS 3.1.10 or newer */ 13838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->established = 1; 13858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->push_buf == NULL) { 13868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Need to return something to get final TLS ACK. */ 13878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf = wpabuf_alloc(0); 13888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 13908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_session_get_data(conn->session, NULL, &size); 13918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->session_data == NULL || 13928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data_size < size) { 13938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global->session_data); 13948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data = os_malloc(size); 13958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 13968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->session_data) { 13978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data_size = size; 13988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_session_get_data(conn->session, 13998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->session_data, 14008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &global->session_data_size); 14018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf && appl_data) 14048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = gnutls_get_appl_data(conn); 14058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data = conn->push_buf; 14088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf = NULL; 14098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_data; 14108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 14148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 14158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 14168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 14178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_connection_handshake(tls_ctx, conn, in_data, appl_data); 14198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 14238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 14248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 14258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 14278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 14288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gnutls_record_send(conn->session, wpabuf_head(in_data), 14308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_len(in_data)); 14318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 14328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "%s: Encryption failed: %s", 14338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, gnutls_strerror(res)); 14348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = conn->push_buf; 14388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->push_buf = NULL; 14398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 14408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 14448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 14458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 14468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ssize_t res; 14488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out; 14498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf) { 14518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " 14528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "pull_buf", __func__, 14538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(conn->pull_buf)); 14548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(conn->pull_buf); 14558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf = wpabuf_dup(in_data); 14578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->pull_buf == NULL) 14588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->pull_buf_offset = wpabuf_head(conn->pull_buf); 14608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 14628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Even though we try to disable TLS compression, it is possible that 14638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * this cannot be done with all TLS libraries. Add extra buffer space 14648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to handle the possibility of the decrypted data being longer than 14658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * input data. 14668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 14678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = wpabuf_alloc((wpabuf_len(in_data) + 500) * 3); 14688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) 14698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = gnutls_record_recv(conn->session, wpabuf_mhead(out), 14728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_size(out)); 14738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 14748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s - gnutls_record_recv failed: %d " 14758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%s)", __func__, (int) res, gnutls_strerror(res)); 14768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out); 14778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 14788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 14798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put(out, res); 14808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 14828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 14868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 14888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 14898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return gnutls_session_is_resumed(conn->session); 14908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 14938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 14948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 14958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 14968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 14978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 14988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 14998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1501d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtint tls_get_version(void *ssl_ctx, struct tls_connection *conn, 1502d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char *buf, size_t buflen) 1503d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1504d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt /* TODO */ 1505d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 1506d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1507d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1508d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 15098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 15108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 15118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 15138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf[0] = '\0'; 15148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 15198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 15208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gnutls_record_disable_padding(conn->session); 15228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 15238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 15278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 15288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 15298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO */ 15318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 15368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 15408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 15448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 15488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 15528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 15548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 15568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 15578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 15598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_session_ticket_cb(void *tls_ctx, 15608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 15618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_session_ticket_cb cb, void *ctx) 15628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 15638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 15648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1565ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1566ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt 1567ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidtint tls_get_library_version(char *buf, size_t buf_len) 1568ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt{ 1569ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt return os_snprintf(buf, buf_len, "GnuTLS build=%s run=%s", 1570ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt GNUTLS_VERSION, gnutls_check_version(NULL)); 1571ff787d557db719adea0fdf2679667500c65cf74dDmitry Shmidt} 1572d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1573d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1574d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data(struct tls_connection *conn, 1575d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct wpabuf *data) 1576d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1577d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1578d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1579d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1580d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_set_success_data_resumed(struct tls_connection *conn) 1581d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1582d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1583d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1584d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1585d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtconst struct wpabuf * 1586d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidttls_connection_get_success_data(struct tls_connection *conn) 1587d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1588d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return NULL; 1589d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1590d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1591d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 1592d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidtvoid tls_connection_remove_session(struct tls_connection *conn) 1593d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt{ 1594d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt} 1595