/*
 * SSL/TLS interface functions for Microsoft Schannel
 * Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

/*
 * FIX: Go through all SSPI functions and verify what needs to be freed
 * FIX: session resumption
 * TODO: add support for server cert chain validation
 * TODO: add support for CA cert validation
 * TODO: add support for EAP-TLS (client cert/key conf)
 */

#include "includes.h"
#include <windows.h>
#include <wincrypt.h>
#include <schannel.h>
#define SECURITY_WIN32
#include <security.h>
#include <sspi.h>

#include "common.h"
#include "tls.h"


struct tls_global {
	HMODULE hsecurity;
	PSecurityFunctionTable sspi;
	HCERTSTORE my_cert_store;
};

struct tls_connection {
	int established, start;
	int failed, read_alerts, write_alerts;

	SCHANNEL_CRED schannel_cred;
	CredHandle creds;
	CtxtHandle context;

	u8 eap_tls_prf[128];
	int eap_tls_prf_set;
};


static int schannel_load_lib(struct tls_global *global)
{
	INIT_SECURITY_INTERFACE pInitSecurityInterface;

	global->hsecurity = LoadLibrary(TEXT("Secur32.dll"));
	if (global->hsecurity == NULL) {
		wpa_printf(MSG_ERROR, "%s: Could not load Secur32.dll - 0x%x",
			   __func__, (unsigned int) GetLastError());
		return -1;
	}

	pInitSecurityInterface = (INIT_SECURITY_INTERFACE) GetProcAddress(
		global->hsecurity, "InitSecurityInterfaceA");
	if (pInitSecurityInterface == NULL) {
		wpa_printf(MSG_ERROR, "%s: Could not find "
			   "InitSecurityInterfaceA from Secur32.dll",
			   __func__);
		FreeLibrary(global->hsecurity);
		global->hsecurity = NULL;
		return -1;
	}

	global->sspi = pInitSecurityInterface();
	if (global->sspi == NULL) {
		wpa_printf(MSG_ERROR, "%s: Could not read security "
			   "interface - 0x%x",
			   __func__, (unsigned int) GetLastError());
		FreeLibrary(global->hsecurity);
		global->hsecurity = NULL;
		return -1;
	}

	return 0;
}


void * tls_init(const struct tls_config *conf)
{
	struct tls_global *global;

	global = os_zalloc(sizeof(*global));
	if (global == NULL)
		return NULL;
	if (schannel_load_lib(global)) {
		os_free(global);
		return NULL;
	}
	return global;
}


void tls_deinit(void *ssl_ctx)
{
	struct tls_global *global = ssl_ctx;

	if (global->my_cert_store)
		CertCloseStore(global->my_cert_store, 0);
	FreeLibrary(global->hsecurity);
	os_free(global);
}


int tls_get_errors(void *ssl_ctx)
{
	return 0;
}


struct tls_connection * tls_connection_init(void *ssl_ctx)
{
	struct tls_connection *conn;

	conn = os_zalloc(sizeof(*conn));
	if (conn == NULL)
		return NULL;
	conn->start = 1;

	return conn;
}


void tls_connection_deinit(void *ssl_ctx, struct tls_connection *conn)
{
	if (conn == NULL)
		return;

	os_free(conn);
}


int tls_connection_established(void *ssl_ctx, struct tls_connection *conn)
{
	return conn ? conn->established : 0;
}


int tls_connection_shutdown(void *ssl_ctx, struct tls_connection *conn)
{
	struct tls_global *global = ssl_ctx;
	if (conn == NULL)
		return -1;

	conn->eap_tls_prf_set = 0;
	conn->established = conn->failed = 0;
	conn->read_alerts = conn->write_alerts = 0;
	global->sspi->DeleteSecurityContext(&conn->context);
	/* FIX: what else needs to be reseted? */

	return 0;
}


int tls_global_set_params(void *tls_ctx,
			  const struct tls_connection_params *params)
{
	return -1;
}


int tls_global_set_verify(void *ssl_ctx, int check_crl)
{
	return -1;
}


int tls_connection_set_verify(void *ssl_ctx, struct tls_connection *conn,
			      int verify_peer)
{
	return -1;
}


int tls_connection_get_keys(void *ssl_ctx, struct tls_connection *conn,
			    struct tls_keys *keys)
{
	/* Schannel does not export master secret or client/server random. */
	return -1;
}


int tls_connection_prf(void *tls_ctx, struct tls_connection *conn,
		       const char *label, int server_random_first,
		       u8 *out, size_t out_len)
{
	/*
	 * Cannot get master_key from Schannel, but EapKeyBlock can be used to
	 * generate session keys for EAP-TLS and EAP-PEAPv0. EAP-PEAPv2 and
	 * EAP-TTLS cannot use this, though, since they are using different
	 * labels. The only option could be to implement TLSv1 completely here
	 * and just use Schannel or CryptoAPI for low-level crypto
	 * functionality..
	 */

	if (conn == NULL || !conn->eap_tls_prf_set || server_random_first ||
	    os_strcmp(label, "client EAP encryption") != 0 ||
	    out_len > sizeof(conn->eap_tls_prf))
		return -1;

	os_memcpy(out, conn->eap_tls_prf, out_len);

	return 0;
}


static struct wpabuf * tls_conn_hs_clienthello(struct tls_global *global,
					       struct tls_connection *conn)
{
	DWORD sspi_flags, sspi_flags_out;
	SecBufferDesc outbuf;
	SecBuffer outbufs[1];
	SECURITY_STATUS status;
	TimeStamp ts_expiry;

	sspi_flags = ISC_REQ_REPLAY_DETECT |
		ISC_REQ_CONFIDENTIALITY |
		ISC_RET_EXTENDED_ERROR |
		ISC_REQ_ALLOCATE_MEMORY |
		ISC_REQ_MANUAL_CRED_VALIDATION;

	wpa_printf(MSG_DEBUG, "%s: Generating ClientHello", __func__);

	outbufs[0].pvBuffer = NULL;
	outbufs[0].BufferType = SECBUFFER_TOKEN;
	outbufs[0].cbBuffer = 0;

	outbuf.cBuffers = 1;
	outbuf.pBuffers = outbufs;
	outbuf.ulVersion = SECBUFFER_VERSION;

#ifdef UNICODE
	status = global->sspi->InitializeSecurityContextW(
		&conn->creds, NULL, NULL /* server name */, sspi_flags, 0,
		SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
		&outbuf, &sspi_flags_out, &ts_expiry);
#else /* UNICODE */
	status = global->sspi->InitializeSecurityContextA(
		&conn->creds, NULL, NULL /* server name */, sspi_flags, 0,
		SECURITY_NATIVE_DREP, NULL, 0, &conn->context,
		&outbuf, &sspi_flags_out, &ts_expiry);
#endif /* UNICODE */
	if (status != SEC_I_CONTINUE_NEEDED) {
		wpa_printf(MSG_ERROR, "%s: InitializeSecurityContextA "
			   "failed - 0x%x",
			   __func__, (unsigned int) status);
		return NULL;
	}

	if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) {
		struct wpabuf *buf;
		wpa_hexdump(MSG_MSGDUMP, "SChannel - ClientHello",
			    outbufs[0].pvBuffer, outbufs[0].cbBuffer);
		conn->start = 0;
		buf = wpabuf_alloc_copy(outbufs[0].pvBuffer,
					outbufs[0].cbBuffer);
		if (buf == NULL)
			return NULL;
		global->sspi->FreeContextBuffer(outbufs[0].pvBuffer);
		return buf;
	}

	wpa_printf(MSG_ERROR, "SChannel: Failed to generate ClientHello");

	return NULL;
}


#ifndef SECPKG_ATTR_EAP_KEY_BLOCK
#define SECPKG_ATTR_EAP_KEY_BLOCK 0x5b

typedef struct _SecPkgContext_EapKeyBlock {
	BYTE rgbKeys[128];
	BYTE rgbIVs[64];
} SecPkgContext_EapKeyBlock, *PSecPkgContext_EapKeyBlock;
#endif /* !SECPKG_ATTR_EAP_KEY_BLOCK */

static int tls_get_eap(struct tls_global *global, struct tls_connection *conn)
{
	SECURITY_STATUS status;
	SecPkgContext_EapKeyBlock kb;

	/* Note: Windows NT and Windows Me/98/95 do not support getting
	 * EapKeyBlock */

	status = global->sspi->QueryContextAttributes(
		&conn->context, SECPKG_ATTR_EAP_KEY_BLOCK, &kb);
	if (status != SEC_E_OK) {
		wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes("
			   "SECPKG_ATTR_EAP_KEY_BLOCK) failed (%d)",
			   __func__, (int) status);
		return -1;
	}

	wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbKeys",
			kb.rgbKeys, sizeof(kb.rgbKeys));
	wpa_hexdump_key(MSG_MSGDUMP, "Schannel - EapKeyBlock - rgbIVs",
			kb.rgbIVs, sizeof(kb.rgbIVs));

	os_memcpy(conn->eap_tls_prf, kb.rgbKeys, sizeof(kb.rgbKeys));
	conn->eap_tls_prf_set = 1;
	return 0;
}


struct wpabuf * tls_connection_handshake(void *tls_ctx,
					 struct tls_connection *conn,
					 const struct wpabuf *in_data,
					 struct wpabuf **appl_data)
{
	struct tls_global *global = tls_ctx;
	DWORD sspi_flags, sspi_flags_out;
	SecBufferDesc inbuf, outbuf;
	SecBuffer inbufs[2], outbufs[1];
	SECURITY_STATUS status;
	TimeStamp ts_expiry;
	struct wpabuf *out_buf = NULL;

	if (appl_data)
		*appl_data = NULL;

	if (conn->start)
		return tls_conn_hs_clienthello(global, conn);

	wpa_printf(MSG_DEBUG, "SChannel: %d bytes handshake data to process",
		   (int) wpabuf_len(in_data));

	sspi_flags = ISC_REQ_REPLAY_DETECT |
		ISC_REQ_CONFIDENTIALITY |
		ISC_RET_EXTENDED_ERROR |
		ISC_REQ_ALLOCATE_MEMORY |
		ISC_REQ_MANUAL_CRED_VALIDATION;

	/* Input buffer for Schannel */
	inbufs[0].pvBuffer = (u8 *) wpabuf_head(in_data);
	inbufs[0].cbBuffer = wpabuf_len(in_data);
	inbufs[0].BufferType = SECBUFFER_TOKEN;

	/* Place for leftover data from Schannel */
	inbufs[1].pvBuffer = NULL;
	inbufs[1].cbBuffer = 0;
	inbufs[1].BufferType = SECBUFFER_EMPTY;

	inbuf.cBuffers = 2;
	inbuf.pBuffers = inbufs;
	inbuf.ulVersion = SECBUFFER_VERSION;

	/* Output buffer for Schannel */
	outbufs[0].pvBuffer = NULL;
	outbufs[0].cbBuffer = 0;
	outbufs[0].BufferType = SECBUFFER_TOKEN;

	outbuf.cBuffers = 1;
	outbuf.pBuffers = outbufs;
	outbuf.ulVersion = SECBUFFER_VERSION;

#ifdef UNICODE
	status = global->sspi->InitializeSecurityContextW(
		&conn->creds, &conn->context, NULL, sspi_flags, 0,
		SECURITY_NATIVE_DREP, &inbuf, 0, NULL,
		&outbuf, &sspi_flags_out, &ts_expiry);
#else /* UNICODE */
	status = global->sspi->InitializeSecurityContextA(
		&conn->creds, &conn->context, NULL, sspi_flags, 0,
		SECURITY_NATIVE_DREP, &inbuf, 0, NULL,
		&outbuf, &sspi_flags_out, &ts_expiry);
#endif /* UNICODE */

	wpa_printf(MSG_MSGDUMP, "Schannel: InitializeSecurityContext -> "
		   "status=%d inlen[0]=%d intype[0]=%d inlen[1]=%d "
		   "intype[1]=%d outlen[0]=%d",
		   (int) status, (int) inbufs[0].cbBuffer,
		   (int) inbufs[0].BufferType, (int) inbufs[1].cbBuffer,
		   (int) inbufs[1].BufferType,
		   (int) outbufs[0].cbBuffer);
	if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED ||
	    (FAILED(status) && (sspi_flags_out & ISC_RET_EXTENDED_ERROR))) {
		if (outbufs[0].cbBuffer != 0 && outbufs[0].pvBuffer) {
			wpa_hexdump(MSG_MSGDUMP, "SChannel - output",
				    outbufs[0].pvBuffer, outbufs[0].cbBuffer);
			out_buf = wpabuf_alloc_copy(outbufs[0].pvBuffer,
						    outbufs[0].cbBuffer);
			global->sspi->FreeContextBuffer(outbufs[0].pvBuffer);
			outbufs[0].pvBuffer = NULL;
			if (out_buf == NULL)
				return NULL;
		}
	}

	switch (status) {
	case SEC_E_INCOMPLETE_MESSAGE:
		wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INCOMPLETE_MESSAGE");
		break;
	case SEC_I_CONTINUE_NEEDED:
		wpa_printf(MSG_DEBUG, "Schannel: SEC_I_CONTINUE_NEEDED");
		break;
	case SEC_E_OK:
		/* TODO: verify server certificate chain */
		wpa_printf(MSG_DEBUG, "Schannel: SEC_E_OK - Handshake "
			   "completed successfully");
		conn->established = 1;
		tls_get_eap(global, conn);

		/* Need to return something to get final TLS ACK. */
		if (out_buf == NULL)
			out_buf = wpabuf_alloc(0);

		if (inbufs[1].BufferType == SECBUFFER_EXTRA) {
			wpa_hexdump(MSG_MSGDUMP, "SChannel - Encrypted "
				    "application data",
				    inbufs[1].pvBuffer, inbufs[1].cbBuffer);
			if (appl_data) {
				*appl_data = wpabuf_alloc_copy(
					outbufs[1].pvBuffer,
					outbufs[1].cbBuffer);
			}
			global->sspi->FreeContextBuffer(inbufs[1].pvBuffer);
			inbufs[1].pvBuffer = NULL;
		}
		break;
	case SEC_I_INCOMPLETE_CREDENTIALS:
		wpa_printf(MSG_DEBUG,
			   "Schannel: SEC_I_INCOMPLETE_CREDENTIALS");
		break;
	case SEC_E_WRONG_PRINCIPAL:
		wpa_printf(MSG_DEBUG, "Schannel: SEC_E_WRONG_PRINCIPAL");
		break;
	case SEC_E_INTERNAL_ERROR:
		wpa_printf(MSG_DEBUG, "Schannel: SEC_E_INTERNAL_ERROR");
		break;
	}

	if (FAILED(status)) {
		wpa_printf(MSG_DEBUG, "Schannel: Handshake failed "
			   "(out_buf=%p)", out_buf);
		conn->failed++;
		global->sspi->DeleteSecurityContext(&conn->context);
		return out_buf;
	}

	if (inbufs[1].BufferType == SECBUFFER_EXTRA) {
		/* TODO: Can this happen? What to do with this data? */
		wpa_hexdump(MSG_MSGDUMP, "SChannel - Leftover data",
			    inbufs[1].pvBuffer, inbufs[1].cbBuffer);
		global->sspi->FreeContextBuffer(inbufs[1].pvBuffer);
		inbufs[1].pvBuffer = NULL;
	}

	return out_buf;
}


struct wpabuf * tls_connection_server_handshake(void *tls_ctx,
						struct tls_connection *conn,
						const struct wpabuf *in_data,
						struct wpabuf **appl_data)
{
	return NULL;
}


struct wpabuf * tls_connection_encrypt(void *tls_ctx,
				       struct tls_connection *conn,
				       const struct wpabuf *in_data)
{
	struct tls_global *global = tls_ctx;
	SECURITY_STATUS status;
	SecBufferDesc buf;
	SecBuffer bufs[4];
	SecPkgContext_StreamSizes sizes;
	int i;
	struct wpabuf *out;

	status = global->sspi->QueryContextAttributes(&conn->context,
						      SECPKG_ATTR_STREAM_SIZES,
						      &sizes);
	if (status != SEC_E_OK) {
		wpa_printf(MSG_DEBUG, "%s: QueryContextAttributes failed",
			   __func__);
		return NULL;
	}
	wpa_printf(MSG_DEBUG, "%s: Stream sizes: header=%u trailer=%u",
		   __func__,
		   (unsigned int) sizes.cbHeader,
		   (unsigned int) sizes.cbTrailer);

	out = wpabuf_alloc(sizes.cbHeader + wpabuf_len(in_data) +
			   sizes.cbTrailer);

	os_memset(&bufs, 0, sizeof(bufs));
	bufs[0].pvBuffer = wpabuf_put(out, sizes.cbHeader);
	bufs[0].cbBuffer = sizes.cbHeader;
	bufs[0].BufferType = SECBUFFER_STREAM_HEADER;

	bufs[1].pvBuffer = wpabuf_put(out, 0);
	wpabuf_put_buf(out, in_data);
	bufs[1].cbBuffer = wpabuf_len(in_data);
	bufs[1].BufferType = SECBUFFER_DATA;

	bufs[2].pvBuffer = wpabuf_put(out, sizes.cbTrailer);
	bufs[2].cbBuffer = sizes.cbTrailer;
	bufs[2].BufferType = SECBUFFER_STREAM_TRAILER;

	buf.ulVersion = SECBUFFER_VERSION;
	buf.cBuffers = 3;
	buf.pBuffers = bufs;

	status = global->sspi->EncryptMessage(&conn->context, 0, &buf, 0);

	wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage -> "
		   "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d "
		   "len[2]=%d type[2]=%d",
		   (int) status,
		   (int) bufs[0].cbBuffer, (int) bufs[0].BufferType,
		   (int) bufs[1].cbBuffer, (int) bufs[1].BufferType,
		   (int) bufs[2].cbBuffer, (int) bufs[2].BufferType);
	wpa_printf(MSG_MSGDUMP, "Schannel: EncryptMessage pointers: "
		   "out_data=%p bufs %p %p %p",
		   wpabuf_head(out), bufs[0].pvBuffer, bufs[1].pvBuffer,
		   bufs[2].pvBuffer);

	for (i = 0; i < 3; i++) {
		if (bufs[i].pvBuffer && bufs[i].BufferType != SECBUFFER_EMPTY)
		{
			wpa_hexdump(MSG_MSGDUMP, "SChannel: bufs",
				    bufs[i].pvBuffer, bufs[i].cbBuffer);
		}
	}

	if (status == SEC_E_OK) {
		wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__);
		wpa_hexdump_buf_key(MSG_MSGDUMP, "Schannel: Encrypted data "
				    "from EncryptMessage", out);
		return out;
	}

	wpa_printf(MSG_DEBUG, "%s: Failed - status=%d",
		   __func__, (int) status);
	wpabuf_free(out);
	return NULL;
}


struct wpabuf * tls_connection_decrypt(void *tls_ctx,
				       struct tls_connection *conn,
				       const struct wpabuf *in_data)
{
	struct tls_global *global = tls_ctx;
	SECURITY_STATUS status;
	SecBufferDesc buf;
	SecBuffer bufs[4];
	int i;
	struct wpabuf *out, *tmp;

	wpa_hexdump_buf(MSG_MSGDUMP,
			"Schannel: Encrypted data to DecryptMessage", in_data);
	os_memset(&bufs, 0, sizeof(bufs));
	tmp = wpabuf_dup(in_data);
	if (tmp == NULL)
		return NULL;
	bufs[0].pvBuffer = wpabuf_mhead(tmp);
	bufs[0].cbBuffer = wpabuf_len(in_data);
	bufs[0].BufferType = SECBUFFER_DATA;

	bufs[1].BufferType = SECBUFFER_EMPTY;
	bufs[2].BufferType = SECBUFFER_EMPTY;
	bufs[3].BufferType = SECBUFFER_EMPTY;

	buf.ulVersion = SECBUFFER_VERSION;
	buf.cBuffers = 4;
	buf.pBuffers = bufs;

	status = global->sspi->DecryptMessage(&conn->context, &buf, 0,
						    NULL);
	wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage -> "
		   "status=%d len[0]=%d type[0]=%d len[1]=%d type[1]=%d "
		   "len[2]=%d type[2]=%d len[3]=%d type[3]=%d",
		   (int) status,
		   (int) bufs[0].cbBuffer, (int) bufs[0].BufferType,
		   (int) bufs[1].cbBuffer, (int) bufs[1].BufferType,
		   (int) bufs[2].cbBuffer, (int) bufs[2].BufferType,
		   (int) bufs[3].cbBuffer, (int) bufs[3].BufferType);
	wpa_printf(MSG_MSGDUMP, "Schannel: DecryptMessage pointers: "
		   "out_data=%p bufs %p %p %p %p",
		   wpabuf_head(tmp), bufs[0].pvBuffer, bufs[1].pvBuffer,
		   bufs[2].pvBuffer, bufs[3].pvBuffer);

	switch (status) {
	case SEC_E_INCOMPLETE_MESSAGE:
		wpa_printf(MSG_DEBUG, "%s: SEC_E_INCOMPLETE_MESSAGE",
			   __func__);
		break;
	case SEC_E_OK:
		wpa_printf(MSG_DEBUG, "%s: SEC_E_OK", __func__);
		for (i = 0; i < 4; i++) {
			if (bufs[i].BufferType == SECBUFFER_DATA)
				break;
		}
		if (i == 4) {
			wpa_printf(MSG_DEBUG, "%s: No output data from "
				   "DecryptMessage", __func__);
			wpabuf_free(tmp);
			return NULL;
		}
		wpa_hexdump_key(MSG_MSGDUMP, "Schannel: Decrypted data from "
				"DecryptMessage",
				bufs[i].pvBuffer, bufs[i].cbBuffer);
		out = wpabuf_alloc_copy(bufs[i].pvBuffer, bufs[i].cbBuffer);
		wpabuf_free(tmp);
		return out;
	}

	wpa_printf(MSG_DEBUG, "%s: Failed - status=%d",
		   __func__, (int) status);
	wpabuf_free(tmp);
	return NULL;
}


int tls_connection_resumed(void *ssl_ctx, struct tls_connection *conn)
{
	return 0;
}


int tls_connection_set_cipher_list(void *tls_ctx, struct tls_connection *conn,
				   u8 *ciphers)
{
	return -1;
}


int tls_get_cipher(void *ssl_ctx, struct tls_connection *conn,
		   char *buf, size_t buflen)
{
	return -1;
}


int tls_connection_enable_workaround(void *ssl_ctx,
				     struct tls_connection *conn)
{
	return 0;
}


int tls_connection_client_hello_ext(void *ssl_ctx, struct tls_connection *conn,
				    int ext_type, const u8 *data,
				    size_t data_len)
{
	return -1;
}


int tls_connection_get_failed(void *ssl_ctx, struct tls_connection *conn)
{
	if (conn == NULL)
		return -1;
	return conn->failed;
}


int tls_connection_get_read_alerts(void *ssl_ctx, struct tls_connection *conn)
{
	if (conn == NULL)
		return -1;
	return conn->read_alerts;
}


int tls_connection_get_write_alerts(void *ssl_ctx, struct tls_connection *conn)
{
	if (conn == NULL)
		return -1;
	return conn->write_alerts;
}


int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn,
			      const struct tls_connection_params *params)
{
	struct tls_global *global = tls_ctx;
	ALG_ID algs[1];
	SECURITY_STATUS status;
	TimeStamp ts_expiry;

	if (conn == NULL)
		return -1;

	if (global->my_cert_store == NULL &&
	    (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) ==
	    NULL) {
		wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x",
			   __func__, (unsigned int) GetLastError());
		return -1;
	}

	os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred));
	conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION;
	conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1;
	algs[0] = CALG_RSA_KEYX;
	conn->schannel_cred.cSupportedAlgs = 1;
	conn->schannel_cred.palgSupportedAlgs = algs;
	conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS;
#ifdef UNICODE
	status = global->sspi->AcquireCredentialsHandleW(
		NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL,
		&conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry);
#else /* UNICODE */
	status = global->sspi->AcquireCredentialsHandleA(
		NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL,
		&conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry);
#endif /* UNICODE */
	if (status != SEC_E_OK) {
		wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - "
			   "0x%x", __func__, (unsigned int) status);
		return -1;
	}

	return 0;
}


unsigned int tls_capabilities(void *tls_ctx)
{
	return 0;
}
