/*
 * TLS support for CUPS on Windows using the Security Support Provider
 * Interface (SSPI).
 *
 * Copyright 2010-2017 by Apple Inc.
 *
 * These coded instructions, statements, and computer programs are the
 * property of Apple Inc. and are protected by Federal copyright
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 * which should have been included with this file.  If this file is
 * missing or damaged, see the license at "http://www.cups.org/".
 *
 * This file is subject to the Apple OS-Developed Software exception.
 */

/**** This file is included from tls.c ****/

/*
 * Include necessary headers...
 */

#include "debug-private.h"


/*
 * Include necessary libraries...
 */

#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "Secur32.lib")
#pragma comment(lib, "Ws2_32.lib")


/*
 * Constants...
 */

#ifndef SECURITY_FLAG_IGNORE_UNKNOWN_CA
#  define SECURITY_FLAG_IGNORE_UNKNOWN_CA         0x00000100 /* Untrusted root */
#endif /* SECURITY_FLAG_IGNORE_UNKNOWN_CA */

#ifndef SECURITY_FLAG_IGNORE_CERT_CN_INVALID
#  define SECURITY_FLAG_IGNORE_CERT_CN_INVALID	  0x00001000 /* Common name does not match */
#endif /* !SECURITY_FLAG_IGNORE_CERT_CN_INVALID */

#ifndef SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
#  define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID  0x00002000 /* Expired X509 Cert. */
#endif /* !SECURITY_FLAG_IGNORE_CERT_DATE_INVALID */


/*
 * Local globals...
 */

static int		tls_options = -1;/* Options for TLS connections */


/*
 * Local functions...
 */

static _http_sspi_t *http_sspi_alloc(void);
static int	http_sspi_client(http_t *http, const char *hostname);
static PCCERT_CONTEXT http_sspi_create_credential(http_credential_t *cred);
static BOOL	http_sspi_find_credentials(http_t *http, const LPWSTR containerName, const char *common_name);
static void	http_sspi_free(_http_sspi_t *sspi);
static BOOL	http_sspi_make_credentials(_http_sspi_t *sspi, const LPWSTR containerName, const char *common_name, _http_mode_t mode, int years);
static int	http_sspi_server(http_t *http, const char *hostname);
static void	http_sspi_set_allows_any_root(_http_sspi_t *sspi, BOOL allow);
static void	http_sspi_set_allows_expired_certs(_http_sspi_t *sspi, BOOL allow);
static const char *http_sspi_strerror(char *buffer, size_t bufsize, DWORD code);
static DWORD	http_sspi_verify(PCCERT_CONTEXT cert, const char *common_name, DWORD dwCertFlags);


/*
 * 'cupsMakeServerCredentials()' - Make a self-signed certificate and private key pair.
 *
 * @since CUPS 2.0/OS 10.10@
 */

int					/* O - 1 on success, 0 on failure */
cupsMakeServerCredentials(
    const char *path,			/* I - Keychain path or @code NULL@ for default */
    const char *common_name,		/* I - Common name */
    int        num_alt_names,		/* I - Number of subject alternate names */
    const char **alt_names,		/* I - Subject Alternate Names */
    time_t     expiration_date)		/* I - Expiration date */
{
  _http_sspi_t	*sspi;			/* SSPI data */
  int		ret;			/* Return value */


  DEBUG_printf(("cupsMakeServerCredentials(path=\"%s\", common_name=\"%s\", num_alt_names=%d, alt_names=%p, expiration_date=%d)", path, common_name, num_alt_names, alt_names, (int)expiration_date));

  (void)path;
  (void)num_alt_names;
  (void)alt_names;

  sspi = http_sspi_alloc();
  ret  = http_sspi_make_credentials(sspi, L"ServerContainer", common_name, _HTTP_MODE_SERVER, (int)((expiration_date - time(NULL) + 86399) / 86400 / 365));

  http_sspi_free(sspi);

  return (ret);
}


/*
 * 'cupsSetServerCredentials()' - Set the default server credentials.
 *
 * Note: The server credentials are used by all threads in the running process.
 * This function is threadsafe.
 *
 * @since CUPS 2.0/OS 10.10@
 */

int					/* O - 1 on success, 0 on failure */
cupsSetServerCredentials(
    const char *path,			/* I - Keychain path or @code NULL@ for default */
    const char *common_name,		/* I - Default common name for server */
    int        auto_create)		/* I - 1 = automatically create self-signed certificates */
{
  DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create));

  (void)path;
  (void)common_name;
  (void)auto_create;

  return (0);
}


/*
 * 'httpCopyCredentials()' - Copy the credentials associated with the peer in
 *                           an encrypted connection.
 *
 * @since CUPS 1.5/macOS 10.7@
 */

int					/* O - Status of call (0 = success) */
httpCopyCredentials(
    http_t	 *http,			/* I - Connection to server */
    cups_array_t **credentials)		/* O - Array of credentials */
{
  DEBUG_printf(("httpCopyCredentials(http=%p, credentials=%p)", http, credentials));

  if (!http || !http->tls || !http->tls->remoteCert || !credentials)
  {
    if (credentials)
      *credentials = NULL;

    return (-1);
  }

  *credentials = cupsArrayNew(NULL, NULL);
  httpAddCredential(*credentials, http->tls->remoteCert->pbCertEncoded, http->tls->remoteCert->cbCertEncoded);

  return (0);
}


/*
 * '_httpCreateCredentials()' - Create credentials in the internal format.
 */

http_tls_credentials_t			/* O - Internal credentials */
_httpCreateCredentials(
    cups_array_t *credentials)		/* I - Array of credentials */
{
  return (http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials)));
}


/*
 * 'httpCredentialsAreValidForName()' - Return whether the credentials are valid for the given name.
 *
 * @since CUPS 2.0/OS 10.10@
 */

int					/* O - 1 if valid, 0 otherwise */
httpCredentialsAreValidForName(
    cups_array_t *credentials,		/* I - Credentials */
    const char   *common_name)		/* I - Name to check */
{
  int		valid = 1;		/* Valid name? */
  PCCERT_CONTEXT cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials));
					/* Certificate */
  char		cert_name[1024];	/* Name from certificate */


  if (cert)
  {
    if (CertNameToStr(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name)))
    {
     /*
      * Extract common name at end...
      */

      char  *ptr = strrchr(cert_name, ',');
      if (ptr && ptr[1])
        _cups_strcpy(cert_name, ptr + 2);
    }
    else
      strlcpy(cert_name, "unknown", sizeof(cert_name));

    CertFreeCertificateContext(cert);
  }
  else
    strlcpy(cert_name, "unknown", sizeof(cert_name));

 /*
  * Compare the common names...
  */

  if (_cups_strcasecmp(common_name, cert_name))
  {
   /*
    * Not an exact match for the common name, check for wildcard certs...
    */

    const char	*domain = strchr(common_name, '.');
					/* Domain in common name */

    if (strncmp(cert_name, "*.", 2) || !domain || _cups_strcasecmp(domain, cert_name + 1))
    {
     /*
      * Not a wildcard match.
      */

      /* TODO: Check subject alternate names */
      valid = 0;
    }
  }

  return (valid);
}


/*
 * 'httpCredentialsGetTrust()' - Return the trust of credentials.
 *
 * @since CUPS 2.0/OS 10.10@
 */

http_trust_t				/* O - Level of trust */
httpCredentialsGetTrust(
    cups_array_t *credentials,		/* I - Credentials */
    const char   *common_name)		/* I - Common name for trust lookup */
{
  http_trust_t	trust = HTTP_TRUST_OK;	/* Level of trust */
  PCCERT_CONTEXT cert = NULL;		/* Certificate to validate */
  DWORD		certFlags = 0;		/* Cert verification flags */
  _cups_globals_t *cg = _cupsGlobals();	/* Per-thread global data */


  if (!common_name)
    return (HTTP_TRUST_UNKNOWN);

  cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials));
  if (!cert)
    return (HTTP_TRUST_UNKNOWN);

  if (cg->any_root < 0)
    _cupsSetDefaults();

  if (cg->any_root)
    certFlags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;

  if (cg->expired_certs)
    certFlags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;

  if (!cg->validate_certs)
    certFlags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;

  if (http_sspi_verify(cert, common_name, certFlags) != SEC_E_OK)
    trust = HTTP_TRUST_INVALID;

  CertFreeCertificateContext(cert);

  return (trust);
}


/*
 * 'httpCredentialsGetExpiration()' - Return the expiration date of the credentials.
 *
 * @since CUPS 2.0/OS 10.10@
 */

time_t					/* O - Expiration date of credentials */
httpCredentialsGetExpiration(
    cups_array_t *credentials)		/* I - Credentials */
{
  time_t	expiration_date = 0;	/* Expiration data of credentials */
  PCCERT_CONTEXT cert = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials));
					/* Certificate */

  if (cert)
  {
    SYSTEMTIME	systime;		/* System time */
    struct tm	tm;			/* UNIX date/time */

    FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime);

    tm.tm_year = systime.wYear - 1900;
    tm.tm_mon  = systime.wMonth - 1;
    tm.tm_mday = systime.wDay;
    tm.tm_hour = systime.wHour;
    tm.tm_min  = systime.wMinute;
    tm.tm_sec  = systime.wSecond;

    expiration_date = mktime(&tm);

    CertFreeCertificateContext(cert);
  }

  return (expiration_date);
}


/*
 * 'httpCredentialsString()' - Return a string representing the credentials.
 *
 * @since CUPS 2.0/OS 10.10@
 */

size_t					/* O - Total size of credentials string */
httpCredentialsString(
    cups_array_t *credentials,		/* I - Credentials */
    char         *buffer,		/* I - Buffer or @code NULL@ */
    size_t       bufsize)		/* I - Size of buffer */
{
  http_credential_t	*first = (http_credential_t *)cupsArrayFirst(credentials);
					/* First certificate */
  PCCERT_CONTEXT 	cert;		/* Certificate */


  DEBUG_printf(("httpCredentialsString(credentials=%p, buffer=%p, bufsize=" CUPS_LLFMT ")", credentials, buffer, CUPS_LLCAST bufsize));

  if (!buffer)
    return (0);

  if (buffer && bufsize > 0)
    *buffer = '\0';

  cert = http_sspi_create_credential(first);

  if (cert)
  {
    char		cert_name[256];	/* Common name */
    SYSTEMTIME		systime;	/* System time */
    struct tm		tm;		/* UNIX date/time */
    time_t		expiration;	/* Expiration date of cert */
    _cups_md5_state_t	md5_state;	/* MD5 state */
    unsigned char	md5_digest[16];	/* MD5 result */

    FileTimeToSystemTime(&(cert->pCertInfo->NotAfter), &systime);

    tm.tm_year = systime.wYear - 1900;
    tm.tm_mon  = systime.wMonth - 1;
    tm.tm_mday = systime.wDay;
    tm.tm_hour = systime.wHour;
    tm.tm_min  = systime.wMinute;
    tm.tm_sec  = systime.wSecond;

    expiration = mktime(&tm);

    if (CertNameToStr(X509_ASN_ENCODING, &(cert->pCertInfo->Subject), CERT_SIMPLE_NAME_STR, cert_name, sizeof(cert_name)))
    {
     /*
      * Extract common name at end...
      */

      char  *ptr = strrchr(cert_name, ',');
      if (ptr && ptr[1])
        _cups_strcpy(cert_name, ptr + 2);
    }
    else
      strlcpy(cert_name, "unknown", sizeof(cert_name));

    _cupsMD5Init(&md5_state);
    _cupsMD5Append(&md5_state, first->data, (int)first->datalen);
    _cupsMD5Finish(&md5_state, md5_digest);

    snprintf(buffer, bufsize, "%s / %s / %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", cert_name, httpGetDateString(expiration), md5_digest[0], md5_digest[1], md5_digest[2], md5_digest[3], md5_digest[4], md5_digest[5], md5_digest[6], md5_digest[7], md5_digest[8], md5_digest[9], md5_digest[10], md5_digest[11], md5_digest[12], md5_digest[13], md5_digest[14], md5_digest[15]);

    CertFreeCertificateContext(cert);
  }

  DEBUG_printf(("1httpCredentialsString: Returning \"%s\".", buffer));

  return (strlen(buffer));
}


/*
 * '_httpFreeCredentials()' - Free internal credentials.
 */

void
_httpFreeCredentials(
    http_tls_credentials_t credentials)	/* I - Internal credentials */
{
  if (!credentials)
    return;

  CertFreeCertificateContext(credentials);
}


/*
 * 'httpLoadCredentials()' - Load X.509 credentials from a keychain file.
 *
 * @since CUPS 2.0/OS 10.10@
 */

int					/* O - 0 on success, -1 on error */
httpLoadCredentials(
    const char   *path,			/* I  - Keychain path or @code NULL@ for default */
    cups_array_t **credentials,		/* IO - Credentials */
    const char   *common_name)		/* I  - Common name for credentials */
{
  HCERTSTORE	store = NULL;		/* Certificate store */
  PCCERT_CONTEXT storedContext = NULL;	/* Context created from the store */
  DWORD		dwSize = 0; 		/* 32 bit size */
  PBYTE		p = NULL;		/* Temporary storage */
  HCRYPTPROV	hProv = (HCRYPTPROV)NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB sib;			/* Arbitrary array of bytes */
#ifdef DEBUG
  char		error[1024];		/* Error message buffer */
#endif /* DEBUG */


  DEBUG_printf(("httpLoadCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name));

  (void)path;

  if (credentials)
  {
    *credentials = NULL;
  }
  else
  {
    DEBUG_puts("1httpLoadCredentials: NULL credentials pointer, returning -1.");
    return (-1);
  }

  if (!common_name)
  {
    DEBUG_puts("1httpLoadCredentials: Bad common name, returning -1.");
    return (-1);
  }

  if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("1httpLoadCredentials: CryptAcquireContext failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY");

  if (!store)
  {
    DEBUG_printf(("1httpLoadCredentials: CertOpenSystemStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  p = (PBYTE)malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("1httpLoadCredentials: malloc failed for %d bytes.", dwSize));
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL))
  {
    DEBUG_printf(("1httpLoadCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  sib.cbData = dwSize;
  sib.pbData = p;

  storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL);

  if (!storedContext)
  {
    DEBUG_printf(("1httpLoadCredentials: Unable to find credentials for \"%s\".", common_name));
    goto cleanup;
  }

  *credentials = cupsArrayNew(NULL, NULL);
  httpAddCredential(*credentials, storedContext->pbCertEncoded, storedContext->cbCertEncoded);

cleanup:

 /*
  * Cleanup
  */

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  DEBUG_printf(("1httpLoadCredentials: Returning %d.", *credentials ? 0 : -1));

  return (*credentials ? 0 : -1);
}


/*
 * 'httpSaveCredentials()' - Save X.509 credentials to a keychain file.
 *
 * @since CUPS 2.0/OS 10.10@
 */

int					/* O - -1 on error, 0 on success */
httpSaveCredentials(
    const char   *path,			/* I - Keychain path or @code NULL@ for default */
    cups_array_t *credentials,		/* I - Credentials */
    const char   *common_name)		/* I - Common name for credentials */
{
  HCERTSTORE	store = NULL;		/* Certificate store */
  PCCERT_CONTEXT storedContext = NULL;	/* Context created from the store */
  PCCERT_CONTEXT createdContext = NULL;	/* Context created by us */
  DWORD		dwSize = 0; 		/* 32 bit size */
  PBYTE		p = NULL;		/* Temporary storage */
  HCRYPTPROV	hProv = (HCRYPTPROV)NULL;
					/* Handle to a CSP */
  CRYPT_KEY_PROV_INFO ckp;		/* Handle to crypto key */
  int		ret = -1;		/* Return value */
#ifdef DEBUG
  char		error[1024];		/* Error message buffer */
#endif /* DEBUG */


  DEBUG_printf(("httpSaveCredentials(path=\"%s\", credentials=%p, common_name=\"%s\")", path, credentials, common_name));

  (void)path;

  if (!common_name)
  {
    DEBUG_puts("1httpSaveCredentials: Bad common name, returning -1.");
    return (-1);
  }

  createdContext = http_sspi_create_credential((http_credential_t *)cupsArrayFirst(credentials));
  if (!createdContext)
  {
    DEBUG_puts("1httpSaveCredentials: Bad credentials, returning -1.");
    return (-1);
  }

  if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, L"RememberedContainer", MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("1httpSaveCredentials: CryptAcquireContext failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY");

  if (!store)
  {
    DEBUG_printf(("1httpSaveCredentials: CertOpenSystemStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  p = (PBYTE)malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("1httpSaveCredentials: malloc failed for %d bytes.", dwSize));
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL))
  {
    DEBUG_printf(("1httpSaveCredentials: CertStrToName failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

 /*
  * Add the created context to the named store, and associate it with the named
  * container...
  */

  if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext))
  {
    DEBUG_printf(("1httpSaveCredentials: CertAddCertificateContextToStore failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  ZeroMemory(&ckp, sizeof(ckp));
  ckp.pwszContainerName = L"RememberedContainer";
  ckp.pwszProvName      = MS_DEF_PROV_W;
  ckp.dwProvType        = PROV_RSA_FULL;
  ckp.dwFlags           = CRYPT_MACHINE_KEYSET;
  ckp.dwKeySpec         = AT_KEYEXCHANGE;

  if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp))
  {
    DEBUG_printf(("1httpSaveCredentials: CertSetCertificateContextProperty failed: %s", http_sspi_strerror(error, sizeof(error), GetLastError())));
    goto cleanup;
  }

  ret = 0;

cleanup:

 /*
  * Cleanup
  */

  if (createdContext)
    CertFreeCertificateContext(createdContext);

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  DEBUG_printf(("1httpSaveCredentials: Returning %d.", ret));
  return (ret);
}


/*
 * '_httpTLSInitialize()' - Initialize the TLS stack.
 */

void
_httpTLSInitialize(void)
{
 /*
  * Nothing to do...
  */
}


/*
 * '_httpTLSPending()' - Return the number of pending TLS-encrypted bytes.
 */

size_t					/* O - Bytes available */
_httpTLSPending(http_t *http)		/* I - HTTP connection */
{
  if (http->tls)
    return (http->tls->readBufferUsed);
  else
    return (0);
}


/*
 * '_httpTLSRead()' - Read from a SSL/TLS connection.
 */

int					/* O - Bytes read */
_httpTLSRead(http_t *http,		/* I - HTTP connection */
	     char   *buf,		/* I - Buffer to store data */
	     int    len)		/* I - Length of buffer */
{
  int		i;			/* Looping var */
  _http_sspi_t	*sspi = http->tls;	/* SSPI data */
  SecBufferDesc	message;		/* Array of SecBuffer struct */
  SecBuffer	buffers[4] = { 0 };	/* Security package buffer */
  int		num = 0;		/* Return value */
  PSecBuffer	pDataBuffer;		/* Data buffer */
  PSecBuffer	pExtraBuffer;		/* Excess data buffer */
  SECURITY_STATUS scRet;		/* SSPI status */


  DEBUG_printf(("4_httpTLSRead(http=%p, buf=%p, len=%d)", http, buf, len));

 /*
  * If there are bytes that have already been decrypted and have not yet been
  * read, return those...
  */

  if (sspi->readBufferUsed > 0)
  {
    int bytesToCopy = min(sspi->readBufferUsed, len);
					/* Number of bytes to copy */

    memcpy(buf, sspi->readBuffer, bytesToCopy);
    sspi->readBufferUsed -= bytesToCopy;

    if (sspi->readBufferUsed > 0)
      memmove(sspi->readBuffer, sspi->readBuffer + bytesToCopy, sspi->readBufferUsed);

    DEBUG_printf(("5_httpTLSRead: Returning %d bytes previously decrypted.", bytesToCopy));

    return (bytesToCopy);
  }

 /*
  * Initialize security buffer structs
  */

  message.ulVersion = SECBUFFER_VERSION;
  message.cBuffers  = 4;
  message.pBuffers  = buffers;

  do
  {
   /*
    * If there is not enough space in the buffer, then increase its size...
    */

    if (sspi->decryptBufferLength <= sspi->decryptBufferUsed)
    {
      BYTE *temp;			/* New buffer */

      if (sspi->decryptBufferLength >= 262144)
      {
	WSASetLastError(E_OUTOFMEMORY);
        DEBUG_puts("_httpTLSRead: Decryption buffer too large (>256k)");
	return (-1);
      }

      if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL)
      {
	DEBUG_printf(("_httpTLSRead: Unable to allocate %d byte decryption buffer.", sspi->decryptBufferLength + 4096));
	WSASetLastError(E_OUTOFMEMORY);
	return (-1);
      }

      sspi->decryptBufferLength += 4096;
      sspi->decryptBuffer       = temp;

      DEBUG_printf(("_httpTLSRead: Resized decryption buffer to %d bytes.", sspi->decryptBufferLength));
    }

    buffers[0].pvBuffer	  = sspi->decryptBuffer;
    buffers[0].cbBuffer	  = (unsigned long)sspi->decryptBufferUsed;
    buffers[0].BufferType = SECBUFFER_DATA;
    buffers[1].BufferType = SECBUFFER_EMPTY;
    buffers[2].BufferType = SECBUFFER_EMPTY;
    buffers[3].BufferType = SECBUFFER_EMPTY;

    DEBUG_printf(("5_httpTLSRead: decryptBufferUsed=%d", sspi->decryptBufferUsed));

    scRet = DecryptMessage(&sspi->context, &message, 0, NULL);

    if (scRet == SEC_E_INCOMPLETE_MESSAGE)
    {
      num = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0);
      if (num < 0)
      {
	DEBUG_printf(("5_httpTLSRead: recv failed: %d", WSAGetLastError()));
	return (-1);
      }
      else if (num == 0)
      {
	DEBUG_puts("5_httpTLSRead: Server disconnected.");
	return (0);
      }

      DEBUG_printf(("5_httpTLSRead: Read %d bytes into decryption buffer.", num));

      sspi->decryptBufferUsed += num;
    }
  }
  while (scRet == SEC_E_INCOMPLETE_MESSAGE);

  if (scRet == SEC_I_CONTEXT_EXPIRED)
  {
    DEBUG_puts("5_httpTLSRead: Context expired.");
    WSASetLastError(WSAECONNRESET);
    return (-1);
  }
  else if (scRet != SEC_E_OK)
  {
    DEBUG_printf(("5_httpTLSRead: DecryptMessage failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
    WSASetLastError(WSASYSCALLFAILURE);
    return (-1);
  }

 /*
  * The decryption worked.  Now, locate data buffer.
  */

  pDataBuffer  = NULL;
  pExtraBuffer = NULL;

  for (i = 1; i < 4; i++)
  {
    if (buffers[i].BufferType == SECBUFFER_DATA)
      pDataBuffer = &buffers[i];
    else if (!pExtraBuffer && (buffers[i].BufferType == SECBUFFER_EXTRA))
      pExtraBuffer = &buffers[i];
  }

 /*
  * If a data buffer is found, then copy the decrypted bytes to the passed-in
  * buffer...
  */

  if (pDataBuffer)
  {
    int bytesToCopy = min((int)pDataBuffer->cbBuffer, len);
				      /* Number of bytes to copy into buf */
    int bytesToSave = pDataBuffer->cbBuffer - bytesToCopy;
				      /* Number of bytes to save in our read buffer */

    if (bytesToCopy)
      memcpy(buf, pDataBuffer->pvBuffer, bytesToCopy);

   /*
    * If there are more decrypted bytes than can be copied to the passed in
    * buffer, then save them...
    */

    if (bytesToSave)
    {
      if ((sspi->readBufferLength - sspi->readBufferUsed) < bytesToSave)
      {
        BYTE *temp;			/* New buffer pointer */

        if ((temp = realloc(sspi->readBuffer, sspi->readBufferUsed + bytesToSave)) == NULL)
	{
	  DEBUG_printf(("_httpTLSRead: Unable to allocate %d bytes.", sspi->readBufferUsed + bytesToSave));
	  WSASetLastError(E_OUTOFMEMORY);
	  return (-1);
	}

	sspi->readBufferLength = sspi->readBufferUsed + bytesToSave;
	sspi->readBuffer       = temp;
      }

      memcpy(((BYTE *)sspi->readBuffer) + sspi->readBufferUsed, ((BYTE *)pDataBuffer->pvBuffer) + bytesToCopy, bytesToSave);

      sspi->readBufferUsed += bytesToSave;
    }

    num = bytesToCopy;
  }
  else
  {
    DEBUG_puts("_httpTLSRead: Unable to find data buffer.");
    WSASetLastError(WSASYSCALLFAILURE);
    return (-1);
  }

 /*
  * If the decryption process left extra bytes, then save those back in
  * decryptBuffer.  They will be processed the next time through the loop.
  */

  if (pExtraBuffer)
  {
    memmove(sspi->decryptBuffer, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer);
    sspi->decryptBufferUsed = pExtraBuffer->cbBuffer;
  }
  else
  {
    sspi->decryptBufferUsed = 0;
  }

  return (num);
}


/*
 * '_httpTLSSetOptions()' - Set TLS protocol and cipher suite options.
 */

void
_httpTLSSetOptions(int options)		/* I - Options */
{
  if (!(options & _HTTP_TLS_SET_DEFAULT) || tls_options < 0)
    tls_options = options;
}


/*
 * '_httpTLSStart()' - Set up SSL/TLS support on a connection.
 */

int					/* O - 0 on success, -1 on failure */
_httpTLSStart(http_t *http)		/* I - HTTP connection */
{
  char	hostname[256],			/* Hostname */
	*hostptr;			/* Pointer into hostname */


  DEBUG_printf(("3_httpTLSStart(http=%p)", http));

  if (tls_options < 0)
  {
    DEBUG_puts("4_httpTLSStart: Setting defaults.");
    _cupsSetDefaults();
    DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options));
  }

  if ((http->tls = http_sspi_alloc()) == NULL)
    return (-1);

  if (http->mode == _HTTP_MODE_CLIENT)
  {
   /*
    * Client: determine hostname...
    */

    if (httpAddrLocalhost(http->hostaddr))
    {
      strlcpy(hostname, "localhost", sizeof(hostname));
    }
    else
    {
     /*
      * Otherwise make sure the hostname we have does not end in a trailing dot.
      */

      strlcpy(hostname, http->hostname, sizeof(hostname));
      if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
	  *hostptr == '.')
	*hostptr = '\0';
    }

    return (http_sspi_client(http, hostname));
  }
  else
  {
   /*
    * Server: determine hostname to use...
    */

    if (http->fields[HTTP_FIELD_HOST][0])
    {
     /*
      * Use hostname for TLS upgrade...
      */

      strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname));
    }
    else
    {
     /*
      * Resolve hostname from connection address...
      */

      http_addr_t	addr;		/* Connection address */
      socklen_t		addrlen;	/* Length of address */

      addrlen = sizeof(addr);
      if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen))
      {
	DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno)));
	hostname[0] = '\0';
      }
      else if (httpAddrLocalhost(&addr))
	hostname[0] = '\0';
      else
      {
	httpAddrLookup(&addr, hostname, sizeof(hostname));
        DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname));
      }
    }

    return (http_sspi_server(http, hostname));
  }
}


/*
 * '_httpTLSStop()' - Shut down SSL/TLS on a connection.
 */

void
_httpTLSStop(http_t *http)		/* I - HTTP connection */
{
  _http_sspi_t	*sspi = http->tls;	/* SSPI data */


  if (sspi->contextInitialized && http->fd >= 0)
  {
    SecBufferDesc	message;	/* Array of SecBuffer struct */
    SecBuffer		buffers[1] = { 0 };
					/* Security package buffer */
    DWORD		dwType;		/* Type */
    DWORD		status;		/* Status */

  /*
   * Notify schannel that we are about to close the connection.
   */

   dwType = SCHANNEL_SHUTDOWN;

   buffers[0].pvBuffer   = &dwType;
   buffers[0].BufferType = SECBUFFER_TOKEN;
   buffers[0].cbBuffer   = sizeof(dwType);

   message.cBuffers  = 1;
   message.pBuffers  = buffers;
   message.ulVersion = SECBUFFER_VERSION;

   status = ApplyControlToken(&sspi->context, &message);

   if (SUCCEEDED(status))
   {
     PBYTE	pbMessage;		/* Message buffer */
     DWORD	cbMessage;		/* Message buffer count */
     DWORD	cbData;			/* Data count */
     DWORD	dwSSPIFlags;		/* SSL attributes we requested */
     DWORD	dwSSPIOutFlags;		/* SSL attributes we received */
     TimeStamp	tsExpiry;		/* Time stamp */

     dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT     |
                   ASC_REQ_REPLAY_DETECT       |
                   ASC_REQ_CONFIDENTIALITY     |
                   ASC_REQ_EXTENDED_ERROR      |
                   ASC_REQ_ALLOCATE_MEMORY     |
                   ASC_REQ_STREAM;

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

     message.cBuffers  = 1;
     message.pBuffers  = buffers;
     message.ulVersion = SECBUFFER_VERSION;

     status = AcceptSecurityContext(&sspi->creds, &sspi->context, NULL,
                                    dwSSPIFlags, SECURITY_NATIVE_DREP, NULL,
                                    &message, &dwSSPIOutFlags, &tsExpiry);

      if (SUCCEEDED(status))
      {
        pbMessage = buffers[0].pvBuffer;
        cbMessage = buffers[0].cbBuffer;

       /*
        * Send the close notify message to the client.
        */

        if (pbMessage && cbMessage)
        {
          cbData = send(http->fd, pbMessage, cbMessage, 0);
          if ((cbData == SOCKET_ERROR) || (cbData == 0))
          {
            status = WSAGetLastError();
            DEBUG_printf(("_httpTLSStop: sending close notify failed: %d", status));
          }
          else
          {
            FreeContextBuffer(pbMessage);
          }
        }
      }
      else
      {
        DEBUG_printf(("_httpTLSStop: AcceptSecurityContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), status)));
      }
    }
    else
    {
      DEBUG_printf(("_httpTLSStop: ApplyControlToken failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), status)));
    }
  }

  http_sspi_free(sspi);

  http->tls = NULL;
}


/*
 * '_httpTLSWrite()' - Write to a SSL/TLS connection.
 */

int					/* O - Bytes written */
_httpTLSWrite(http_t     *http,		/* I - HTTP connection */
	      const char *buf,		/* I - Buffer holding data */
	      int        len)		/* I - Length of buffer */
{
  _http_sspi_t	*sspi = http->tls;	/* SSPI data */
  SecBufferDesc	message;		/* Array of SecBuffer struct */
  SecBuffer	buffers[4] = { 0 };	/* Security package buffer */
  int		bufferLen;		/* Buffer length */
  int		bytesLeft;		/* Bytes left to write */
  const char	*bufptr;		/* Pointer into buffer */
  int		num = 0;		/* Return value */


  bufferLen = sspi->streamSizes.cbMaximumMessage + sspi->streamSizes.cbHeader + sspi->streamSizes.cbTrailer;

  if (bufferLen > sspi->writeBufferLength)
  {
    BYTE *temp;				/* New buffer pointer */

    if ((temp = (BYTE *)realloc(sspi->writeBuffer, bufferLen)) == NULL)
    {
      DEBUG_printf(("_httpTLSWrite: Unable to allocate buffer of %d bytes.", bufferLen));
      WSASetLastError(E_OUTOFMEMORY);
      return (-1);
    }

    sspi->writeBuffer       = temp;
    sspi->writeBufferLength = bufferLen;
  }

  bytesLeft = len;
  bufptr    = buf;

  while (bytesLeft)
  {
    int chunk = min((int)sspi->streamSizes.cbMaximumMessage, bytesLeft);
					/* Size of data to write */
    SECURITY_STATUS scRet;		/* SSPI status */

   /*
    * Copy user data into the buffer, starting just past the header...
    */

    memcpy(sspi->writeBuffer + sspi->streamSizes.cbHeader, bufptr, chunk);

   /*
    * Setup the SSPI buffers
    */

    message.ulVersion = SECBUFFER_VERSION;
    message.cBuffers  = 4;
    message.pBuffers  = buffers;

    buffers[0].pvBuffer   = sspi->writeBuffer;
    buffers[0].cbBuffer   = sspi->streamSizes.cbHeader;
    buffers[0].BufferType = SECBUFFER_STREAM_HEADER;
    buffers[1].pvBuffer   = sspi->writeBuffer + sspi->streamSizes.cbHeader;
    buffers[1].cbBuffer   = (unsigned long) chunk;
    buffers[1].BufferType = SECBUFFER_DATA;
    buffers[2].pvBuffer   = sspi->writeBuffer + sspi->streamSizes.cbHeader + chunk;
    buffers[2].cbBuffer   = sspi->streamSizes.cbTrailer;
    buffers[2].BufferType = SECBUFFER_STREAM_TRAILER;
    buffers[3].BufferType = SECBUFFER_EMPTY;

   /*
    * Encrypt the data
    */

    scRet = EncryptMessage(&sspi->context, 0, &message, 0);

    if (FAILED(scRet))
    {
      DEBUG_printf(("_httpTLSWrite: EncryptMessage failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      WSASetLastError(WSASYSCALLFAILURE);
      return (-1);
    }

   /*
    * Send the data. Remember the size of the total data to send is the size
    * of the header, the size of the data the caller passed in and the size
    * of the trailer...
    */

    num = send(http->fd, sspi->writeBuffer, buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer, 0);

    if (num <= 0)
    {
      DEBUG_printf(("_httpTLSWrite: send failed: %ld", WSAGetLastError()));
      return (num);
    }

    bytesLeft -= chunk;
    bufptr    += chunk;
  }

  return (len);
}


#if 0
/*
 * 'http_setup_ssl()' - Set up SSL/TLS support on a connection.
 */

static int				/* O - 0 on success, -1 on failure */
http_setup_ssl(http_t *http)		/* I - Connection to server */
{
  char			hostname[256],	/* Hostname */
			*hostptr;	/* Pointer into hostname */

  TCHAR			username[256];	/* Username returned from GetUserName() */
  TCHAR			commonName[256];/* Common name for certificate */
  DWORD			dwSize;		/* 32 bit size */


  DEBUG_printf(("7http_setup_ssl(http=%p)", http));

 /*
  * Get the hostname to use for SSL...
  */

  if (httpAddrLocalhost(http->hostaddr))
  {
    strlcpy(hostname, "localhost", sizeof(hostname));
  }
  else
  {
   /*
    * Otherwise make sure the hostname we have does not end in a trailing dot.
    */

    strlcpy(hostname, http->hostname, sizeof(hostname));
    if ((hostptr = hostname + strlen(hostname) - 1) >= hostname &&
        *hostptr == '.')
      *hostptr = '\0';
  }

  http->tls = http_sspi_alloc();

  if (!http->tls)
  {
    _cupsSetHTTPError(HTTP_STATUS_ERROR);
    return (-1);
  }

  dwSize          = sizeof(username) / sizeof(TCHAR);
  GetUserName(username, &dwSize);
  _sntprintf_s(commonName, sizeof(commonName) / sizeof(TCHAR),
               sizeof(commonName) / sizeof(TCHAR), TEXT("CN=%s"), username);

  if (!_sspiGetCredentials(http->tls, L"ClientContainer",
                           commonName, FALSE))
  {
    _sspiFree(http->tls);
    http->tls = NULL;

    http->error  = EIO;
    http->status = HTTP_STATUS_ERROR;

    _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI,
                  _("Unable to establish a secure connection to host."), 1);

    return (-1);
  }

  _sspiSetAllowsAnyRoot(http->tls, TRUE);
  _sspiSetAllowsExpiredCerts(http->tls, TRUE);

  if (!_sspiConnect(http->tls, hostname))
  {
    _sspiFree(http->tls);
    http->tls = NULL;

    http->error  = EIO;
    http->status = HTTP_STATUS_ERROR;

    _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI,
                  _("Unable to establish a secure connection to host."), 1);

    return (-1);
  }

  return (0);
}
#endif // 0


/*
 * 'http_sspi_alloc()' - Allocate SSPI object.
 */

static _http_sspi_t *			/* O  - New SSPI/SSL object */
http_sspi_alloc(void)
{
  return ((_http_sspi_t *)calloc(sizeof(_http_sspi_t), 1));
}


/*
 * 'http_sspi_client()' - Negotiate a TLS connection as a client.
 */

static int				/* O - 0 on success, -1 on failure */
http_sspi_client(http_t     *http,	/* I - Client connection */
                 const char *hostname)	/* I - Server hostname */
{
  _http_sspi_t	*sspi = http->tls;	/* SSPI data */
  DWORD		dwSize;			/* Size for buffer */
  DWORD		dwSSPIFlags;		/* SSL connection attributes we want */
  DWORD		dwSSPIOutFlags;		/* SSL connection attributes we got */
  TimeStamp	tsExpiry;		/* Time stamp */
  SECURITY_STATUS scRet;		/* Status */
  int		cbData;			/* Data count */
  SecBufferDesc	inBuffer;		/* Array of SecBuffer structs */
  SecBuffer	inBuffers[2];		/* Security package buffer */
  SecBufferDesc	outBuffer;		/* Array of SecBuffer structs */
  SecBuffer	outBuffers[1];		/* Security package buffer */
  int		ret = 0;		/* Return value */
  char		username[1024],		/* Current username */
		common_name[1024];	/* CN=username */


  DEBUG_printf(("4http_sspi_client(http=%p, hostname=\"%s\")", http, hostname));

  dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT   |
                ISC_REQ_REPLAY_DETECT     |
                ISC_REQ_CONFIDENTIALITY   |
                ISC_RET_EXTENDED_ERROR    |
                ISC_REQ_ALLOCATE_MEMORY   |
                ISC_REQ_STREAM;

 /*
  * Lookup the client certificate...
  */

  dwSize = sizeof(username);
  GetUserName(username, &dwSize);
  snprintf(common_name, sizeof(common_name), "CN=%s", username);

  if (!http_sspi_find_credentials(http, L"ClientContainer", common_name))
    if (!http_sspi_make_credentials(http->tls, L"ClientContainer", common_name, _HTTP_MODE_CLIENT, 10))
    {
      DEBUG_puts("5http_sspi_client: Unable to get client credentials.");
      return (-1);
    }

 /*
  * Initiate a ClientHello message and generate a token.
  */

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

  outBuffer.cBuffers  = 1;
  outBuffer.pBuffers  = outBuffers;
  outBuffer.ulVersion = SECBUFFER_VERSION;

  scRet = InitializeSecurityContext(&sspi->creds, NULL, TEXT(""), dwSSPIFlags, 0, SECURITY_NATIVE_DREP, NULL, 0, &sspi->context, &outBuffer, &dwSSPIOutFlags, &tsExpiry);

  if (scRet != SEC_I_CONTINUE_NEEDED)
  {
    DEBUG_printf(("5http_sspi_client: InitializeSecurityContext(1) failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
    return (-1);
  }

 /*
  * Send response to server if there is one.
  */

  if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer)
  {
    if ((cbData = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0)) <= 0)
    {
      DEBUG_printf(("5http_sspi_client: send failed: %d", WSAGetLastError()));
      FreeContextBuffer(outBuffers[0].pvBuffer);
      DeleteSecurityContext(&sspi->context);
      return (-1);
    }

    DEBUG_printf(("5http_sspi_client: %d bytes of handshake data sent.", cbData));

    FreeContextBuffer(outBuffers[0].pvBuffer);
    outBuffers[0].pvBuffer = NULL;
  }

  dwSSPIFlags = ISC_REQ_MANUAL_CRED_VALIDATION |
		ISC_REQ_SEQUENCE_DETECT        |
                ISC_REQ_REPLAY_DETECT          |
                ISC_REQ_CONFIDENTIALITY        |
                ISC_RET_EXTENDED_ERROR         |
                ISC_REQ_ALLOCATE_MEMORY        |
                ISC_REQ_STREAM;

  sspi->decryptBufferUsed = 0;

 /*
  * Loop until the handshake is finished or an error occurs.
  */

  scRet = SEC_I_CONTINUE_NEEDED;

  while(scRet == SEC_I_CONTINUE_NEEDED        ||
        scRet == SEC_E_INCOMPLETE_MESSAGE     ||
        scRet == SEC_I_INCOMPLETE_CREDENTIALS)
  {
    if (sspi->decryptBufferUsed == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE)
    {
      if (sspi->decryptBufferLength <= sspi->decryptBufferUsed)
      {
	BYTE *temp;			/* New buffer */

	if (sspi->decryptBufferLength >= 262144)
	{
	  WSASetLastError(E_OUTOFMEMORY);
	  DEBUG_puts("5http_sspi_client: Decryption buffer too large (>256k)");
	  return (-1);
	}

	if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL)
	{
	  DEBUG_printf(("5http_sspi_client: Unable to allocate %d byte buffer.", sspi->decryptBufferLength + 4096));
	  WSASetLastError(E_OUTOFMEMORY);
	  return (-1);
	}

	sspi->decryptBufferLength += 4096;
	sspi->decryptBuffer       = temp;
      }

      cbData = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0);

      if (cbData < 0)
      {
        DEBUG_printf(("5http_sspi_client: recv failed: %d", WSAGetLastError()));
        return (-1);
      }
      else if (cbData == 0)
      {
        DEBUG_printf(("5http_sspi_client: Server unexpectedly disconnected."));
        return (-1);
      }

      DEBUG_printf(("5http_sspi_client: %d bytes of handshake data received", cbData));

      sspi->decryptBufferUsed += cbData;
    }

   /*
    * Set up the input buffers. Buffer 0 is used to pass in data received from
    * the server.  Schannel will consume some or all of this.  Leftover data
    * (if any) will be placed in buffer 1 and given a buffer type of
    * SECBUFFER_EXTRA.
    */

    inBuffers[0].pvBuffer   = sspi->decryptBuffer;
    inBuffers[0].cbBuffer   = (unsigned long)sspi->decryptBufferUsed;
    inBuffers[0].BufferType = SECBUFFER_TOKEN;

    inBuffers[1].pvBuffer   = NULL;
    inBuffers[1].cbBuffer   = 0;
    inBuffers[1].BufferType = SECBUFFER_EMPTY;

    inBuffer.cBuffers       = 2;
    inBuffer.pBuffers       = inBuffers;
    inBuffer.ulVersion      = SECBUFFER_VERSION;

   /*
    * Set up the output buffers. These are initialized to NULL so as to make it
    * less likely we'll attempt to free random garbage later.
    */

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

    outBuffer.cBuffers       = 1;
    outBuffer.pBuffers       = outBuffers;
    outBuffer.ulVersion      = SECBUFFER_VERSION;

   /*
    * Call InitializeSecurityContext.
    */

    scRet = InitializeSecurityContext(&sspi->creds, &sspi->context, NULL, dwSSPIFlags, 0, SECURITY_NATIVE_DREP, &inBuffer, 0, NULL, &outBuffer, &dwSSPIOutFlags, &tsExpiry);

   /*
    * If InitializeSecurityContext was successful (or if the error was one of
    * the special extended ones), send the contents of the output buffer to the
    * server.
    */

    if (scRet == SEC_E_OK                ||
        scRet == SEC_I_CONTINUE_NEEDED   ||
        FAILED(scRet) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR))
    {
      if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer)
      {
        cbData = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0);

        if (cbData <= 0)
        {
          DEBUG_printf(("5http_sspi_client: send failed: %d", WSAGetLastError()));
          FreeContextBuffer(outBuffers[0].pvBuffer);
          DeleteSecurityContext(&sspi->context);
          return (-1);
        }

        DEBUG_printf(("5http_sspi_client: %d bytes of handshake data sent.", cbData));

       /*
        * Free output buffer.
        */

        FreeContextBuffer(outBuffers[0].pvBuffer);
        outBuffers[0].pvBuffer = NULL;
      }
    }

   /*
    * If InitializeSecurityContext returned SEC_E_INCOMPLETE_MESSAGE, then we
    * need to read more data from the server and try again.
    */

    if (scRet == SEC_E_INCOMPLETE_MESSAGE)
      continue;

   /*
    * If InitializeSecurityContext returned SEC_E_OK, then the handshake
    * completed successfully.
    */

    if (scRet == SEC_E_OK)
    {
     /*
      * If the "extra" buffer contains data, this is encrypted application
      * protocol layer stuff. It needs to be saved. The application layer will
      * later decrypt it with DecryptMessage.
      */

      DEBUG_puts("5http_sspi_client: Handshake was successful.");

      if (inBuffers[1].BufferType == SECBUFFER_EXTRA)
      {
        memmove(sspi->decryptBuffer, sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer, inBuffers[1].cbBuffer);

        sspi->decryptBufferUsed = inBuffers[1].cbBuffer;

        DEBUG_printf(("5http_sspi_client: %d bytes of app data was bundled with handshake data", sspi->decryptBufferUsed));
      }
      else
        sspi->decryptBufferUsed = 0;

     /*
      * Bail out to quit
      */

      break;
    }

   /*
    * Check for fatal error.
    */

    if (FAILED(scRet))
    {
      DEBUG_printf(("5http_sspi_client: InitializeSecurityContext(2) failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      ret = -1;
      break;
    }

   /*
    * If InitializeSecurityContext returned SEC_I_INCOMPLETE_CREDENTIALS,
    * then the server just requested client authentication.
    */

    if (scRet == SEC_I_INCOMPLETE_CREDENTIALS)
    {
     /*
      * Unimplemented
      */

      DEBUG_printf(("5http_sspi_client: server requested client credentials."));
      ret = -1;
      break;
    }

   /*
    * Copy any leftover data from the "extra" buffer, and go around again.
    */

    if (inBuffers[1].BufferType == SECBUFFER_EXTRA)
    {
      memmove(sspi->decryptBuffer, sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer, inBuffers[1].cbBuffer);

      sspi->decryptBufferUsed = inBuffers[1].cbBuffer;
    }
    else
    {
      sspi->decryptBufferUsed = 0;
    }
  }

  if (!ret)
  {
   /*
    * Success!  Get the server cert
    */

    sspi->contextInitialized = TRUE;

    scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (VOID *)&(sspi->remoteCert));

    if (scRet != SEC_E_OK)
    {
      DEBUG_printf(("5http_sspi_client: QueryContextAttributes failed(SECPKG_ATTR_REMOTE_CERT_CONTEXT): %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      return (-1);
    }

   /*
    * Find out how big the header/trailer will be:
    */

    scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_STREAM_SIZES, &sspi->streamSizes);

    if (scRet != SEC_E_OK)
    {
      DEBUG_printf(("5http_sspi_client: QueryContextAttributes failed(SECPKG_ATTR_STREAM_SIZES): %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      ret = -1;
    }
  }

  return (ret);
}


/*
 * 'http_sspi_create_credential()' - Create an SSPI certificate context.
 */

static PCCERT_CONTEXT			/* O - Certificate context */
http_sspi_create_credential(
    http_credential_t *cred)		/* I - Credential */
{
  if (cred)
    return (CertCreateCertificateContext(X509_ASN_ENCODING, cred->data, cred->datalen));
  else
    return (NULL);
}


/*
 * 'http_sspi_find_credentials()' - Retrieve a TLS certificate from the system store.
 */

static BOOL				/* O - 1 on success, 0 on failure */
http_sspi_find_credentials(
    http_t       *http,			/* I - HTTP connection */
    const LPWSTR container,		/* I - Cert container name */
    const char   *common_name)		/* I - Common name of certificate */
{
  _http_sspi_t	*sspi = http->tls;	/* SSPI data */
  HCERTSTORE	store = NULL;		/* Certificate store */
  PCCERT_CONTEXT storedContext = NULL;	/* Context created from the store */
  DWORD		dwSize = 0; 		/* 32 bit size */
  PBYTE		p = NULL;		/* Temporary storage */
  HCRYPTPROV	hProv = (HCRYPTPROV)NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB sib;			/* Arbitrary array of bytes */
  SCHANNEL_CRED	SchannelCred;		/* Schannel credential data */
  TimeStamp	tsExpiry;		/* Time stamp */
  SECURITY_STATUS Status;		/* Status */
  BOOL		ok = TRUE;		/* Return value */


  if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("5http_sspi_find_credentials: CryptAcquireContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
        ok = FALSE;
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY");

  if (!store)
  {
    DEBUG_printf(("5http_sspi_find_credentials: CertOpenSystemStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  p = (PBYTE)malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("5http_sspi_find_credentials: malloc failed for %d bytes.", dwSize));
    ok = FALSE;
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL))
  {
    DEBUG_printf(("5http_sspi_find_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  sib.cbData = dwSize;
  sib.pbData = p;

  storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL);

  if (!storedContext)
  {
    DEBUG_printf(("5http_sspi_find_credentials: Unable to find credentials for \"%s\".", common_name));
    ok = FALSE;
    goto cleanup;
  }

  ZeroMemory(&SchannelCred, sizeof(SchannelCred));

  SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
  SchannelCred.cCreds    = 1;
  SchannelCred.paCred    = &storedContext;

 /*
  * Set supported protocols (can also be overriden in the registry...)
  */

#ifdef SP_PROT_TLS1_2_SERVER
  if (http->mode == _HTTP_MODE_SERVER)
  {
    if (tls_options & _HTTP_TLS_DENY_TLS10)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER;
    else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER | SP_PROT_SSL3_SERVER;
    else
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_SERVER | SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_0_SERVER;
  }
  else
  {
    if (tls_options & _HTTP_TLS_DENY_TLS10)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT;
    else if (tls_options & _HTTP_TLS_ALLOW_SSL3)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT | SP_PROT_SSL3_CLIENT;
    else
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_0_CLIENT;
  }

#else
  if (http->mode == _HTTP_MODE_SERVER)
  {
    if (tls_options & _HTTP_TLS_ALLOW_SSL3)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER;
    else
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_SERVER;
  }
  else
  {
    if (tls_options & _HTTP_TLS_ALLOW_SSL3)
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT | SP_PROT_SSL3_CLIENT;
    else
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_CLIENT;
  }
#endif /* SP_PROT_TLS1_2_SERVER */

  /* TODO: Support _HTTP_TLS_ALLOW_RC4, _HTTP_TLS_ALLOW_DH, and _HTTP_TLS_DENY_CBC options; right now we'll rely on Windows registry to enable/disable RC4/DH/CBC... */

 /*
  * Create an SSPI credential.
  */

  Status = AcquireCredentialsHandle(NULL, UNISP_NAME, http->mode == _HTTP_MODE_SERVER ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &sspi->creds, &tsExpiry);
  if (Status != SEC_E_OK)
  {
    DEBUG_printf(("5http_sspi_find_credentials: AcquireCredentialsHandle failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), Status)));
    ok = FALSE;
    goto cleanup;
  }

cleanup:

 /*
  * Cleanup
  */

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  return (ok);
}


/*
 * 'http_sspi_free()' - Close a connection and free resources.
 */

static void
http_sspi_free(_http_sspi_t *sspi)	/* I - SSPI data */
{
  if (!sspi)
    return;

  if (sspi->contextInitialized)
    DeleteSecurityContext(&sspi->context);

  if (sspi->decryptBuffer)
    free(sspi->decryptBuffer);

  if (sspi->readBuffer)
    free(sspi->readBuffer);

  if (sspi->writeBuffer)
    free(sspi->writeBuffer);

  if (sspi->localCert)
    CertFreeCertificateContext(sspi->localCert);

  if (sspi->remoteCert)
    CertFreeCertificateContext(sspi->remoteCert);

  free(sspi);
}


/*
 * 'http_sspi_make_credentials()' - Create a TLS certificate in the system store.
 */

static BOOL				/* O - 1 on success, 0 on failure */
http_sspi_make_credentials(
    _http_sspi_t *sspi,			/* I - SSPI data */
    const LPWSTR container,		/* I - Cert container name */
    const char   *common_name,		/* I - Common name of certificate */
    _http_mode_t mode,			/* I - Client or server? */
    int          years)			/* I - Years until expiration */
{
  HCERTSTORE	store = NULL;		/* Certificate store */
  PCCERT_CONTEXT storedContext = NULL;	/* Context created from the store */
  PCCERT_CONTEXT createdContext = NULL;	/* Context created by us */
  DWORD		dwSize = 0; 		/* 32 bit size */
  PBYTE		p = NULL;		/* Temporary storage */
  HCRYPTPROV	hProv = (HCRYPTPROV)NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB sib;			/* Arbitrary array of bytes */
  SCHANNEL_CRED	SchannelCred;		/* Schannel credential data */
  TimeStamp	tsExpiry;		/* Time stamp */
  SECURITY_STATUS Status;		/* Status */
  HCRYPTKEY	hKey = (HCRYPTKEY)NULL;	/* Handle to crypto key */
  CRYPT_KEY_PROV_INFO kpi;		/* Key container info */
  SYSTEMTIME	et;			/* System time */
  CERT_EXTENSIONS exts;			/* Array of cert extensions */
  CRYPT_KEY_PROV_INFO ckp;		/* Handle to crypto key */
  BOOL		ok = TRUE;		/* Return value */


  DEBUG_printf(("4http_sspi_make_credentials(sspi=%p, container=%p, common_name=\"%s\", mode=%d, years=%d)", sspi, container, common_name, mode, years));

  if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, (LPWSTR)container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("5http_sspi_make_credentials: CryptAcquireContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
        ok = FALSE;
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY");

  if (!store)
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertOpenSystemStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  p = (PBYTE)malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("5http_sspi_make_credentials: malloc failed for %d bytes", dwSize));
    ok = FALSE;
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, common_name, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL))
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertStrToName failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

 /*
  * Create a private key and self-signed certificate...
  */

  if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
  {
    DEBUG_printf(("5http_sspi_make_credentials: CryptGenKey failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  ZeroMemory(&kpi, sizeof(kpi));
  kpi.pwszContainerName = (LPWSTR)container;
  kpi.pwszProvName      = MS_DEF_PROV_W;
  kpi.dwProvType        = PROV_RSA_FULL;
  kpi.dwFlags           = CERT_SET_KEY_CONTEXT_PROP_ID;
  kpi.dwKeySpec         = AT_KEYEXCHANGE;

  GetSystemTime(&et);
  et.wYear += years;

  ZeroMemory(&exts, sizeof(exts));

  createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, &et, &exts);

  if (!createdContext)
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertCreateSelfSignCertificate failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

 /*
  * Add the created context to the named store, and associate it with the named
  * container...
  */

  if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext))
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertAddCertificateContextToStore failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

  ZeroMemory(&ckp, sizeof(ckp));
  ckp.pwszContainerName = (LPWSTR) container;
  ckp.pwszProvName      = MS_DEF_PROV_W;
  ckp.dwProvType        = PROV_RSA_FULL;
  ckp.dwFlags           = CRYPT_MACHINE_KEYSET;
  ckp.dwKeySpec         = AT_KEYEXCHANGE;

  if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp))
  {
    DEBUG_printf(("5http_sspi_make_credentials: CertSetCertificateContextProperty failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), GetLastError())));
    ok = FALSE;
    goto cleanup;
  }

 /*
  * Get a handle to use the certificate...
  */

  ZeroMemory(&SchannelCred, sizeof(SchannelCred));

  SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
  SchannelCred.cCreds    = 1;
  SchannelCred.paCred    = &storedContext;

 /*
  * SSPI doesn't seem to like it if grbitEnabledProtocols is set for a client.
  */

  if (mode == _HTTP_MODE_SERVER)
    SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1;

 /*
  * Create an SSPI credential.
  */

  Status = AcquireCredentialsHandle(NULL, UNISP_NAME, mode == _HTTP_MODE_SERVER ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &sspi->creds, &tsExpiry);
  if (Status != SEC_E_OK)
  {
    DEBUG_printf(("5http_sspi_make_credentials: AcquireCredentialsHandle failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), Status)));
    ok = FALSE;
    goto cleanup;
  }

cleanup:

 /*
  * Cleanup
  */

  if (hKey)
    CryptDestroyKey(hKey);

  if (createdContext)
    CertFreeCertificateContext(createdContext);

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  return (ok);
}


/*
 * 'http_sspi_server()' - Negotiate a TLS connection as a server.
 */

static int				/* O - 0 on success, -1 on failure */
http_sspi_server(http_t     *http,	/* I - HTTP connection */
                 const char *hostname)	/* I - Hostname of server */
{
  _http_sspi_t	*sspi = http->tls;	/* I - SSPI data */
  char		common_name[512];	/* Common name for cert */
  DWORD		dwSSPIFlags;		/* SSL connection attributes we want */
  DWORD		dwSSPIOutFlags;		/* SSL connection attributes we got */
  TimeStamp	tsExpiry;		/* Time stamp */
  SECURITY_STATUS scRet;		/* SSPI Status */
  SecBufferDesc	inBuffer;		/* Array of SecBuffer structs */
  SecBuffer	inBuffers[2];		/* Security package buffer */
  SecBufferDesc	outBuffer;		/* Array of SecBuffer structs */
  SecBuffer	outBuffers[1];		/* Security package buffer */
  int		num = 0;		/* 32 bit status value */
  BOOL		fInitContext = TRUE;	/* Has the context been init'd? */
  int		ret = 0;		/* Return value */


  DEBUG_printf(("4http_sspi_server(http=%p, hostname=\"%s\")", http, hostname));

  dwSSPIFlags = ASC_REQ_SEQUENCE_DETECT  |
                ASC_REQ_REPLAY_DETECT    |
                ASC_REQ_CONFIDENTIALITY  |
                ASC_REQ_EXTENDED_ERROR   |
                ASC_REQ_ALLOCATE_MEMORY  |
                ASC_REQ_STREAM;

  sspi->decryptBufferUsed = 0;

 /*
  * Lookup the server certificate...
  */

  snprintf(common_name, sizeof(common_name), "CN=%s", hostname);

  if (!http_sspi_find_credentials(http, L"ServerContainer", common_name))
    if (!http_sspi_make_credentials(http->tls, L"ServerContainer", common_name, _HTTP_MODE_SERVER, 10))
    {
      DEBUG_puts("5http_sspi_server: Unable to get server credentials.");
      return (-1);
    }

 /*
  * Set OutBuffer for AcceptSecurityContext call
  */

  outBuffer.cBuffers  = 1;
  outBuffer.pBuffers  = outBuffers;
  outBuffer.ulVersion = SECBUFFER_VERSION;

  scRet = SEC_I_CONTINUE_NEEDED;

  while (scRet == SEC_I_CONTINUE_NEEDED    ||
         scRet == SEC_E_INCOMPLETE_MESSAGE ||
         scRet == SEC_I_INCOMPLETE_CREDENTIALS)
  {
    if (sspi->decryptBufferUsed == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE)
    {
      if (sspi->decryptBufferLength <= sspi->decryptBufferUsed)
      {
	BYTE *temp;			/* New buffer */

	if (sspi->decryptBufferLength >= 262144)
	{
	  WSASetLastError(E_OUTOFMEMORY);
	  DEBUG_puts("5http_sspi_server: Decryption buffer too large (>256k)");
	  return (-1);
	}

	if ((temp = realloc(sspi->decryptBuffer, sspi->decryptBufferLength + 4096)) == NULL)
	{
	  DEBUG_printf(("5http_sspi_server: Unable to allocate %d byte buffer.", sspi->decryptBufferLength + 4096));
	  WSASetLastError(E_OUTOFMEMORY);
	  return (-1);
	}

	sspi->decryptBufferLength += 4096;
	sspi->decryptBuffer       = temp;
      }

      for (;;)
      {
        num = recv(http->fd, sspi->decryptBuffer + sspi->decryptBufferUsed, (int)(sspi->decryptBufferLength - sspi->decryptBufferUsed), 0);

        if (num == -1 && WSAGetLastError() == WSAEWOULDBLOCK)
          Sleep(1);
        else
          break;
      }

      if (num < 0)
      {
        DEBUG_printf(("5http_sspi_server: recv failed: %d", WSAGetLastError()));
        return (-1);
      }
      else if (num == 0)
      {
        DEBUG_puts("5http_sspi_server: client disconnected");
        return (-1);
      }

      DEBUG_printf(("5http_sspi_server: received %d (handshake) bytes from client.", num));
      sspi->decryptBufferUsed += num;
    }

   /*
    * InBuffers[1] is for getting extra data that SSPI/SCHANNEL doesn't process
    * on this run around the loop.
    */

    inBuffers[0].pvBuffer   = sspi->decryptBuffer;
    inBuffers[0].cbBuffer   = (unsigned long)sspi->decryptBufferUsed;
    inBuffers[0].BufferType = SECBUFFER_TOKEN;

    inBuffers[1].pvBuffer   = NULL;
    inBuffers[1].cbBuffer   = 0;
    inBuffers[1].BufferType = SECBUFFER_EMPTY;

    inBuffer.cBuffers       = 2;
    inBuffer.pBuffers       = inBuffers;
    inBuffer.ulVersion      = SECBUFFER_VERSION;

   /*
    * Initialize these so if we fail, pvBuffer contains NULL, so we don't try to
    * free random garbage at the quit.
    */

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

    scRet = AcceptSecurityContext(&sspi->creds, (fInitContext?NULL:&sspi->context), &inBuffer, dwSSPIFlags, SECURITY_NATIVE_DREP, (fInitContext?&sspi->context:NULL), &outBuffer, &dwSSPIOutFlags, &tsExpiry);

    fInitContext = FALSE;

    if (scRet == SEC_E_OK              ||
        scRet == SEC_I_CONTINUE_NEEDED ||
        (FAILED(scRet) && ((dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR) != 0)))
    {
      if (outBuffers[0].cbBuffer && outBuffers[0].pvBuffer)
      {
       /*
        * Send response to server if there is one.
        */

        num = send(http->fd, outBuffers[0].pvBuffer, outBuffers[0].cbBuffer, 0);

        if (num <= 0)
        {
          DEBUG_printf(("5http_sspi_server: handshake send failed: %d", WSAGetLastError()));
	  return (-1);
        }

        DEBUG_printf(("5http_sspi_server: sent %d handshake bytes to client.", outBuffers[0].cbBuffer));

        FreeContextBuffer(outBuffers[0].pvBuffer);
        outBuffers[0].pvBuffer = NULL;
      }
    }

    if (scRet == SEC_E_OK)
    {
     /*
      * If there's extra data then save it for next time we go to decrypt.
      */

      if (inBuffers[1].BufferType == SECBUFFER_EXTRA)
      {
        memcpy(sspi->decryptBuffer, (LPBYTE)(sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer), inBuffers[1].cbBuffer);
        sspi->decryptBufferUsed = inBuffers[1].cbBuffer;
      }
      else
      {
        sspi->decryptBufferUsed = 0;
      }
      break;
    }
    else if (FAILED(scRet) && scRet != SEC_E_INCOMPLETE_MESSAGE)
    {
      DEBUG_printf(("5http_sspi_server: AcceptSecurityContext failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      ret = -1;
      break;
    }

    if (scRet != SEC_E_INCOMPLETE_MESSAGE &&
        scRet != SEC_I_INCOMPLETE_CREDENTIALS)
    {
      if (inBuffers[1].BufferType == SECBUFFER_EXTRA)
      {
        memcpy(sspi->decryptBuffer, (LPBYTE)(sspi->decryptBuffer + sspi->decryptBufferUsed - inBuffers[1].cbBuffer), inBuffers[1].cbBuffer);
        sspi->decryptBufferUsed = inBuffers[1].cbBuffer;
      }
      else
      {
        sspi->decryptBufferUsed = 0;
      }
    }
  }

  if (!ret)
  {
    sspi->contextInitialized = TRUE;

   /*
    * Find out how big the header will be:
    */

    scRet = QueryContextAttributes(&sspi->context, SECPKG_ATTR_STREAM_SIZES, &sspi->streamSizes);

    if (scRet != SEC_E_OK)
    {
      DEBUG_printf(("5http_sspi_server: QueryContextAttributes failed: %s", http_sspi_strerror(sspi->error, sizeof(sspi->error), scRet)));
      ret = -1;
    }
  }

  return (ret);
}


/*
 * 'http_sspi_strerror()' - Return a string for the specified error code.
 */

static const char *			/* O - String for error */
http_sspi_strerror(char   *buffer,	/* I - Error message buffer */
                   size_t bufsize,	/* I - Size of buffer */
                   DWORD  code)		/* I - Error code */
{
  if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, code, 0, buffer, bufsize, NULL))
  {
   /*
    * Strip trailing CR + LF...
    */

    char	*ptr;			/* Pointer into error message */

    for (ptr = buffer + strlen(buffer) - 1; ptr >= buffer; ptr --)
      if (*ptr == '\n' || *ptr == '\r')
        *ptr = '\0';
      else
        break;
  }
  else
    snprintf(buffer, bufsize, "Unknown error %x", code);

  return (buffer);
}


/*
 * 'http_sspi_verify()' - Verify a certificate.
 */

static DWORD				/* O - Error code (0 == No error) */
http_sspi_verify(
    PCCERT_CONTEXT cert,		/* I - Server certificate */
    const char     *common_name,	/* I - Common name */
    DWORD          dwCertFlags)		/* I - Verification flags */
{
  HTTPSPolicyCallbackData httpsPolicy;	/* HTTPS Policy Struct */
  CERT_CHAIN_POLICY_PARA policyPara;	/* Cert chain policy parameters */
  CERT_CHAIN_POLICY_STATUS policyStatus;/* Cert chain policy status */
  CERT_CHAIN_PARA	chainPara;	/* Used for searching and matching criteria */
  PCCERT_CHAIN_CONTEXT	chainContext = NULL;
					/* Certificate chain */
  PWSTR			commonNameUnicode = NULL;
					/* Unicode common name */
  LPSTR			rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH,
                                         szOID_SERVER_GATED_CRYPTO,
                                         szOID_SGC_NETSCAPE };
					/* How are we using this certificate? */
  DWORD			cUsages = sizeof(rgszUsages) / sizeof(LPSTR);
					/* Number of ites in rgszUsages */
  DWORD			count;		/* 32 bit count variable */
  DWORD			status;		/* Return value */
#ifdef DEBUG
  char			error[1024];	/* Error message string */
#endif /* DEBUG */


  if (!cert)
    return (SEC_E_WRONG_PRINCIPAL);

 /*
  * Convert common name to Unicode.
  */

  if (!common_name || !*common_name)
    return (SEC_E_WRONG_PRINCIPAL);

  count             = MultiByteToWideChar(CP_ACP, 0, common_name, -1, NULL, 0);
  commonNameUnicode = LocalAlloc(LMEM_FIXED, count * sizeof(WCHAR));
  if (!commonNameUnicode)
    return (SEC_E_INSUFFICIENT_MEMORY);

  if (!MultiByteToWideChar(CP_ACP, 0, common_name, -1, commonNameUnicode, count))
  {
    LocalFree(commonNameUnicode);
    return (SEC_E_WRONG_PRINCIPAL);
  }

 /*
  * Build certificate chain.
  */

  ZeroMemory(&chainPara, sizeof(chainPara));

  chainPara.cbSize					= sizeof(chainPara);
  chainPara.RequestedUsage.dwType			= USAGE_MATCH_TYPE_OR;
  chainPara.RequestedUsage.Usage.cUsageIdentifier	= cUsages;
  chainPara.RequestedUsage.Usage.rgpszUsageIdentifier	= rgszUsages;

  if (!CertGetCertificateChain(NULL, cert, NULL, cert->hCertStore, &chainPara, 0, NULL, &chainContext))
  {
    status = GetLastError();

    DEBUG_printf(("CertGetCertificateChain returned: %s", http_sspi_strerror(error, sizeof(error), status)));

    LocalFree(commonNameUnicode);
    return (status);
  }

 /*
  * Validate certificate chain.
  */

  ZeroMemory(&httpsPolicy, sizeof(HTTPSPolicyCallbackData));
  httpsPolicy.cbStruct		= sizeof(HTTPSPolicyCallbackData);
  httpsPolicy.dwAuthType	= AUTHTYPE_SERVER;
  httpsPolicy.fdwChecks		= dwCertFlags;
  httpsPolicy.pwszServerName	= commonNameUnicode;

  memset(&policyPara, 0, sizeof(policyPara));
  policyPara.cbSize		= sizeof(policyPara);
  policyPara.pvExtraPolicyPara	= &httpsPolicy;

  memset(&policyStatus, 0, sizeof(policyStatus));
  policyStatus.cbSize = sizeof(policyStatus);

  if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chainContext, &policyPara, &policyStatus))
  {
    status = GetLastError();

    DEBUG_printf(("CertVerifyCertificateChainPolicy returned %s", http_sspi_strerror(error, sizeof(error), status)));
  }
  else if (policyStatus.dwError)
    status = policyStatus.dwError;
  else
    status = SEC_E_OK;

  if (chainContext)
    CertFreeCertificateChain(chainContext);

  if (commonNameUnicode)
    LocalFree(commonNameUnicode);

  return (status);
}
