18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SSL/TLS interface functions for Microsoft Schannel 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2005-2009, 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/* 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FIX: Go through all SSPI functions and verify what needs to be freed 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FIX: session resumption 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: add support for server cert chain validation 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: add support for CA cert validation 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TODO: add support for EAP-TLS (client cert/key conf) 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <windows.h> 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <wincrypt.h> 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <schannel.h> 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SECURITY_WIN32 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <security.h> 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <sspi.h> 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "tls.h" 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_global { 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HMODULE hsecurity; 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt PSecurityFunctionTable sspi; 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt HCERTSTORE my_cert_store; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection { 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int established, start; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int failed, read_alerts, write_alerts; 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SCHANNEL_CRED schannel_cred; 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CredHandle creds; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CtxtHandle context; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 eap_tls_prf[128]; 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_tls_prf_set; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int schannel_load_lib(struct tls_global *global) 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt INIT_SECURITY_INTERFACE pInitSecurityInterface; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->hsecurity = LoadLibrary(TEXT("Secur32.dll")); 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->hsecurity == NULL) { 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not load Secur32.dll - 0x%x", 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned int) GetLastError()); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress( 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->hsecurity, "InitSecurityInterfaceA"); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pInitSecurityInterface == NULL) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not find " 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "InitSecurityInterfaceA from Secur32.dll", 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FreeLibrary(global->hsecurity); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->hsecurity = NULL; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi = pInitSecurityInterface(); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->sspi == NULL) { 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not read security " 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "interface - 0x%x", 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned int) GetLastError()); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FreeLibrary(global->hsecurity); 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->hsecurity = NULL; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid * tls_init(const struct tls_config *conf) 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global = os_zalloc(sizeof(*global)); 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global == NULL) 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (schannel_load_lib(global)) { 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return global; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_deinit(void *ssl_ctx) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = ssl_ctx; 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->my_cert_store) 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt CertCloseStore(global->my_cert_store, 0); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt FreeLibrary(global->hsecurity); 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(global); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_errors(void *ssl_ctx) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn = os_zalloc(sizeof(*conn)); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->start = 1; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(conn); 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn ? conn->established : 0; 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = ssl_ctx; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->eap_tls_prf_set = 0; 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->established = conn->failed = 0; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->read_alerts = conn->write_alerts = 0; 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->DeleteSecurityContext(&conn->context); 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* FIX: what else needs to be reseted? */ 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_params(void *tls_ctx, 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verify_peer) 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_keys *keys) 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Schannel does not export master secret or client/server random. */ 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *label, int server_random_first, 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *out, size_t out_len) 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Cannot get master_key from Schannel, but EapKeyBlock can be used to 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TTLS cannot use this, though, since they are using different 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * labels. The only option could be to implement TLSv1 completely here 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and just use Schannel or CryptoAPI for low-level crypto 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * functionality.. 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL || !conn->eap_tls_prf_set || server_random_first || 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strcmp(label, "client EAP encryption") != 0 || 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_len > sizeof(conn->eap_tls_prf)) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(out, conn->eap_tls_prf, out_len); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * tls_conn_hs_clienthello(struct tls_global *global, 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD sspi_flags, sspi_flags_out; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBufferDesc outbuf; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBuffer outbufs[1]; 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TimeStamp ts_expiry; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sspi_flags = ISC_REQ_REPLAY_DETECT | 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_CONFIDENTIALITY | 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_RET_EXTENDED_ERROR | 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_ALLOCATE_MEMORY | 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_MANUAL_CRED_VALIDATION; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Generating ClientHello", __func__); 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].pvBuffer = NULL; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].BufferType = SECBUFFER_TOKEN; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].cbBuffer = 0; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.cBuffers = 1; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.pBuffers = outbufs; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.ulVersion = SECBUFFER_VERSION; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->InitializeSecurityContextW( 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->InitializeSecurityContextA( 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != SEC_I_CONTINUE_NEEDED) { 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: InitializeSecurityContextA " 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "failed - 0x%x", 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned int) status); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - ClientHello", 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].pvBuffer, outbufs[0].cbBuffer); 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->start = 0; 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc_copy(outbufs[0].pvBuffer, 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].cbBuffer); 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SChannel: Failed to generate ClientHello"); 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef SECPKG_ATTR_EAP_KEY_BLOCK 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidttypedef struct _SecPkgContext_EapKeyBlock { 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE rgbKeys[128]; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt BYTE rgbIVs[64]; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock; 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* !SECPKG_ATTR_EAP_KEY_BLOCK */ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int tls_get_eap(struct tls_global *global, struct tls_connection *conn) 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecPkgContext_EapKeyBlock kb; 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Note: Windows NT and Windows Me/98/95 do not support getting 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EapKeyBlock */ 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->QueryContextAttributes( 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->context, SECPKG_ATTR_EAP_KEY_BLOCK, &kb); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != SEC_E_OK) { 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes(" 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "SECPKG_ATTR_EAP_KEY_BLOCK) failed (%d)", 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (int) status); 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbKeys", 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kb.rgbKeys, sizeof(kb.rgbKeys)); 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbIVs", 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kb.rgbIVs, sizeof(kb.rgbIVs)); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(conn->eap_tls_prf, kb.rgbKeys, sizeof(kb.rgbKeys)); 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->eap_tls_prf_set = 1; 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_handshake(void *tls_ctx, 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DWORD sspi_flags, sspi_flags_out; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBufferDesc inbuf, outbuf; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBuffer inbufs[2], outbufs[1]; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TimeStamp ts_expiry; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out_buf = NULL; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = NULL; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn->start) 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_conn_hs_clienthello(global, conn); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SChannel: %d bytes handshake data to process", 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) wpabuf_len(in_data)); 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sspi_flags = ISC_REQ_REPLAY_DETECT | 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_CONFIDENTIALITY | 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_RET_EXTENDED_ERROR | 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_ALLOCATE_MEMORY | 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ISC_REQ_MANUAL_CRED_VALIDATION; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Input buffer for Schannel */ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[0].pvBuffer = (u8 *) wpabuf_head(in_data); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[0].cbBuffer = wpabuf_len(in_data); 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[0].BufferType = SECBUFFER_TOKEN; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Place for leftover data from Schannel */ 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].pvBuffer = NULL; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].cbBuffer = 0; 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].BufferType = SECBUFFER_EMPTY; 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbuf.cBuffers = 2; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbuf.pBuffers = inbufs; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbuf.ulVersion = SECBUFFER_VERSION; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Output buffer for Schannel */ 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].pvBuffer = NULL; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].cbBuffer = 0; 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].BufferType = SECBUFFER_TOKEN; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.cBuffers = 1; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.pBuffers = outbufs; 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbuf.ulVersion = SECBUFFER_VERSION; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->InitializeSecurityContextW( 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->creds, &conn->context, NULL, sspi_flags, 0, 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->InitializeSecurityContextA( 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->creds, &conn->context, NULL, sspi_flags, 0, 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: InitializeSecurityContext -> " 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d inlen[0]=%d intype[0]=%d inlen[1]=%d " 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "intype[1]=%d outlen[0]=%d", 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) status, (int) inbufs[0].cbBuffer, 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) inbufs[0].BufferType, (int) inbufs[1].cbBuffer, 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) inbufs[1].BufferType, 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) outbufs[0].cbBuffer); 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED || 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (FAILED(status) && (sspi_flags_out & ISC_RET_EXTENDED_ERROR))) { 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - output", 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].pvBuffer, outbufs[0].cbBuffer); 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_buf = wpabuf_alloc_copy(outbufs[0].pvBuffer, 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].cbBuffer); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[0].pvBuffer = NULL; 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_buf == NULL) 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_INCOMPLETE_MESSAGE: 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INCOMPLETE_MESSAGE"); 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_I_CONTINUE_NEEDED: 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_I_CONTINUE_NEEDED"); 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_OK: 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: verify server certificate chain */ 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_OK - Handshake " 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "completed successfully"); 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->established = 1; 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_get_eap(global, conn); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Need to return something to get final TLS ACK. */ 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out_buf == NULL) 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_buf = wpabuf_alloc(0); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - Encrypted " 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "application data", 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].pvBuffer, inbufs[1].cbBuffer); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data) { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *appl_data = wpabuf_alloc_copy( 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[1].pvBuffer, 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt outbufs[1].cbBuffer); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].pvBuffer = NULL; 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_I_INCOMPLETE_CREDENTIALS: 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Schannel: SEC_I_INCOMPLETE_CREDENTIALS"); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_WRONG_PRINCIPAL: 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_WRONG_PRINCIPAL"); 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_INTERNAL_ERROR: 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INTERNAL_ERROR"); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (FAILED(status)) { 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: Handshake failed " 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(out_buf=%p)", out_buf); 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->failed++; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->DeleteSecurityContext(&conn->context); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_buf; 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: Can this happen? What to do with this data? */ 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - Leftover data", 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].pvBuffer, inbufs[1].cbBuffer); 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt inbufs[1].pvBuffer = NULL; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out_buf; 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_server_handshake(void *tls_ctx, 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **appl_data) 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_encrypt(void *tls_ctx, 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBufferDesc buf; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBuffer bufs[4]; 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecPkgContext_StreamSizes sizes; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out; 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->QueryContextAttributes(&conn->context, 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECPKG_ATTR_STREAM_SIZES, 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &sizes); 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != SEC_E_OK) { 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes failed", 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Stream sizes: header=%u trailer=%u", 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) sizes.cbHeader, 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned int) sizes.cbTrailer); 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = wpabuf_alloc(sizes.cbHeader + wpabuf_len(in_data) + 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sizes.cbTrailer); 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&bufs, 0, sizeof(bufs)); 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].pvBuffer = wpabuf_put(out, sizes.cbHeader); 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].cbBuffer = sizes.cbHeader; 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].BufferType = SECBUFFER_STREAM_HEADER; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[1].pvBuffer = wpabuf_put(out, 0); 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(out, in_data); 5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[1].cbBuffer = wpabuf_len(in_data); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[1].BufferType = SECBUFFER_DATA; 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].pvBuffer = wpabuf_put(out, sizes.cbTrailer); 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].cbBuffer = sizes.cbTrailer; 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].BufferType = SECBUFFER_STREAM_TRAILER; 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.ulVersion = SECBUFFER_VERSION; 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.cBuffers = 3; 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.pBuffers = bufs; 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->EncryptMessage(&conn->context, 0, &buf, 0); 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage -> " 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len[2]=%d type[2]=%d", 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) status, 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[2].cbBuffer, (int) bufs[2].BufferType); 5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage pointers: " 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "out_data=%p bufs %p %p %p", 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(out), bufs[0].pvBuffer, bufs[1].pvBuffer, 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].pvBuffer); 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 3; i++) { 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bufs[i].pvBuffer && bufs[i].BufferType != SECBUFFER_EMPTY) 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel: bufs", 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[i].pvBuffer, bufs[i].cbBuffer); 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status == SEC_E_OK) { 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "Schannel: Encrypted data " 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "from EncryptMessage", out); 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (int) status); 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(out); 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * tls_connection_decrypt(void *tls_ctx, 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn, 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBufferDesc buf; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SecBuffer bufs[4]; 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int i; 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *out, *tmp; 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf(MSG_MSGDUMP, 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Schannel: Encrypted data to DecryptMessage", in_data); 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&bufs, 0, sizeof(bufs)); 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tmp = wpabuf_dup(in_data); 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tmp == NULL) 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].pvBuffer = wpabuf_mhead(tmp); 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].cbBuffer = wpabuf_len(in_data); 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[0].BufferType = SECBUFFER_DATA; 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[1].BufferType = SECBUFFER_EMPTY; 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].BufferType = SECBUFFER_EMPTY; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[3].BufferType = SECBUFFER_EMPTY; 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.ulVersion = SECBUFFER_VERSION; 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.cBuffers = 4; 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf.pBuffers = bufs; 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->DecryptMessage(&conn->context, &buf, 0, 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL); 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage -> " 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "len[2]=%d type[2]=%d len[3]=%d type[3]=%d", 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) status, 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[2].cbBuffer, (int) bufs[2].BufferType, 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) bufs[3].cbBuffer, (int) bufs[3].BufferType); 5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage pointers: " 5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "out_data=%p bufs %p %p %p %p", 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head(tmp), bufs[0].pvBuffer, bufs[1].pvBuffer, 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[2].pvBuffer, bufs[3].pvBuffer); 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (status) { 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_INCOMPLETE_MESSAGE: 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_INCOMPLETE_MESSAGE", 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__); 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case SEC_E_OK: 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < 4; i++) { 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (bufs[i].BufferType == SECBUFFER_DATA) 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (i == 4) { 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: No output data from " 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DecryptMessage", __func__); 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Decrypted data from " 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "DecryptMessage", 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt bufs[i].pvBuffer, bufs[i].cbBuffer); 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = wpabuf_alloc_copy(bufs[i].pvBuffer, bufs[i].cbBuffer); 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (int) status); 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(tmp); 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *ciphers) 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen) 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection *conn) 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ext_type, const u8 *data, 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len) 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->failed; 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->read_alerts; 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return conn->write_alerts; 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct tls_connection_params *params) 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_global *global = tls_ctx; 6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ALG_ID algs[1]; 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt SECURITY_STATUS status; 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt TimeStamp ts_expiry; 6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (conn == NULL) 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (global->my_cert_store == NULL && 6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) == 6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL) { 6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x", 6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt __func__, (unsigned int) GetLastError()); 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred)); 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1; 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt algs[0] = CALG_RSA_KEYX; 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->schannel_cred.cSupportedAlgs = 1; 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->schannel_cred.palgSupportedAlgs = algs; 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef UNICODE 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->AcquireCredentialsHandleW( 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* UNICODE */ 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt status = global->sspi->AcquireCredentialsHandleA( 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* UNICODE */ 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (status != SEC_E_OK) { 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - " 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "0x%x", __func__, (unsigned int) status); 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtunsigned int tls_capabilities(void *tls_ctx) 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 733