1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant / SSL/TLS interface functions for Microsoft Schannel 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2005, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * FIX: Go through all SSPI functions and verify what needs to be freed 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * FIX: session resumption 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: add support for server cert chain validation 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: add support for CA cert validation 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * TODO: add support for EAP-TLS (client cert/key conf) 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <windows.h> 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <wincrypt.h> 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <schannel.h> 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define SECURITY_WIN32 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <security.h> 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <sspi.h> 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "tls.h" 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct tls_global { 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HMODULE hsecurity; 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt PSecurityFunctionTable sspi; 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HCERTSTORE my_cert_store; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct tls_connection { 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int established, start; 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int failed, read_alerts, write_alerts; 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SCHANNEL_CRED schannel_cred; 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CredHandle creds; 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CtxtHandle context; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 eap_tls_prf[128]; 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int eap_tls_prf_set; 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int schannel_load_lib(struct tls_global *global) 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt INIT_SECURITY_INTERFACE pInitSecurityInterface; 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->hsecurity = LoadLibrary(TEXT("Secur32.dll")); 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global->hsecurity == NULL) { 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not load Secur32.dll - 0x%x", 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (unsigned int) GetLastError()); 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress( 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->hsecurity, "InitSecurityInterfaceA"); 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pInitSecurityInterface == NULL) { 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not find " 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "InitSecurityInterfaceA from Secur32.dll", 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__); 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FreeLibrary(global->hsecurity); 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->hsecurity = NULL; 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi = pInitSecurityInterface(); 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global->sspi == NULL) { 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "%s: Could not read security " 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface - 0x%x", 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (unsigned int) GetLastError()); 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FreeLibrary(global->hsecurity); 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->hsecurity = NULL; 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid * tls_init(const struct tls_config *conf) 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global; 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global = os_zalloc(sizeof(*global)); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global == NULL) 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (schannel_load_lib(global)) { 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(global); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return global; 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid tls_deinit(void *ssl_ctx) 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = ssl_ctx; 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global->my_cert_store) 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CertCloseStore(global->my_cert_store, 0); 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt FreeLibrary(global->hsecurity); 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(global); 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_get_errors(void *ssl_ctx) 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct tls_connection * tls_connection_init(void *ssl_ctx) 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn; 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn = os_zalloc(sizeof(*conn)); 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->start = 1; 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return conn; 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn) 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(conn); 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_established(void *ssl_ctx, struct tls_connection *conn) 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return conn ? conn->established : 0; 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn) 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = ssl_ctx; 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->eap_tls_prf_set = 0; 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->established = conn->failed = 0; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->read_alerts = conn->write_alerts = 0; 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->DeleteSecurityContext(&conn->context); 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* FIX: what else needs to be reseted? */ 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_global_set_params(void *tls_ctx, 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct tls_connection_params *params) 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_global_set_verify(void *ssl_ctx, int check_crl) 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn, 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int verify_peer) 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn, 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_keys *keys) 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Schannel does not export master secret or client/server random. */ 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_prf(void *tls_ctx, struct tls_connection *conn, 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *label, int server_random_first, 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *out, size_t out_len) 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Cannot get master_key from Schannel, but EapKeyBlock can be used to 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EAP-TTLS cannot use this, though, since they are using different 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * labels. The only option could be to implement TLSv1 completely here 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * and just use Schannel or CryptoAPI for low-level crypto 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * functionality.. 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL || !conn->eap_tls_prf_set || server_random_first || 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_strcmp(label, "client EAP encryption") != 0 || 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out_len > sizeof(conn->eap_tls_prf)) 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(out, conn->eap_tls_prf, out_len); 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic u8 * tls_conn_hs_clienthello(struct tls_global *global, 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn, 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t *out_len) 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD sspi_flags, sspi_flags_out; 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBufferDesc outbuf; 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBuffer outbufs[1]; 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TimeStamp ts_expiry; 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sspi_flags = ISC_REQ_REPLAY_DETECT | 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_CONFIDENTIALITY | 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_RET_EXTENDED_ERROR | 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_ALLOCATE_MEMORY | 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_MANUAL_CRED_VALIDATION; 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Generating ClientHello", __func__); 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].pvBuffer = NULL; 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].BufferType = SECBUFFER_TOKEN; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].cbBuffer = 0; 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.cBuffers = 1; 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.pBuffers = outbufs; 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.ulVersion = SECBUFFER_VERSION; 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->InitializeSecurityContextW( 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* UNICODE */ 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->InitializeSecurityContextA( 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->creds, NULL, NULL /* server name */, sspi_flags, 0, 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_NATIVE_DREP, NULL, 0, &conn->context, 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* UNICODE */ 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status != SEC_I_CONTINUE_NEEDED) { 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "%s: InitializeSecurityContextA " 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "failed - 0x%x", 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (unsigned int) status); 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *buf; 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - ClientHello", 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].pvBuffer, outbufs[0].cbBuffer); 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->start = 0; 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *out_len = outbufs[0].cbBuffer; 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf = os_malloc(*out_len); 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (buf == NULL) 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(buf, outbufs[0].pvBuffer, *out_len); 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return buf; 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "SChannel: Failed to generate ClientHello"); 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef SECPKG_ATTR_EAP_KEY_BLOCK 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidttypedef struct _SecPkgContext_EapKeyBlock { 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BYTE rgbKeys[128]; 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BYTE rgbIVs[64]; 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock; 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* !SECPKG_ATTR_EAP_KEY_BLOCK */ 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int tls_get_eap(struct tls_global *global, struct tls_connection *conn) 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecPkgContext_EapKeyBlock kb; 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Note: Windows NT and Windows Me/98/95 do not support getting 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * EapKeyBlock */ 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->QueryContextAttributes( 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->context, SECPKG_ATTR_EAP_KEY_BLOCK, &kb); 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status != SEC_E_OK) { 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes(" 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "SECPKG_ATTR_EAP_KEY_BLOCK) failed (%d)", 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (int) status); 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbKeys", 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kb.rgbKeys, sizeof(kb.rgbKeys)); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbIVs", 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt kb.rgbIVs, sizeof(kb.rgbIVs)); 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(conn->eap_tls_prf, kb.rgbKeys, sizeof(kb.rgbKeys)); 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->eap_tls_prf_set = 1; 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtu8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *in_data, size_t in_len, 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t *out_len, u8 **appl_data, 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t *appl_data_len) 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = ssl_ctx; 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD sspi_flags, sspi_flags_out; 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBufferDesc inbuf, outbuf; 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBuffer inbufs[2], outbufs[1]; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TimeStamp ts_expiry; 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *out_buf = NULL; 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (appl_data) 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *appl_data = NULL; 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn->start) { 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return tls_conn_hs_clienthello(global, conn, out_len); 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "SChannel: %d bytes handshake data to process", 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt in_len); 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt sspi_flags = ISC_REQ_REPLAY_DETECT | 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_CONFIDENTIALITY | 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_RET_EXTENDED_ERROR | 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_ALLOCATE_MEMORY | 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ISC_REQ_MANUAL_CRED_VALIDATION; 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Input buffer for Schannel */ 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[0].pvBuffer = (u8 *) in_data; 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[0].cbBuffer = in_len; 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[0].BufferType = SECBUFFER_TOKEN; 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Place for leftover data from Schannel */ 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].pvBuffer = NULL; 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].cbBuffer = 0; 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].BufferType = SECBUFFER_EMPTY; 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbuf.cBuffers = 2; 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbuf.pBuffers = inbufs; 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbuf.ulVersion = SECBUFFER_VERSION; 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Output buffer for Schannel */ 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].pvBuffer = NULL; 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].cbBuffer = 0; 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].BufferType = SECBUFFER_TOKEN; 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.cBuffers = 1; 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.pBuffers = outbufs; 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbuf.ulVersion = SECBUFFER_VERSION; 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->InitializeSecurityContextW( 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->creds, &conn->context, NULL, sspi_flags, 0, 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* UNICODE */ 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->InitializeSecurityContextA( 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->creds, &conn->context, NULL, sspi_flags, 0, 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_NATIVE_DREP, &inbuf, 0, NULL, 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &outbuf, &sspi_flags_out, &ts_expiry); 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* UNICODE */ 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: InitializeSecurityContext -> " 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "status=%d inlen[0]=%d intype[0]=%d inlen[1]=%d " 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "intype[1]=%d outlen[0]=%d", 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) status, (int) inbufs[0].cbBuffer, 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) inbufs[0].BufferType, (int) inbufs[1].cbBuffer, 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) inbufs[1].BufferType, 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) outbufs[0].cbBuffer); 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED || 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (FAILED(status) && (sspi_flags_out & ISC_RET_EXTENDED_ERROR))) { 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) { 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - output", 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].pvBuffer, outbufs[0].cbBuffer); 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *out_len = outbufs[0].cbBuffer; 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out_buf = os_malloc(*out_len); 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (out_buf) 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(out_buf, outbufs[0].pvBuffer, 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *out_len); 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->FreeContextBuffer(outbufs[0].pvBuffer); 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[0].pvBuffer = NULL; 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (out_buf == NULL) 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (status) { 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_INCOMPLETE_MESSAGE: 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INCOMPLETE_MESSAGE"); 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_I_CONTINUE_NEEDED: 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_I_CONTINUE_NEEDED"); 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_OK: 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: verify server certificate chain */ 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_OK - Handshake " 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "completed successfully"); 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->established = 1; 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tls_get_eap(global, conn); 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Need to return something to get final TLS ACK. */ 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (out_buf == NULL) 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out_buf = os_malloc(1); 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - Encrypted " 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "application data", 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].pvBuffer, inbufs[1].cbBuffer); 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (appl_data) { 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *appl_data_len = outbufs[1].cbBuffer; 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt appl_data = os_malloc(*appl_data_len); 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (appl_data) 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(appl_data, 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt outbufs[1].pvBuffer, 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *appl_data_len); 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].pvBuffer = NULL; 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_I_INCOMPLETE_CREDENTIALS: 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Schannel: SEC_I_INCOMPLETE_CREDENTIALS"); 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_WRONG_PRINCIPAL: 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_WRONG_PRINCIPAL"); 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_INTERNAL_ERROR: 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INTERNAL_ERROR"); 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(status)) { 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Schannel: Handshake failed " 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "(out_buf=%p)", out_buf); 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->failed++; 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->DeleteSecurityContext(&conn->context); 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return out_buf; 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (inbufs[1].BufferType == SECBUFFER_EXTRA) { 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* TODO: Can this happen? What to do with this data? */ 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel - Leftover data", 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].pvBuffer, inbufs[1].cbBuffer); 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt global->sspi->FreeContextBuffer(inbufs[1].pvBuffer); 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt inbufs[1].pvBuffer = NULL; 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return out_buf; 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtu8 * tls_connection_server_handshake(void *ssl_ctx, 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn, 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *in_data, size_t in_len, 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t *out_len) 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_encrypt(void *ssl_ctx, struct tls_connection *conn, 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *in_data, size_t in_len, 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *out_data, size_t out_len) 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = ssl_ctx; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBufferDesc buf; 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBuffer bufs[4]; 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecPkgContext_StreamSizes sizes; 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t total_len; 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->QueryContextAttributes(&conn->context, 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECPKG_ATTR_STREAM_SIZES, 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &sizes); 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status != SEC_E_OK) { 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes failed", 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__); 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Stream sizes: header=%u trailer=%u", 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned int) sizes.cbHeader, 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned int) sizes.cbTrailer); 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt total_len = sizes.cbHeader + in_len + sizes.cbTrailer; 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (out_len < total_len) { 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: too short out_data (out_len=%lu " 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "in_len=%lu total_len=%lu)", __func__, 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) out_len, (unsigned long) in_len, 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) total_len); 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&bufs, 0, sizeof(bufs)); 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].pvBuffer = out_data; 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].cbBuffer = sizes.cbHeader; 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].BufferType = SECBUFFER_STREAM_HEADER; 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(out_data + sizes.cbHeader, in_data, in_len); 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[1].pvBuffer = out_data + sizes.cbHeader; 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[1].cbBuffer = in_len; 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[1].BufferType = SECBUFFER_DATA; 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].pvBuffer = out_data + sizes.cbHeader + in_len; 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].cbBuffer = sizes.cbTrailer; 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].BufferType = SECBUFFER_STREAM_TRAILER; 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.ulVersion = SECBUFFER_VERSION; 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.cBuffers = 3; 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.pBuffers = bufs; 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->EncryptMessage(&conn->context, 0, &buf, 0); 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage -> " 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "len[2]=%d type[2]=%d", 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) status, 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[2].cbBuffer, (int) bufs[2].BufferType); 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage pointers: " 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "out_data=%p bufs %p %p %p", 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out_data, bufs[0].pvBuffer, bufs[1].pvBuffer, 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].pvBuffer); 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 3; i++) { 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bufs[i].pvBuffer && bufs[i].BufferType != SECBUFFER_EMPTY) 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt { 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "SChannel: bufs", 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[i].pvBuffer, bufs[i].cbBuffer); 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status == SEC_E_OK) { 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Encrypted data from " 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "EncryptMessage", out_data, total_len); 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return total_len; 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (int) status); 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *in_data, size_t in_len, 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *out_data, size_t out_len) 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = ssl_ctx; 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBufferDesc buf; 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SecBuffer bufs[4]; 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (out_len < in_len) { 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: out_len=%lu < in_len=%lu", __func__, 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (unsigned long) out_len, (unsigned long) in_len); 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "Schannel: Encrypted data to DecryptMessage", 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt in_data, in_len); 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&bufs, 0, sizeof(bufs)); 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(out_data, in_data, in_len); 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].pvBuffer = out_data; 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].cbBuffer = in_len; 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[0].BufferType = SECBUFFER_DATA; 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[1].BufferType = SECBUFFER_EMPTY; 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].BufferType = SECBUFFER_EMPTY; 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[3].BufferType = SECBUFFER_EMPTY; 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.ulVersion = SECBUFFER_VERSION; 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.cBuffers = 4; 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt buf.pBuffers = bufs; 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->DecryptMessage(&conn->context, &buf, 0, 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL); 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage -> " 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d " 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "len[2]=%d type[2]=%d len[3]=%d type[3]=%d", 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) status, 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[0].cbBuffer, (int) bufs[0].BufferType, 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[1].cbBuffer, (int) bufs[1].BufferType, 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[2].cbBuffer, (int) bufs[2].BufferType, 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) bufs[3].cbBuffer, (int) bufs[3].BufferType); 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage pointers: " 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "out_data=%p bufs %p %p %p %p", 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt out_data, bufs[0].pvBuffer, bufs[1].pvBuffer, 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[2].pvBuffer, bufs[3].pvBuffer); 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (status) { 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_INCOMPLETE_MESSAGE: 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_INCOMPLETE_MESSAGE", 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__); 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case SEC_E_OK: 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__); 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < 4; i++) { 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bufs[i].BufferType == SECBUFFER_DATA) 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (i == 4) { 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: No output data from " 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "DecryptMessage", __func__); 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Decrypted data from " 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "DecryptMessage", 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bufs[i].pvBuffer, bufs[i].cbBuffer); 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (bufs[i].cbBuffer > out_len) { 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Too long output data", 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__); 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memmove(out_data, bufs[i].pvBuffer, bufs[i].cbBuffer); 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return bufs[i].cbBuffer; 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: Failed - status=%d", 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (int) status); 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn) 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn, 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *ciphers) 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_get_cipher(void *ssl_ctx, struct tls_connection *conn, 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *buf, size_t buflen) 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_enable_workaround(void *ssl_ctx, 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn) 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn, 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ext_type, const u8 *data, 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t data_len) 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn) 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return conn->failed; 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn) 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return conn->read_alerts; 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn) 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return conn->write_alerts; 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct tls_connection_params *params) 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_global *global = tls_ctx; 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ALG_ID algs[1]; 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SECURITY_STATUS status; 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt TimeStamp ts_expiry; 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (conn == NULL) 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (global->my_cert_store == NULL && 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) == 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL) { 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x", 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt __func__, (unsigned int) GetLastError()); 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred)); 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1; 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt algs[0] = CALG_RSA_KEYX; 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->schannel_cred.cSupportedAlgs = 1; 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->schannel_cred.palgSupportedAlgs = algs; 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef UNICODE 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->AcquireCredentialsHandleW( 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#else /* UNICODE */ 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt status = global->sspi->AcquireCredentialsHandleA( 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* UNICODE */ 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (status != SEC_E_OK) { 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - " 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "0x%x", __func__, (unsigned int) status); 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtunsigned int tls_capabilities(void *tls_ctx) 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_set_ia(void *tls_ctx, struct tls_connection *conn, 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int tls_ia) 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_ia_send_phase_finished(void *tls_ctx, 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn, 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int final, 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u8 *out_data, size_t out_len) 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_ia_final_phase_finished(void *tls_ctx, 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn) 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint tls_connection_ia_permute_inner_secret(void *tls_ctx, 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct tls_connection *conn, 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const u8 *key, size_t key_len) 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 790