/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */

/*
 * SChannel is designed to encrypt and decrypt data in place.  So a
 * given buffer is expected to sometimes contain encrypted data,
 * sometimes decrypted data, and occasionally both.  Outgoing buffers
 * need to reserve space for the TLS header and trailer.  Read
 * operations need to ignore the same headers and trailers from
 * incoming buffers.  Outgoing is simple because we choose record
 * boundaries.  Incoming is complicated by handling incomplete TLS
 * records, and buffering contiguous data for the app layer that may
 * span many records.  A lazy double buffering system is used for
 * the latter.
 */

#include "core/autodetect.h"
#include "core/engine-internal.h"
#include "core/logger_private.h"
#include "core/util.h"

#include "platform/platform.h"

#include <proton/ssl.h>
#include <proton/engine.h>

#include <assert.h>
#include <stdio.h>

// security.h needs to see this to distinguish from kernel use.
#include <windows.h>
#define SECURITY_WIN32
#include <security.h>
#include <Schnlsp.h>
#include <WinInet.h>
#undef SECURITY_WIN32

extern "C" {

/** @file
 * SSL/TLS support API.
 *
 * This file contains an SChannel-based implemention of the SSL/TLS API for Windows platforms.
 */

static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, const char *fmt, ...);
static void ssl_log_error(const char *fmt, ...);
static void ssl_log_error_status(HRESULT status, const char *fmt, ...);
static HCERTSTORE open_cert_db(const char *store_name, const char *passwd, int *error);

// Thread support.  Some SChannel objects are shared or ref-counted.
// Consistent with the rest of Proton, we assume a connection (and
// therefore its pn_ssl_t) will not be accessed concurrently by
// multiple threads.
class csguard {
  public:
    csguard(CRITICAL_SECTION *cs) : cs_(cs), set_(true) { EnterCriticalSection(cs_); }
    ~csguard() { if (set_) LeaveCriticalSection(cs_); }
    void release() {
        if (set_) {
            set_ = false;
            LeaveCriticalSection(cs_);
        }
    }
  private:
    LPCRITICAL_SECTION cs_;
    bool set_;
};

/*
 * win_credential_t: SChannel context that must accompany TLS connections.
 *
 * SChannel attempts session resumption for shared CredHandle objects.
 * To mimic openssl behavior, server CredHandle handles must be shared
 * by derived connections, client CredHandle handles must be unique
 * when app's session_id is null and tracked for reuse otherwise
 * (TODO).
 *
 * Ref counted by parent ssl_domain_t and each derived connection.
 */
struct win_credential_t {
  CRITICAL_SECTION cslock;
  pn_ssl_mode_t mode;
  PCCERT_CONTEXT cert_context;  // Particulars of the certificate (if any)
  CredHandle cred_handle;       // Bound session parameters, certificate, CAs, verification_mode
  HCERTSTORE trust_store;       // Store of root CAs for validating
  HCERTSTORE server_CA_certs;   // CAs advertised by server (may be a duplicate of the trust_store)
  char *trust_store_name;
};

#define win_credential_compare NULL
#define win_credential_inspect NULL
#define win_credential_hashcode NULL

static void win_credential_initialize(void *object)
{
  win_credential_t *c = (win_credential_t *) object;
  InitializeCriticalSectionAndSpinCount(&c->cslock, 4000);
  SecInvalidateHandle(&c->cred_handle);
  c->cert_context = 0;
  c->trust_store = 0;
  c->server_CA_certs = 0;
  c->trust_store_name = 0;
}

static void win_credential_finalize(void *object)
{
  win_credential_t *c = (win_credential_t *) object;
  if (SecIsValidHandle(&c->cred_handle))
    FreeCredentialsHandle(&c->cred_handle);
  if (c->cert_context)
    CertFreeCertificateContext(c->cert_context);
  if (c->trust_store)
    CertCloseStore(c->trust_store, 0);
  if (c->server_CA_certs)
    CertCloseStore(c->server_CA_certs, 0);
  DeleteCriticalSection(&c->cslock);
  free(c->trust_store_name);
}

static win_credential_t *win_credential(pn_ssl_mode_t m)
{
  static const pn_cid_t CID_win_credential = CID_pn_void;
  static const pn_class_t clazz = PN_CLASS(win_credential);
  win_credential_t *c = (win_credential_t *) pn_class_new(&clazz, sizeof(win_credential_t));
  c->mode = m;
  csguard g(&c->cslock);
  pn_incref(c);  // See next comment regarding refcounting and locks
  return c;
}

// Hack strategy for Proton object refcounting.  Just hold the lock for incref.
// Use the next two functions for decref, one with, the other without the lock.
// The refcount is artificially bumped by one in win_credential() so that we
// can use refcount == 1 to actually delete (by calling decref one last time).
static bool win_credential_decref(win_credential_t *c)
{
  // Call with lock held.  Caller MUST call win_credential_delete if this returns true.
  return pn_decref(c) == 1;
}

static void win_credential_delete(win_credential_t *c)
{
  // Call without lock held.
  assert(pn_refcount(c) == 1);
  pn_decref(c);
}

static int win_credential_load_cert(win_credential_t *cred, const char *store_name, const char *cert_name, const char *passwd)
{
  if (!store_name)
    return -2;

  int ec = 0;
  HCERTSTORE cert_store = open_cert_db(store_name, passwd, &ec);
  if (!cert_store)
    return ec;

  // find friendly name that matches cert_name, or sole certificate
  PCCERT_CONTEXT tmpctx = NULL;
  PCCERT_CONTEXT found_ctx = NULL;
  int cert_count = 0;
  int name_len = cert_name ? strlen(cert_name) : 0;
  char *fn = name_len ? (char *) malloc(name_len + 1) : 0;
  while (tmpctx = CertEnumCertificatesInStore(cert_store, tmpctx)) {
    cert_count++;
    if (cert_name && *cert_name) {
      DWORD len = CertGetNameString(tmpctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
                                    0, NULL, NULL, 0);
      if (len != name_len + 1)
        continue;
      CertGetNameString(tmpctx, CERT_NAME_FRIENDLY_DISPLAY_TYPE,
                        0, NULL, fn, len);
      if (!strcmp(cert_name, fn)) {
        found_ctx = tmpctx;
        tmpctx= NULL;
        break;
      }
    } else {
      // Test for single certificate
      if (cert_count == 1) {
        found_ctx = CertDuplicateCertificateContext(tmpctx);
      } else {
        ssl_log_error("Multiple certificates to choose from certificate store %s", store_name);
        found_ctx = NULL;
        break;
      }
    }
  }

  if (tmpctx) {
    CertFreeCertificateContext(tmpctx);
    tmpctx = false;
  }
  if (!found_ctx && cert_name && cert_count == 1)
    ssl_log_error("Could not find certificate %s in store %s", cert_name, store_name);
  cred->cert_context = found_ctx;

  free(fn);
  CertCloseStore(cert_store, 0);
  return found_ctx ? 0 : -8;
}


// call with win_credential lock held
static CredHandle win_credential_cred_handle(win_credential_t *cred, const char *session_id, SECURITY_STATUS *status)
{
  if (cred->mode == PN_SSL_MODE_SERVER && SecIsValidHandle(&cred->cred_handle)) {
    *status = SEC_E_OK;
    return cred->cred_handle;  // Server always reuses cached value
  }
  // TODO: if (is_client && session_id != NULL) create or use cached value based on
  // session_id+server_host_name (per domain? reclaimed after X hours?)

  CredHandle tmp_handle;
  SecInvalidateHandle(&tmp_handle);
  TimeStamp expiry;  // Not used
  SCHANNEL_CRED descriptor;
  memset(&descriptor, 0, sizeof(descriptor));

  descriptor.dwVersion = SCHANNEL_CRED_VERSION;
  descriptor.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION;
  if (cred->cert_context != NULL) {
    // assign the certificate into the credentials
    descriptor.paCred = &cred->cert_context;
    descriptor.cCreds = 1;
  }

  if (cred->mode == PN_SSL_MODE_SERVER) {
    descriptor.dwFlags |= SCH_CRED_NO_SYSTEM_MAPPER;
    if (cred->server_CA_certs) {
      descriptor.hRootStore = cred->server_CA_certs;
    }
  }

  ULONG direction = (cred->mode == PN_SSL_MODE_SERVER) ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND;
  *status = AcquireCredentialsHandle(NULL, UNISP_NAME, direction, NULL,
                                               &descriptor, NULL, NULL, &tmp_handle, &expiry);
  if (cred->mode == PN_SSL_MODE_SERVER && *status == SEC_E_OK)
    cred->cred_handle = tmp_handle;

  return tmp_handle;
}

static bool win_credential_has_certificate(win_credential_t *cred)
{
  if (!cred) return false;
  return (cred->cert_context != NULL);
}

#define SSL_DATA_SIZE 16384
#define SSL_BUF_SIZE (SSL_DATA_SIZE + 5 + 2048 + 32)

typedef enum { UNKNOWN_CONNECTION, SSL_CONNECTION, CLEAR_CONNECTION } connection_mode_t;
typedef struct pn_ssl_session_t pn_ssl_session_t;

struct pn_ssl_domain_t {
  CRITICAL_SECTION cslock;
  int ref_count;
  pn_ssl_mode_t mode;
  pn_ssl_verify_mode_t verify_mode;
  bool allow_unsecured;
  win_credential_t *cred;
};

typedef enum { CREATED, CLIENT_HELLO, NEGOTIATING,
               RUNNING, SHUTTING_DOWN, SSL_CLOSED } ssl_state_t;

struct pni_ssl_t {
  const char    *session_id;
  const char *peer_hostname;
  ssl_state_t state;

  bool protocol_detected;
  bool queued_shutdown;
  bool ssl_closed;            // shutdown complete, or SSL error
  ssize_t app_input_closed;   // error code returned by upper layer process input
  ssize_t app_output_closed;  // error code returned by upper layer process output

  // OpenSSL hides the protocol envelope bytes, SChannel has them in-line.
  char *sc_outbuf;     // SChannel output buffer
  size_t sc_out_size;
  size_t sc_out_count;
  char *network_outp;   // network ready bytes within sc_outbuf
  size_t network_out_pending;

  char *sc_inbuf;      // SChannel input buffer
  size_t sc_in_size;
  size_t sc_in_count;
  bool sc_in_incomplete;

  char *inbuf_extra;    // Still encrypted data from following Record(s)
  size_t extra_count;

  char *in_data;          // Just the plaintext data part of sc_inbuf, decrypted in place
  size_t in_data_size;
  size_t in_data_count;
  bool decrypting;
  size_t max_data_size;  // computed in the handshake

  pn_bytes_t app_inbytes; // Virtual decrypted datastream, presented to app layer

  pn_buffer_t *inbuf2;    // Second input buf if longer contiguous bytes needed
  bool double_buffered;

  bool sc_input_shutdown;

  CredHandle cred_handle;
  CtxtHandle ctxt_handle;
  SecPkgContext_StreamSizes sc_sizes;
  pn_ssl_mode_t mode;
  pn_ssl_verify_mode_t verify_mode;
  win_credential_t *cred;
  char *subject;
};

static inline pn_transport_t *get_transport_internal(pn_ssl_t *ssl)
{
  // The external pn_sasl_t is really a pointer to the internal pni_transport_t
  return ((pn_transport_t *)ssl);
}

static inline pni_ssl_t *get_ssl_internal(pn_ssl_t *ssl)
{
  // The external pn_sasl_t is really a pointer to the internal pni_transport_t
  return ssl ? ((pn_transport_t *)ssl)->ssl : NULL;
}

struct pn_ssl_session_t {
  const char       *id;
// TODO
  pn_ssl_session_t *ssn_cache_next;
  pn_ssl_session_t *ssn_cache_prev;
};


static ssize_t process_input_ssl( pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len);
static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *input_data, size_t len);
static ssize_t process_input_done(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len);
static ssize_t process_output_done(pn_transport_t *transport, unsigned int layer, char *input_data, size_t len);
static pn_ssl_session_t *ssn_cache_find( pn_ssl_domain_t *, const char * );
static void ssl_session_free( pn_ssl_session_t *);
static size_t buffered_output( pn_transport_t *transport );
static void start_ssl_shutdown(pn_transport_t *transport);
static void rewind_sc_inbuf(pni_ssl_t *ssl);
static bool grow_inbuf2(pn_transport_t *ssl, size_t minimum_size);
static HRESULT verify_peer(pni_ssl_t *ssl, HCERTSTORE root_store, const char *server_name, bool tracing);

// @todo: used to avoid littering the code with calls to printf...
static void ssl_vlog(pn_transport_t *transport, pn_log_level_t sev, const char *fmt, va_list ap)
{
  pn_logger_t *logger =  transport ? &transport->logger : pn_default_logger();
  if (PN_SHOULD_LOG(logger, PN_SUBSYSTEM_SSL, sev)) {
    pni_logger_vlogf(logger, PN_SUBSYSTEM_SSL, sev, fmt, ap);
  }
}

static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  ssl_vlog(transport, sev, fmt, ap);
  va_end(ap);
}

// @todo: used to avoid littering the code with calls to printf...
static void ssl_log_error(const char *fmt, ...)
{
  va_list ap;
  va_start(ap, fmt);
  ssl_vlog(NULL, PN_LEVEL_ERROR, fmt, ap);
  va_end(ap);
}

static void ssl_log_error_status(HRESULT status, const char *fmt, ...)
{
  char buf[512];
  va_list ap;

  if (fmt) {
    va_start(ap, fmt);
    ssl_vlog(NULL, PN_LEVEL_ERROR, fmt, ap);
    va_end(ap);
  }

  if (FormatMessage(FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_SYSTEM,
                    0, status, 0, buf, sizeof(buf), 0))
    ssl_log_error("%s", buf);
  else
    ssl_log_error("Internal Windows error: %x for %x", GetLastError(), status);
}

static void ssl_log_clear_data(pn_transport_t *transport, const char *data, size_t len)
{
  PN_LOG_DATA(&transport->logger, PN_SUBSYSTEM_SSL, PN_LEVEL_RAW, "decrypted data", data, len );
}

static size_t _pni_min(size_t a, size_t b)
{
  return (a < b) ? a : b;
}

// unrecoverable SSL failure occured, notify transport and generate error code.
static int ssl_failed(pn_transport_t *transport, const char *reason)
{
  char buf[512] = "Unknown error.";
  if (!reason) {
    HRESULT status = GetLastError();

    FormatMessage(FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_SYSTEM,
                  0, status, 0, buf, sizeof(buf), 0);
    reason = buf;
  }
  pni_ssl_t *ssl = transport->ssl;
  ssl->ssl_closed = true;
  ssl->app_input_closed = ssl->app_output_closed = PN_EOS;
  ssl->state = SSL_CLOSED;
  pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: %s", reason);
  return PN_EOS;
}

static pn_ssl_session_t *ssn_cache_find( pn_ssl_domain_t *domain, const char *id )
{
// TODO:
  return NULL;
}

static void ssl_session_free( pn_ssl_session_t *ssn)
{
  if (ssn) {
    if (ssn->id) free( (void *)ssn->id );
    free( ssn );
  }
}


/** Public API - visible to application code */

bool pn_ssl_present(void)
{
  return true;
}

pn_ssl_domain_t *pn_ssl_domain( pn_ssl_mode_t mode )
{
  switch (mode) {
  case PN_SSL_MODE_CLIENT:
  case PN_SSL_MODE_SERVER:
    break;

  default:
    ssl_log_error("Invalid mode for pn_ssl_mode_t: %d", mode);
    return NULL;
  }

  pn_ssl_domain_t *domain = (pn_ssl_domain_t *) calloc(1, sizeof(pn_ssl_domain_t));
  if (!domain) return NULL;

  InitializeCriticalSectionAndSpinCount(&domain->cslock, 4000);
  {
  csguard(&domain->cslock);
  domain->ref_count = 1;
  domain->mode = mode;
  domain->cred = win_credential(mode);
  }

  if (pn_ssl_domain_set_trusted_ca_db(domain, "ss:root") != 0) {
    pn_ssl_domain_free(domain);
    return NULL;
  }
  if (mode == PN_SSL_MODE_CLIENT)
    domain->verify_mode = PN_SSL_VERIFY_PEER_NAME;
  return domain;
}

// call with no locks
void pn_ssl_domain_free( pn_ssl_domain_t *domain )
{
  if (!domain) return;
  {
    csguard g(&domain->cslock);
    if (--domain->ref_count)
      return;
  }
  {
    csguard g2(&domain->cred->cslock);
    if (win_credential_decref(domain->cred)) {
      g2.release();
      win_credential_delete(domain->cred);
    }
  }
  DeleteCriticalSection(&domain->cslock);
  free(domain);
}


int pn_ssl_domain_set_credentials( pn_ssl_domain_t *domain,
                               const char *certificate_file,
                               const char *private_key_file,
                               const char *password)
{
  if (!domain) return -1;
  csguard g(&domain->cslock);
  csguard g2(&domain->cred->cslock);

  if (win_credential_has_certificate(domain->cred)) {
    // Need a new win_credential_t to hold new certificate
    if (win_credential_decref(domain->cred)) {
      g2.release();
      win_credential_delete(domain->cred);
    }
    domain->cred = win_credential(domain->mode);
    if (!domain->cred)
      return -1;
  }
  return win_credential_load_cert(domain->cred, certificate_file, private_key_file, password);
}


int pn_ssl_domain_set_trusted_ca_db(pn_ssl_domain_t *domain,
                                    const char *certificate_db)
{
  if (!domain || !certificate_db) return -1;
  csguard g(&domain->cslock);

  int ec = 0;
  HCERTSTORE store = open_cert_db(certificate_db, NULL, &ec);
  if (!store)
    return ec;

  csguard g2(&domain->cred->cslock);
  if (domain->cred->trust_store) {
    win_credential_t *new_cred = win_credential(domain->mode);
    if (!new_cred) {
      CertCloseStore(store, 0);
      return -1;
    }
    new_cred->cert_context = CertDuplicateCertificateContext(domain->cred->cert_context);
    if (win_credential_decref(domain->cred)) {
      g2.release();
      win_credential_delete(domain->cred);
    }
    domain->cred = new_cred;
  }

  domain->cred->trust_store = store;
  domain->cred->trust_store_name = pn_strdup(certificate_db);
  return 0;
}


int pn_ssl_domain_set_peer_authentication(pn_ssl_domain_t *domain,
                                          const pn_ssl_verify_mode_t mode,
                                          const char *trusted_CAs)
{
  if (!domain) return -1;
  csguard g(&domain->cslock);
  csguard g2(&domain->cred->cslock);

  HCERTSTORE store = 0;
  bool changed = domain->verify_mode && mode != domain->verify_mode;

  switch (mode) {
  case PN_SSL_VERIFY_PEER:
  case PN_SSL_VERIFY_PEER_NAME:
    if (domain->mode == PN_SSL_MODE_SERVER) {
      if (!trusted_CAs) {
        ssl_log_error("Error: a list of trusted CAs must be provided.");
        return -1;
      }
      if (!win_credential_has_certificate(domain->cred)) {
        ssl_log_error("Error: Server cannot verify peer without configuring a certificate, use pn_ssl_domain_set_credentials()");
        return -1;
      }
      int ec = 0;
      if (!strcmp(trusted_CAs, domain->cred->trust_store_name)) {
        changed = true;
        store = open_cert_db(trusted_CAs, NULL, &ec);
        if (!store)
          return ec;
      }
    }
    break;

  case PN_SSL_ANONYMOUS_PEER:   // hippie free love mode... :)
    break;

  default:
    ssl_log_error("Invalid peer authentication mode given.");
    return -1;
  }

  if (changed) {
    win_credential_t *new_cred = win_credential(domain->mode);
    if (!new_cred) {
      if (store)
        CertCloseStore(store, 0);
      return -1;
    }
    new_cred->cert_context = CertDuplicateCertificateContext(domain->cred->cert_context);
    new_cred->trust_store = CertDuplicateStore(domain->cred->trust_store);
    new_cred->trust_store_name = pn_strdup(domain->cred->trust_store_name);
    if (win_credential_decref(domain->cred)) {
      g2.release();
      win_credential_delete(domain->cred);
    }
    domain->cred = new_cred;
    domain->cred->server_CA_certs = store;
  }

  domain->verify_mode = mode;

  return 0;
}

int pn_ssl_domain_set_ciphers(pn_ssl_domain_t *domain, const char *ciphers)
{
  return PN_ERR;
}

int pn_ssl_domain_set_protocols(pn_ssl_domain_t *domain, const char *protocols)
{
  return PN_ERR;
}

const pn_io_layer_t ssl_layer = {
    process_input_ssl,
    process_output_ssl,
    NULL,
    NULL,
    buffered_output
};

const pn_io_layer_t ssl_input_closed_layer = {
    process_input_done,
    process_output_ssl,
    NULL,
    NULL,
    buffered_output
};

const pn_io_layer_t ssl_output_closed_layer = {
    process_input_ssl,
    process_output_done,
    NULL,
    NULL,
    buffered_output
};

const pn_io_layer_t ssl_closed_layer = {
    process_input_done,
    process_output_done,
    NULL,
    NULL,
    buffered_output
};

static pn_ssl_domain_t *default_client_domain = 0;
static pn_ssl_domain_t *default_server_domain = 0;

int pn_ssl_init(pn_ssl_t *ssl0, pn_ssl_domain_t *domain, const char *session_id)
{
  pn_transport_t *transport = get_transport_internal(ssl0);
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl) return -1;
  if (ssl->state != CREATED) return -1;

  if (!domain) {
    if (transport->server) {
        if (!default_server_domain) {
            default_server_domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
        }
        domain = default_server_domain;
    }
    else {
      if (!default_client_domain) {
        default_client_domain = pn_ssl_domain(PN_SSL_MODE_CLIENT);
        pn_ssl_domain_set_peer_authentication(default_client_domain, PN_SSL_VERIFY_PEER_NAME, NULL);
      }
      domain = default_client_domain;
    }
  }

  csguard g(&domain->cslock);
  csguard g2(&domain->cred->cslock);
  if (session_id && domain->mode == PN_SSL_MODE_CLIENT)
    ssl->session_id = pn_strdup(session_id);

  // If SSL doesn't specifically allow skipping encryption, require SSL
  // TODO: This is a probably a stop-gap until allow_unsecured is removed
  if (!domain->allow_unsecured) transport->encryption_required = true;

  ssl->cred = domain->cred;
  pn_incref(domain->cred);

  SECURITY_STATUS status = SEC_E_OK;
  ssl->cred_handle = win_credential_cred_handle(ssl->cred, ssl->session_id, &status);
  if (status != SEC_E_OK) {
    ssl_log_error_status(status, "Credentials handle failure");
    return -1;
  }

  ssl->state = (domain->mode == PN_SSL_MODE_CLIENT) ? CLIENT_HELLO : NEGOTIATING;
  ssl->verify_mode = domain->verify_mode;
  ssl->mode = domain->mode;
  return 0;
}


int pn_ssl_domain_allow_unsecured_client(pn_ssl_domain_t *domain)
{
  if (!domain) return -1;
  if (domain->mode != PN_SSL_MODE_SERVER) {
    ssl_log_error("Cannot permit unsecured clients - not a server.");
    return -1;
  }
  domain->allow_unsecured = true;
  return 0;
}


// TODO: This is just an untested guess
int pn_ssl_get_ssf(pn_ssl_t *ssl0)
{
  SecPkgContext_ConnectionInfo info;

  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (ssl &&
      ssl->state == RUNNING &&
      SecIsValidHandle(&ssl->ctxt_handle) &&
      QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info) == SEC_E_OK) {
    return info.dwCipherStrength;
  }
  return 0;
}

bool pn_ssl_get_cipher_name(pn_ssl_t *ssl0, char *buffer, size_t size )
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  *buffer = '\0';
  if (ssl->state != RUNNING || !SecIsValidHandle(&ssl->ctxt_handle))
    return false;
  SecPkgContext_ConnectionInfo info;
  if (QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info) == SEC_E_OK) {
    // TODO: come up with string for all permutations?
    snprintf( buffer, size, "%x_%x:%x_%x:%x_%x",
              info.aiExch, info.dwExchStrength,
              info.aiCipher, info.dwCipherStrength,
              info.aiHash, info.dwHashStrength);
    return true;
  }
  return false;
}

bool pn_ssl_get_protocol_name(pn_ssl_t *ssl0, char *buffer, size_t size )
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  *buffer = '\0';
  if (ssl->state != RUNNING || !SecIsValidHandle(&ssl->ctxt_handle))
    return false;
  SecPkgContext_ConnectionInfo info;
  if (QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info) == SEC_E_OK) {
    if (info.dwProtocol & (SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_SERVER))
      snprintf(buffer, size, "%s", "TLSv1");
    // TLSV1.1 and TLSV1.2 are supported as of XP-SP3, but not defined until VS2010
    else if ((info.dwProtocol & 0x300))
      snprintf(buffer, size, "%s", "TLSv1.1");
    else if ((info.dwProtocol & 0xC00))
      snprintf(buffer, size, "%s", "TLSv1.2");
    else {
      ssl_log_error("unexpected protocol %x", info.dwProtocol);
      return false;
    }
    return true;
  }
  return false;
}


void pn_ssl_free( pn_transport_t *transport)
{
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl) return;
  ssl_log( transport, PN_LEVEL_DEBUG, "SSL socket freed." );
  // clean up Windows per TLS session data before releasing the domain count
  csguard g(&ssl->cred->cslock);
  if (SecIsValidHandle(&ssl->ctxt_handle))
    DeleteSecurityContext(&ssl->ctxt_handle);
  if (ssl->cred) {
    if (ssl->mode == PN_SSL_MODE_CLIENT && ssl->session_id == NULL) {
      // Responsible for unshared handle
      if (SecIsValidHandle(&ssl->cred_handle))
        FreeCredentialsHandle(&ssl->cred_handle);
    }
    if (win_credential_decref(ssl->cred)) {
      g.release();
      win_credential_delete(ssl->cred);
    }
  }

  g.release();

  if (ssl->session_id) free((void *)ssl->session_id);
  if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
  if (ssl->sc_inbuf) free((void *)ssl->sc_inbuf);
  if (ssl->sc_outbuf) free((void *)ssl->sc_outbuf);
  if (ssl->inbuf2) pn_buffer_free(ssl->inbuf2);
  if (ssl->subject) free(ssl->subject);

  free(ssl);
}

pn_ssl_t *pn_ssl(pn_transport_t *transport)
{
  if (!transport) return NULL;
  if (transport->ssl) return (pn_ssl_t *)transport;

  pni_ssl_t *ssl = (pni_ssl_t *) calloc(1, sizeof(pni_ssl_t));
  if (!ssl) return NULL;
  ssl->sc_out_size = ssl->sc_in_size = SSL_BUF_SIZE;

  ssl->sc_outbuf = (char *)malloc(ssl->sc_out_size);
  if (!ssl->sc_outbuf) {
    free(ssl);
    return NULL;
  }
  ssl->sc_inbuf = (char *)malloc(ssl->sc_in_size);
  if (!ssl->sc_inbuf) {
    free(ssl->sc_outbuf);
    free(ssl);
    return NULL;
  }

  ssl->inbuf2 = pn_buffer(0);
  if (!ssl->inbuf2) {
    free(ssl->sc_inbuf);
    free(ssl->sc_outbuf);
    free(ssl);
    return NULL;
  }

  transport->ssl = ssl;

  // Set up hostname from any bound connection
  if (transport->connection) {
    if (pn_string_size(transport->connection->hostname)) {
      pn_ssl_set_peer_hostname((pn_ssl_t *) transport, pn_string_get(transport->connection->hostname));
    }
  }

  SecInvalidateHandle(&ssl->cred_handle);
  SecInvalidateHandle(&ssl->ctxt_handle);
  ssl->state = CREATED;
  ssl->decrypting = true;

  return (pn_ssl_t *)transport;
}


pn_ssl_resume_status_t pn_ssl_resume_status( pn_ssl_t *ssl )
{
  // TODO
  return PN_SSL_RESUME_UNKNOWN;
}


int pn_ssl_set_peer_hostname( pn_ssl_t *ssl0, const char *hostname )
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl) return -1;

  if (ssl->peer_hostname) free((void *)ssl->peer_hostname);
  ssl->peer_hostname = NULL;
  if (hostname) {
    ssl->peer_hostname = pn_strdup(hostname);
    if (!ssl->peer_hostname) return -2;
  }
  return 0;
}

int pn_ssl_get_peer_hostname( pn_ssl_t *ssl0, char *hostname, size_t *bufsize )
{
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl) return -1;
  if (!ssl->peer_hostname) {
    *bufsize = 0;
    if (hostname) *hostname = '\0';
    return 0;
  }
  unsigned len = strlen(ssl->peer_hostname);
  if (hostname) {
    if (len >= *bufsize) return -1;
    strcpy( hostname, ssl->peer_hostname );
  }
  *bufsize = len;
  return 0;
}

const char* pn_ssl_get_remote_subject(pn_ssl_t *ssl0)
{
  // RFC 2253 compliant, but differs from openssl's subject string with space separators and
  // ordering of multicomponent RDNs.  Made to work as similarly as possible with choice of flags.
  pni_ssl_t *ssl = get_ssl_internal(ssl0);
  if (!ssl || !SecIsValidHandle(&ssl->ctxt_handle))
    return NULL;
  if (!ssl->subject) {
    SECURITY_STATUS status;
    PCCERT_CONTEXT peer_cc = 0;
    status = QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &peer_cc);
    if (status != SEC_E_OK) {
      ssl_log_error_status(status, "can't obtain remote certificate subject");
      return NULL;
    }
    DWORD flags = CERT_X500_NAME_STR | CERT_NAME_STR_REVERSE_FLAG;
    DWORD strlen = CertNameToStr(peer_cc->dwCertEncodingType, &peer_cc->pCertInfo->Subject,
                                 flags, NULL, 0);
    if (strlen > 0) {
      ssl->subject = (char*) malloc(strlen);
      if (ssl->subject) {
        DWORD len = CertNameToStr(peer_cc->dwCertEncodingType, &peer_cc->pCertInfo->Subject,
                                  flags, ssl->subject, strlen);
        if (len != strlen) {
          free(ssl->subject);
          ssl->subject = NULL;
          ssl_log_error("pn_ssl_get_remote_subject failure in CertNameToStr");
        }
      }
    }
    CertFreeCertificateContext(peer_cc);
  }
  return ssl->subject;
}


/** SChannel specific: */

const char *tls_version_check(pni_ssl_t *ssl)
{
  SecPkgContext_ConnectionInfo info;
  QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_CONNECTION_INFO, &info);
  // Ascending bit patterns denote newer SSL/TLS protocol versions.
  // SP_PROT_TLS1_0_SERVER is not defined until VS2010.
  return (info.dwProtocol < SP_PROT_TLS1_SERVER) ?
    "peer does not support TLS 1.0 security" : NULL;
}

static void ssl_encrypt(pn_transport_t *transport, char *app_data, size_t count)
{
  pni_ssl_t *ssl = transport->ssl;

  // Get SChannel to encrypt exactly one Record.
  SecBuffer buffs[4];
  buffs[0].cbBuffer = ssl->sc_sizes.cbHeader;
  buffs[0].BufferType = SECBUFFER_STREAM_HEADER;
  buffs[0].pvBuffer = ssl->sc_outbuf;
  buffs[1].cbBuffer = count;
  buffs[1].BufferType = SECBUFFER_DATA;
  buffs[1].pvBuffer = app_data;
  buffs[2].cbBuffer = ssl->sc_sizes.cbTrailer;
  buffs[2].BufferType = SECBUFFER_STREAM_TRAILER;
  buffs[2].pvBuffer = &app_data[count];
  buffs[3].cbBuffer = 0;
  buffs[3].BufferType = SECBUFFER_EMPTY;
  buffs[3].pvBuffer = 0;
  SecBufferDesc buff_desc;
  buff_desc.ulVersion = SECBUFFER_VERSION;
  buff_desc.cBuffers = 4;
  buff_desc.pBuffers = buffs;
  SECURITY_STATUS status = EncryptMessage(&ssl->ctxt_handle, 0, &buff_desc, 0);
  assert(status == SEC_E_OK);

  // EncryptMessage encrypts the data in place. The header and trailer
  // areas were reserved previously and must now be included in the updated
  // count of bytes to write to the peer.
  ssl->sc_out_count = buffs[0].cbBuffer + buffs[1].cbBuffer + buffs[2].cbBuffer;
  ssl->network_outp = ssl->sc_outbuf;
  ssl->network_out_pending = ssl->sc_out_count;
  ssl_log(transport, PN_LEVEL_TRACE, "ssl_encrypt %d network bytes", ssl->network_out_pending);
}

// Returns true if decryption succeeded (even for empty content)
static bool ssl_decrypt(pn_transport_t *transport)
{
  pni_ssl_t *ssl = transport->ssl;
  // Get SChannel to decrypt input.  May have an incomplete Record,
  // exactly one, or more than one.  Check also for session ending,
  // session renegotiation.

  SecBuffer recv_buffs[4];
  recv_buffs[0].cbBuffer = ssl->sc_in_count;
  recv_buffs[0].BufferType = SECBUFFER_DATA;
  recv_buffs[0].pvBuffer = ssl->sc_inbuf;
  recv_buffs[1].BufferType = SECBUFFER_EMPTY;
  recv_buffs[2].BufferType = SECBUFFER_EMPTY;
  recv_buffs[3].BufferType = SECBUFFER_EMPTY;
  SecBufferDesc buff_desc;
  buff_desc.ulVersion = SECBUFFER_VERSION;
  buff_desc.cBuffers = 4;
  buff_desc.pBuffers = recv_buffs;
  SECURITY_STATUS status = DecryptMessage(&ssl->ctxt_handle, &buff_desc, 0, NULL);

  if (status == SEC_E_INCOMPLETE_MESSAGE) {
    // Less than a full Record, come back later with more network data
    ssl->sc_in_incomplete = true;
    return false;
  }

  ssl->decrypting = false;

  if (status != SEC_E_OK) {
    rewind_sc_inbuf(ssl);
    switch (status) {
    case SEC_I_CONTEXT_EXPIRED:
      // TLS shutdown alert record.  Ignore all subsequent input.
      ssl->state = SHUTTING_DOWN;
      ssl->sc_input_shutdown = true;
      return false;

    case SEC_I_RENEGOTIATE:
      ssl_log_error("unexpected TLS renegotiation");
      // TODO.  Fall through for now.
    default:
      ssl_failed(transport, 0);
      return false;
    }
  }

  ssl->decrypting = false;
  // have a decrypted Record and possible (still-encrypted) data of
  // one (or more) later Recordss.  Adjust pointers accordingly.
  for (int i = 0; i < 4; i++) {
    switch (recv_buffs[i].BufferType) {
    case SECBUFFER_DATA:
      ssl->in_data = (char *) recv_buffs[i].pvBuffer;
      ssl->in_data_size = ssl->in_data_count = recv_buffs[i].cbBuffer;
      break;
    case SECBUFFER_EXTRA:
      ssl->inbuf_extra = (char *)recv_buffs[i].pvBuffer;
      ssl->extra_count = recv_buffs[i].cbBuffer;
      break;
    default:
      // SECBUFFER_STREAM_HEADER:
      // SECBUFFER_STREAM_TRAILER:
      break;
    }
  }
  return true;
}

static void client_handshake_init(pn_transport_t *transport)
{
  pni_ssl_t *ssl = transport->ssl;
  // Tell SChannel to create the first handshake token (ClientHello)
  // and place it in sc_outbuf
  SEC_CHAR *host = (SEC_CHAR *)(ssl->peer_hostname);
  ULONG ctxt_requested = ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_EXTENDED_ERROR;
  ULONG ctxt_attrs;

  SecBuffer send_buffs[2];
  send_buffs[0].cbBuffer = ssl->sc_out_size;
  send_buffs[0].BufferType = SECBUFFER_TOKEN;
  send_buffs[0].pvBuffer = ssl->sc_outbuf;
  send_buffs[1].cbBuffer = 0;
  send_buffs[1].BufferType = SECBUFFER_EMPTY;
  send_buffs[1].pvBuffer = 0;
  SecBufferDesc send_buff_desc;
  send_buff_desc.ulVersion = SECBUFFER_VERSION;
  send_buff_desc.cBuffers = 2;
  send_buff_desc.pBuffers = send_buffs;
  csguard g(&ssl->cred->cslock);
  SECURITY_STATUS status = InitializeSecurityContext(&ssl->cred_handle,
                               NULL, host, ctxt_requested, 0, 0, NULL, 0,
                               &ssl->ctxt_handle, &send_buff_desc,
                               &ctxt_attrs, NULL);

  if (status == SEC_I_CONTINUE_NEEDED) {
    ssl->sc_out_count = send_buffs[0].cbBuffer;
    ssl->network_out_pending = ssl->sc_out_count;
    // the token is the whole quantity to send
    ssl->network_outp = ssl->sc_outbuf;
    ssl_log(transport, PN_LEVEL_TRACE, "Sending client hello %d bytes", ssl->network_out_pending);
  } else {
    ssl_log_error_status(status, "InitializeSecurityContext failed");
    ssl_failed(transport, 0);
  }
}

static void client_handshake( pn_transport_t* transport) {
  pni_ssl_t *ssl = transport->ssl;
  // Feed SChannel ongoing responses from the server until the handshake is complete.
  SEC_CHAR *host = (SEC_CHAR *)(ssl->peer_hostname);
  ULONG ctxt_requested = ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS;
  ULONG ctxt_attrs;
  size_t max = 0;

  // token_buffs describe the buffer that's coming in. It should have
  // a token from the SSL server, or empty if sending final shutdown alert.
  bool shutdown = ssl->state == SHUTTING_DOWN;
  SecBuffer token_buffs[2];
  token_buffs[0].cbBuffer = shutdown ? 0 : ssl->sc_in_count;
  token_buffs[0].BufferType = SECBUFFER_TOKEN;
  token_buffs[0].pvBuffer = shutdown ? 0 : ssl->sc_inbuf;
  token_buffs[1].cbBuffer = 0;
  token_buffs[1].BufferType = SECBUFFER_EMPTY;
  token_buffs[1].pvBuffer = 0;
  SecBufferDesc token_buff_desc;
  token_buff_desc.ulVersion = SECBUFFER_VERSION;
  token_buff_desc.cBuffers = 2;
  token_buff_desc.pBuffers = token_buffs;

  // send_buffs will hold information to forward to the peer.
  SecBuffer send_buffs[2];
  send_buffs[0].cbBuffer = ssl->sc_out_size;
  send_buffs[0].BufferType = SECBUFFER_TOKEN;
  send_buffs[0].pvBuffer = ssl->sc_outbuf;
  send_buffs[1].cbBuffer = 0;
  send_buffs[1].BufferType = SECBUFFER_EMPTY;
  send_buffs[1].pvBuffer = 0;
  SecBufferDesc send_buff_desc;
  send_buff_desc.ulVersion = SECBUFFER_VERSION;
  send_buff_desc.cBuffers = 2;
  send_buff_desc.pBuffers = send_buffs;

  SECURITY_STATUS status;
  {
    csguard g(&ssl->cred->cslock);
    status = InitializeSecurityContext(&ssl->cred_handle,
                               &ssl->ctxt_handle, host, ctxt_requested, 0, 0,
                               &token_buff_desc, 0, NULL, &send_buff_desc,
                               &ctxt_attrs, NULL);
  }

  switch (status) {
  case SEC_E_INCOMPLETE_MESSAGE:
    // Not enough - get more data from the server then try again.
    // Leave input buffers untouched.
    ssl_log(transport, PN_LEVEL_TRACE, "client handshake: incomplete record");
    ssl->sc_in_incomplete = true;
    return;

  case SEC_I_CONTINUE_NEEDED:
    // Successful handshake step, requiring data to be sent to peer.
    ssl->sc_out_count = send_buffs[0].cbBuffer;
    // the token is the whole quantity to send
    ssl->network_out_pending = ssl->sc_out_count;
    ssl->network_outp = ssl->sc_outbuf;
    ssl_log(transport, PN_LEVEL_DEBUG, "client handshake token %d bytes", ssl->network_out_pending);
    break;

  case SEC_E_OK:
    // Handshake complete.
    if (shutdown) {
      if (send_buffs[0].cbBuffer > 0) {
        ssl->sc_out_count = send_buffs[0].cbBuffer;
        // the token is the whole quantity to send
        ssl->network_out_pending = ssl->sc_out_count;
        ssl->network_outp = ssl->sc_outbuf;
        ssl_log(transport, PN_LEVEL_DEBUG, "client shutdown token %d bytes", ssl->network_out_pending);
      } else {
        ssl->state = SSL_CLOSED;
      }
      // we didn't touch sc_inbuf, no need to reset
      return;
    }
    if (send_buffs[0].cbBuffer != 0) {
      ssl_failed(transport, "unexpected final server token");
      break;
    }
    if (const char *err = tls_version_check(ssl)) {
      ssl_failed(transport, err);
      break;
    }
    if (ssl->verify_mode == PN_SSL_VERIFY_PEER || ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME) {
      bool tracing = PN_SHOULD_LOG(&transport->logger, PN_SUBSYSTEM_SSL, PN_LEVEL_TRACE);
      HRESULT ec = verify_peer(ssl, ssl->cred->trust_store, ssl->peer_hostname, tracing);
      if (ec) {
        if (ssl->peer_hostname)
          ssl_log_error_status(ec, "certificate verification failed for host %s", ssl->peer_hostname);
        else
          ssl_log_error_status(ec, "certificate verification failed");
        ssl_failed(transport, "TLS certificate verification error");
        break;
      }
    }

    if (token_buffs[1].BufferType == SECBUFFER_EXTRA && token_buffs[1].cbBuffer > 0) {
      // This seems to work but not documented, plus logic differs from decrypt message
      // since the pvBuffer value is not set.  Grrr.
      ssl->extra_count = token_buffs[1].cbBuffer;
      ssl->inbuf_extra = ssl->sc_inbuf + (ssl->sc_in_count - ssl->extra_count);
    }

    QueryContextAttributes(&ssl->ctxt_handle,
                             SECPKG_ATTR_STREAM_SIZES, &ssl->sc_sizes);
    max = ssl->sc_sizes.cbMaximumMessage + ssl->sc_sizes.cbHeader + ssl->sc_sizes.cbTrailer;
    if (max > ssl->sc_out_size) {
      ssl_log_error("Buffer size mismatch have %d, need %d", (int) ssl->sc_out_size, (int) max);
      ssl->state = SHUTTING_DOWN;
      ssl->app_input_closed = ssl->app_output_closed = PN_ERR;
      start_ssl_shutdown(transport);
      pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: buffer size");
      break;
    }

    ssl->state = RUNNING;
    ssl->max_data_size = max - ssl->sc_sizes.cbHeader - ssl->sc_sizes.cbTrailer;
    ssl_log(transport, PN_LEVEL_DEBUG, "client handshake successful %d max record size", max);
    break;

  case SEC_I_CONTEXT_EXPIRED:
    // ended before we got going
  default:
    ssl_log(transport, PN_LEVEL_ERROR, "client handshake failed %d", (int) status);
    ssl_failed(transport, 0);
    break;
  }

  if (token_buffs[1].BufferType == SECBUFFER_EXTRA && token_buffs[1].cbBuffer > 0 &&
      !ssl->ssl_closed) {
    // remaining data after the consumed TLS record(s)
    ssl->extra_count = token_buffs[1].cbBuffer;
    ssl->inbuf_extra = ssl->sc_inbuf + (ssl->sc_in_count - ssl->extra_count);
  }

  ssl->decrypting = false;
  rewind_sc_inbuf(ssl);
}


static void server_handshake(pn_transport_t* transport)
{
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl->protocol_detected) {
    // SChannel fails less aggressively than openssl on client hello, causing hangs
    // waiting for more bytes.  Help out here.
    pni_protocol_type_t type = pni_sniff_header(ssl->sc_inbuf, ssl->sc_in_count);
    if (type == PNI_PROTOCOL_INSUFFICIENT) {
      ssl_log(transport, PN_LEVEL_DEBUG, "server handshake: incomplete record");
      ssl->sc_in_incomplete = true;
      return;
    } else {
      ssl->protocol_detected = true;
      if (type != PNI_PROTOCOL_SSL) {
        ssl_failed(transport, "bad client hello");
        ssl->decrypting = false;
        rewind_sc_inbuf(ssl);
        return;
      }
    }
  }

  // Feed SChannel ongoing handshake records from the client until the handshake is complete.
  ULONG ctxt_requested = ASC_REQ_STREAM | ASC_REQ_EXTENDED_ERROR;
  if (ssl->verify_mode == PN_SSL_VERIFY_PEER || ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME)
    ctxt_requested |= ASC_REQ_MUTUAL_AUTH;
  ULONG ctxt_attrs;
  size_t max = 0;

  // token_buffs describe the buffer that's coming in. It should have
  // a token from the SSL client except if shutting down or renegotiating.
  bool shutdown = ssl->state == SHUTTING_DOWN;
  SecBuffer token_buffs[2];
  token_buffs[0].cbBuffer = shutdown ? 0 : ssl->sc_in_count;
  token_buffs[0].BufferType = SECBUFFER_TOKEN;
  token_buffs[0].pvBuffer = shutdown ? 0 : ssl->sc_inbuf;
  token_buffs[1].cbBuffer = 0;
  token_buffs[1].BufferType = SECBUFFER_EMPTY;
  token_buffs[1].pvBuffer = 0;
  SecBufferDesc token_buff_desc;
  token_buff_desc.ulVersion = SECBUFFER_VERSION;
  token_buff_desc.cBuffers = 2;
  token_buff_desc.pBuffers = token_buffs;

  // send_buffs will hold information to forward to the peer.
  SecBuffer send_buffs[2];
  send_buffs[0].cbBuffer = ssl->sc_out_size;
  send_buffs[0].BufferType = SECBUFFER_TOKEN;
  send_buffs[0].pvBuffer = ssl->sc_outbuf;
  send_buffs[1].cbBuffer = 0;
  send_buffs[1].BufferType = SECBUFFER_EMPTY;
  send_buffs[1].pvBuffer = 0;
  SecBufferDesc send_buff_desc;
  send_buff_desc.ulVersion = SECBUFFER_VERSION;
  send_buff_desc.cBuffers = 2;
  send_buff_desc.pBuffers = send_buffs;
  PCtxtHandle ctxt_handle_ptr = (SecIsValidHandle(&ssl->ctxt_handle)) ? &ssl->ctxt_handle : 0;

  SECURITY_STATUS status;
  {
    csguard g(&ssl->cred->cslock);
    status = AcceptSecurityContext(&ssl->cred_handle, ctxt_handle_ptr,
                               &token_buff_desc, ctxt_requested, 0, &ssl->ctxt_handle,
                               &send_buff_desc, &ctxt_attrs, NULL);
  }
  bool outbound_token = false;
  switch(status) {
  case SEC_E_INCOMPLETE_MESSAGE:
    // Not enough - get more data from the client then try again.
    // Leave input buffers untouched.
    ssl_log(transport, PN_LEVEL_DEBUG, "server handshake: incomplete record");
    ssl->sc_in_incomplete = true;
    return;

  case SEC_I_CONTINUE_NEEDED:
    outbound_token = true;
    break;

  case SEC_E_OK:
    // Handshake complete.
    if (shutdown) {
      if (send_buffs[0].cbBuffer > 0) {
        ssl->sc_out_count = send_buffs[0].cbBuffer;
        // the token is the whole quantity to send
        ssl->network_out_pending = ssl->sc_out_count;
        ssl->network_outp = ssl->sc_outbuf;
        ssl_log(transport, PN_LEVEL_DEBUG, "server shutdown token %d bytes", ssl->network_out_pending);
      } else {
        ssl->state = SSL_CLOSED;
      }
      // we didn't touch sc_inbuf, no need to reset
      return;
    }
    if (const char *err = tls_version_check(ssl)) {
      ssl_failed(transport, err);
      break;
    }
    // Handshake complete.

    if (ssl->verify_mode == PN_SSL_VERIFY_PEER || ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME) {
      bool tracing = PN_SHOULD_LOG(&transport->logger, PN_SUBSYSTEM_SSL, PN_LEVEL_TRACE);
      HRESULT ec = verify_peer(ssl, ssl->cred->trust_store, NULL, tracing);
      if (ec) {
        ssl_log_error_status(ec, "certificate verification failed");
        ssl_failed(transport, "certificate verification error");
        break;
      }
    }

    QueryContextAttributes(&ssl->ctxt_handle,
                             SECPKG_ATTR_STREAM_SIZES, &ssl->sc_sizes);
    max = ssl->sc_sizes.cbMaximumMessage + ssl->sc_sizes.cbHeader + ssl->sc_sizes.cbTrailer;
    if (max > ssl->sc_out_size) {
      ssl_log_error("Buffer size mismatch have %d, need %d", (int) ssl->sc_out_size, (int) max);
      ssl->state = SHUTTING_DOWN;
      ssl->app_input_closed = ssl->app_output_closed = PN_ERR;
      start_ssl_shutdown(transport);
      pn_do_error(transport, "amqp:connection:framing-error", "SSL Failure: buffer size");
      break;
    }

    if (send_buffs[0].cbBuffer != 0)
      outbound_token = true;

    ssl->state = RUNNING;
    ssl->max_data_size = max - ssl->sc_sizes.cbHeader - ssl->sc_sizes.cbTrailer;
    ssl_log(transport, PN_LEVEL_DEBUG, "server handshake successful %d max record size", max);
    break;

  case SEC_E_ALGORITHM_MISMATCH:
    ssl_log(transport, PN_LEVEL_WARNING, "server handshake failed: no common algorithm");
    ssl_failed(transport, "server handshake failed: no common algorithm");
    break;

  case SEC_I_CONTEXT_EXPIRED:
    // ended before we got going
  default:
    ssl_log(transport, PN_LEVEL_ERROR, "server handshake failed %d", (int) status);
    ssl_failed(transport, 0);
    break;
  }

  if (outbound_token) {
    // Successful handshake step, requiring data to be sent to peer.
    assert(ssl->network_out_pending == 0);
    ssl->sc_out_count = send_buffs[0].cbBuffer;
    // the token is the whole quantity to send
    ssl->network_out_pending = ssl->sc_out_count;
    ssl->network_outp = ssl->sc_outbuf;
    ssl_log(transport, PN_LEVEL_DEBUG, "server handshake token %d bytes", ssl->network_out_pending);
  }

  if (token_buffs[1].BufferType == SECBUFFER_EXTRA && token_buffs[1].cbBuffer > 0 &&
      !ssl->ssl_closed) {
    // remaining data after the consumed TLS record(s)
    ssl->extra_count = token_buffs[1].cbBuffer;
    ssl->inbuf_extra = ssl->sc_inbuf + (ssl->sc_in_count - ssl->extra_count);
  }

  ssl->decrypting = false;
  rewind_sc_inbuf(ssl);
}

static void ssl_handshake(pn_transport_t* transport) {
  if (transport->ssl->mode == PN_SSL_MODE_CLIENT)
    client_handshake(transport);
  else {
    server_handshake(transport);
  }
}

static bool grow_inbuf2(pn_transport_t *transport, size_t minimum_size) {
  pni_ssl_t *ssl = transport->ssl;
  size_t old_capacity = pn_buffer_capacity(ssl->inbuf2);
  size_t new_capacity = old_capacity ? old_capacity * 2 : 1024;

  while (new_capacity < minimum_size)
    new_capacity *= 2;

  uint32_t max_frame = pn_transport_get_max_frame(transport);
  if (max_frame != 0) {
    if (old_capacity >= max_frame) {
      //  already big enough
      ssl_log(transport, PN_LEVEL_ERROR, "Application expecting %d bytes (> negotiated maximum frame)", new_capacity);
      ssl_failed(transport, "TLS: transport maximum frame size error");
      return false;
    }
  }

  size_t extra_bytes = new_capacity - pn_buffer_size(ssl->inbuf2);
  int err = pn_buffer_ensure(ssl->inbuf2, extra_bytes);
  if (err) {
    ssl_log(transport, PN_LEVEL_ERROR, "TLS memory allocation failed for %d bytes", max_frame);
    ssl_failed(transport, "TLS memory allocation failed");
    return false;
  }
  return true;
}


// Peer initiated a session end by sending us a shutdown alert (and we should politely
// reciprocate), or else we are initiating the session end (and will not bother to wait
// for the peer shutdown alert). Stop processing input immediately, and stop processing
// output once this is sent.

static void start_ssl_shutdown(pn_transport_t *transport)
{
  pni_ssl_t *ssl = transport->ssl;
  assert(ssl->network_out_pending == 0);
  if (ssl->queued_shutdown)
    return;
  ssl->queued_shutdown = true;
  ssl_log(transport, PN_LEVEL_INFO, "Shutting down SSL connection...");

  DWORD shutdown = SCHANNEL_SHUTDOWN;
  SecBuffer shutBuff;
  shutBuff.cbBuffer = sizeof(DWORD);
  shutBuff.BufferType = SECBUFFER_TOKEN;
  shutBuff.pvBuffer = &shutdown;
  SecBufferDesc desc;
  desc.ulVersion = SECBUFFER_VERSION;
  desc.cBuffers = 1;
  desc.pBuffers = &shutBuff;
  ApplyControlToken(&ssl->ctxt_handle, &desc);

  // Next handshake will generate the shutdown alert token
  ssl_handshake(transport);
}

static void rewind_sc_inbuf(pni_ssl_t *ssl)
{
  // Decrypted bytes have been drained or double buffered.  Prepare for the next SSL Record.
  assert(ssl->in_data_count == 0);
  if (ssl->decrypting)
    return;
  ssl->decrypting = true;
  if (ssl->inbuf_extra) {
    // A previous read picked up more than one Record.  Move it to the beginning.
    memmove(ssl->sc_inbuf, ssl->inbuf_extra, ssl->extra_count);
    ssl->sc_in_count = ssl->extra_count;
    ssl->inbuf_extra = 0;
    ssl->extra_count = 0;
  } else {
    ssl->sc_in_count = 0;
  }
}

static void app_inbytes_add(pn_transport_t *transport)
{
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl->app_inbytes.start) {
    ssl->app_inbytes.start = ssl->in_data;
    ssl->app_inbytes.size = ssl->in_data_count;
    return;
  }

  if (ssl->double_buffered) {
    if (pn_buffer_available(ssl->inbuf2) == 0) {
      if (!grow_inbuf2(transport, 1024))
        // could not add room
        return;
    }
    size_t count = _pni_min(ssl->in_data_count, pn_buffer_available(ssl->inbuf2));
    pn_buffer_append(ssl->inbuf2, ssl->in_data, count);
    ssl->in_data += count;
    ssl->in_data_count -= count;
    ssl->app_inbytes = pn_buffer_bytes(ssl->inbuf2);
  } else {
    assert(ssl->app_inbytes.size == 0);
    ssl->app_inbytes.start = ssl->in_data;
    ssl->app_inbytes.size = ssl->in_data_count;
  }
}


static void app_inbytes_progress(pn_transport_t *transport, size_t minimum)
{
  pni_ssl_t *ssl = transport->ssl;
  // Make more decrypted data available, if possible.  Otherwise, move
  // unread bytes to front of inbuf2 to make room for next bulk decryption.
  // SSL may have chopped up data that app layer expects to be
  // contiguous.  Start, continue or stop double buffering here.
  if (ssl->double_buffered) {
    if (ssl->app_inbytes.size == 0) {
      // no straggler bytes, optimistically stop for now
      ssl->double_buffered = false;
      pn_buffer_clear(ssl->inbuf2);
      ssl->app_inbytes.start = ssl->in_data;
      ssl->app_inbytes.size = ssl->in_data_count;
    } else {
      pn_bytes_t ib2 = pn_buffer_bytes(ssl->inbuf2);
      assert(ssl->app_inbytes.size <= ib2.size);
      size_t consumed = ib2.size - ssl->app_inbytes.size;
      if (consumed > 0) {
        memmove((void *)ib2.start, ib2.start + consumed, ssl->app_inbytes.size);
        pn_buffer_trim(ssl->inbuf2, 0, consumed);
      }
      if (!pn_buffer_available(ssl->inbuf2)) {
        if (!grow_inbuf2(transport, minimum))
          // could not add room
          return;
      }
      size_t count = _pni_min(ssl->in_data_count, pn_buffer_available(ssl->inbuf2));
      pn_buffer_append(ssl->inbuf2, ssl->in_data, count);
      ssl->in_data += count;
      ssl->in_data_count -= count;
      ssl->app_inbytes = pn_buffer_bytes(ssl->inbuf2);
    }
  } else {
    if (ssl->app_inbytes.size) {
      // start double buffering the left over bytes
      ssl->double_buffered = true;
      pn_buffer_clear(ssl->inbuf2);
      if (!pn_buffer_available(ssl->inbuf2)) {
        if (!grow_inbuf2(transport, minimum))
          // could not add room
          return;
      }
      size_t count = _pni_min(ssl->in_data_count, pn_buffer_available(ssl->inbuf2));
      pn_buffer_append(ssl->inbuf2, ssl->in_data, count);
      ssl->in_data += count;
      ssl->in_data_count -= count;
      ssl->app_inbytes = pn_buffer_bytes(ssl->inbuf2);
    } else {
      // already pointing at all available bytes until next decrypt
    }
  }
  if (ssl->in_data_count == 0)
    rewind_sc_inbuf(ssl);
}


static void app_inbytes_advance(pn_transport_t *transport, size_t consumed)
{
  pni_ssl_t *ssl = transport->ssl;
  if (consumed == 0) {
    // more contiguous bytes required
    app_inbytes_progress(transport, ssl->app_inbytes.size + 1);
    return;
  }
  assert(consumed <= ssl->app_inbytes.size);
  ssl->app_inbytes.start += consumed;
  ssl->app_inbytes.size -= consumed;
  if (!ssl->double_buffered) {
    ssl->in_data += consumed;
    ssl->in_data_count -= consumed;
  }
  if (ssl->app_inbytes.size == 0)
    app_inbytes_progress(transport, 0);
}

static void read_closed(pn_transport_t *transport, unsigned int layer, ssize_t error)
{
  pni_ssl_t *ssl = transport->ssl;
  if (ssl->app_input_closed)
    return;
  if (ssl->state == RUNNING && !error) {
    // Signal end of stream
    ssl->app_input_closed = transport->io_layers[layer+1]->process_input(transport, layer+1, ssl->app_inbytes.start, 0);
  }
  if (!ssl->app_input_closed)
    ssl->app_input_closed = error ? error : PN_ERR;

  if (ssl->app_output_closed) {
    // both sides of app closed, and no more app output pending:
    ssl->state = SHUTTING_DOWN;
    if (ssl->network_out_pending == 0 && !ssl->queued_shutdown) {
      start_ssl_shutdown(transport);
    }
  }
}


// Read up to "available" bytes from the network, decrypt it and pass plaintext to application.

static ssize_t process_input_ssl(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t available)
{
  pni_ssl_t *ssl = transport->ssl;
  ssl_log( transport, PN_LEVEL_TRACE, "process_input_ssl( data size=%d )",available );
  ssize_t consumed = 0;
  ssize_t forwarded = 0;
  bool new_app_input;

  if (available == 0) {
    // No more inbound network data
    read_closed(transport, layer, 0);
    return 0;
  }

  do {
    if (ssl->sc_input_shutdown) {
      // TLS protocol shutdown detected on input, so we are done.
      read_closed(transport, layer, 0);
      return PN_EOS;
    }

    // sc_inbuf should be ready for new or additional network encrypted bytes.
    // i.e. no straggling decrypted bytes pending.
    assert(ssl->in_data_count == 0 && ssl->decrypting);
    new_app_input = false;
    size_t count;

    if (ssl->state != RUNNING) {
      count = _pni_min(ssl->sc_in_size - ssl->sc_in_count, available);
    } else {
      // look for TLS record boundaries
      if (ssl->sc_in_count < 5) {
        ssl->sc_in_incomplete = true;
        size_t hc = _pni_min(available, 5 - ssl->sc_in_count);
        memmove(ssl->sc_inbuf + ssl->sc_in_count, input_data, hc);
        ssl->sc_in_count += hc;
        input_data += hc;
        available -= hc;
        consumed += hc;
        if (ssl->sc_in_count < 5 || available == 0)
          break;
      }

      // Top up sc_inbuf from network input_data hoping for a complete TLS Record
      // We try to guess the length as an optimization, but let SChannel
      // ultimately decide if there is spoofing going on.
      unsigned char low = (unsigned char) ssl->sc_inbuf[4];
      unsigned char high = (unsigned char) ssl->sc_inbuf[3];
      size_t rec_len = high * 256 + low + 5;
      if (rec_len < 5 || rec_len == ssl->sc_in_count || rec_len > ssl->sc_in_size)
        rec_len = ssl->sc_in_size;

      count = _pni_min(rec_len - ssl->sc_in_count, available);
    }

    if (count > 0) {
      memmove(ssl->sc_inbuf + ssl->sc_in_count, input_data, count);
      ssl->sc_in_count += count;
      input_data += count;
      available -= count;
      consumed += count;
      ssl->sc_in_incomplete = false;
    }

    // Try to decrypt another TLS Record.

    if (ssl->sc_in_count > 0 && ssl->state <= SHUTTING_DOWN) {
      if (ssl->state == NEGOTIATING) {
        ssl_handshake(transport);
      } else {
        if (ssl_decrypt(transport)) {
          // Ignore TLS Record with 0 length data (does not mean EOS)
          if (ssl->in_data_size > 0) {
            new_app_input = true;
            app_inbytes_add(transport);
          } else {
            assert(ssl->decrypting == false);
            rewind_sc_inbuf(ssl);
          }
        }
        ssl_log(transport, PN_LEVEL_TRACE, "Next decryption, %d left over", available);
      }
    }

    if (ssl->state == SHUTTING_DOWN) {
      if (ssl->network_out_pending == 0 && !ssl->queued_shutdown) {
        start_ssl_shutdown(transport);
      }
    } else if (ssl->state == SSL_CLOSED) {
      return PN_EOS;
    }

    // Consume or discard the decrypted bytes
    if (new_app_input && (ssl->state == RUNNING || ssl->state == SHUTTING_DOWN)) {
      // present app_inbytes to io_next only if it has new content
      while (ssl->app_inbytes.size > 0) {
        if (!ssl->app_input_closed) {
          ssize_t count = transport->io_layers[layer+1]->process_input(transport, layer+1, ssl->app_inbytes.start, ssl->app_inbytes.size);
          if (count > 0) {
            forwarded += count;
            // advance() can increase app_inbytes.size if double buffered
            app_inbytes_advance(transport, count);
            ssl_log(transport, PN_LEVEL_TRACE, "Application consumed %d bytes from peer", (int) count);
          } else if (count == 0) {
            size_t old_size = ssl->app_inbytes.size;
            app_inbytes_advance(transport, 0);
            if (ssl->app_inbytes.size == old_size) {
              break;  // no additional contiguous decrypted data available, get more network data
            }
          } else {
            // count < 0
            ssl_log(transport, PN_LEVEL_WARNING, "Application layer closed its input, error=%d (discarding %d bytes)",
                 (int) count, (int)ssl->app_inbytes.size);
            app_inbytes_advance(transport, ssl->app_inbytes.size);    // discard
            read_closed(transport, layer, count);
          }
        } else {
          ssl_log(transport, PN_LEVEL_WARNING, "Input closed discard %d bytes",
               (int)ssl->app_inbytes.size);
          app_inbytes_advance(transport, ssl->app_inbytes.size);      // discard
        }
      }
    }
  } while (available || (ssl->sc_in_count && !ssl->sc_in_incomplete));

  if (ssl->state >= SHUTTING_DOWN) {
    if (ssl->app_input_closed || ssl->sc_input_shutdown) {
      // Next layer doesn't want more bytes, or it can't process without more data than it has seen so far
      // but the ssl stream has ended
      consumed = ssl->app_input_closed ? ssl->app_input_closed : PN_EOS;
      if (transport->io_layers[layer]==&ssl_output_closed_layer) {
        transport->io_layers[layer] = &ssl_closed_layer;
      } else {
        transport->io_layers[layer] = &ssl_input_closed_layer;
      }
    }
  }
  ssl_log(transport, PN_LEVEL_TRACE, "process_input_ssl() returning %d, forwarded %d", (int) consumed, (int) forwarded);
  return consumed;
}

static ssize_t process_output_ssl( pn_transport_t *transport, unsigned int layer, char *buffer, size_t max_len)
{
  pni_ssl_t *ssl = transport->ssl;
  if (!ssl) return PN_EOS;
  ssl_log( transport, PN_LEVEL_TRACE, "process_output_ssl( max_len=%d )",max_len );

  ssize_t written = 0;
  ssize_t total_app_bytes = 0;
  bool work_pending;

  if (ssl->state == CLIENT_HELLO) {
    // output buffers eclusively for internal handshake use until negotiation complete
    client_handshake_init(transport);
    if (ssl->state == SSL_CLOSED)
      return PN_EOS;
    ssl->state = NEGOTIATING;
  }

  do {
    work_pending = false;

    if (ssl->network_out_pending > 0) {
      size_t wcount = _pni_min(ssl->network_out_pending, max_len);
      memmove(buffer, ssl->network_outp, wcount);
      ssl->network_outp += wcount;
      ssl->network_out_pending -= wcount;
      buffer += wcount;
      max_len -= wcount;
      written += wcount;
    }

    if (ssl->network_out_pending == 0 && ssl->state == RUNNING  && !ssl->app_output_closed) {
      // refill the buffer with app data and encrypt it

      char *app_data = ssl->sc_outbuf + ssl->sc_sizes.cbHeader;
      char *app_outp = app_data;
      size_t remaining = ssl->max_data_size;
      ssize_t app_bytes;
      do {
        app_bytes = transport->io_layers[layer+1]->process_output(transport, layer+1, app_outp, remaining);
        if (app_bytes > 0) {
          app_outp += app_bytes;
          remaining -= app_bytes;
          ssl_log( transport, PN_LEVEL_TRACE, "Gathered %d bytes from app to send to peer", app_bytes );
        } else {
          if (app_bytes < 0) {
            ssl_log(transport, PN_LEVEL_WARNING, "Application layer closed its output, error=%d (%d bytes pending send)",
                 (int) app_bytes, (int) ssl->network_out_pending);
            ssl->app_output_closed = app_bytes;
            if (ssl->app_input_closed)
              ssl->state = SHUTTING_DOWN;
          } else if (total_app_bytes == 0 && ssl->app_input_closed) {
            // We've drained all the App layer can provide
            ssl_log(transport, PN_LEVEL_WARNING, "Application layer blocked on input, closing");
            ssl->state = SHUTTING_DOWN;
            ssl->app_output_closed = PN_ERR;
          }
        }
      } while (app_bytes > 0);
      if (app_outp > app_data) {
        work_pending = (max_len > 0);
        ssl_encrypt(transport, app_data, app_outp - app_data);
      }
    }

    if (ssl->network_out_pending == 0) {
      if (ssl->state == SHUTTING_DOWN) {
        if (!ssl->queued_shutdown) {
          start_ssl_shutdown(transport);
          work_pending = true;
        } else {
          ssl->state = SSL_CLOSED;
        }
      }
      else if (ssl->state == NEGOTIATING && ssl->app_input_closed) {
        ssl->app_output_closed = PN_EOS;
        ssl->state = SSL_CLOSED;
      }
    }
  } while (work_pending);

  if (written == 0 && ssl->state == SSL_CLOSED) {
    written = ssl->app_output_closed ? ssl->app_output_closed : PN_EOS;
    if (transport->io_layers[layer]==&ssl_input_closed_layer) {
      transport->io_layers[layer] = &ssl_closed_layer;
    } else {
      transport->io_layers[layer] = &ssl_output_closed_layer;
    }
  }
  ssl_log(transport, PN_LEVEL_TRACE, "process_output_ssl() returning %d", (int) written);
  return written;
}


static ssize_t process_input_done(pn_transport_t *transport, unsigned int layer, const char *input_data, size_t len)
{
  return PN_EOS;
}

static ssize_t process_output_done(pn_transport_t *transport, unsigned int layer, char *input_data, size_t len)
{
  return PN_EOS;
}

// return # output bytes sitting in this layer
static size_t buffered_output(pn_transport_t *transport)
{
  size_t count = 0;
  pni_ssl_t *ssl = transport->ssl;
  if (ssl) {
    count += ssl->network_out_pending;
    if (count == 0 && ssl->state == SHUTTING_DOWN && ssl->queued_shutdown)
      count++;
  }
  return count;
}

static HCERTSTORE open_cert_db(const char *store_name, const char *passwd, int *error) {
  *error = 0;
  DWORD sys_store_type = 0;
  HCERTSTORE cert_store = 0;

  if (store_name) {
    if (strncmp(store_name, "ss:", 3) == 0) {
      store_name += 3;
      sys_store_type = CERT_SYSTEM_STORE_CURRENT_USER;
    }
    else if (strncmp(store_name, "lmss:", 5) == 0) {
      store_name += 5;
      sys_store_type = CERT_SYSTEM_STORE_LOCAL_MACHINE;
    }
  }

  if (sys_store_type) {
    // Opening a system store, names are not case sensitive.
    // Map confusing GUI name to actual registry store name.
    if (!pn_strcasecmp(store_name, "personal")) store_name= "my";
    cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL,
                               CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG |
                               sys_store_type, store_name);
    if (!cert_store) {
      ssl_log_error_status(GetLastError(), "Failed to open system certificate store %s", store_name);
      *error = -3;
      return NULL;
    }
  } else {
    // PKCS#12 file
    HANDLE cert_file = CreateFile(store_name, GENERIC_READ, 0, NULL, OPEN_EXISTING,
                                  FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == cert_file) {
      HRESULT status = GetLastError();
      ssl_log_error_status(status, "Failed to open the file holding the private key: %s", store_name);
      *error = -4;
      return NULL;
    }
    DWORD nread = 0L;
    const DWORD file_size = GetFileSize(cert_file, NULL);
    char *buf = NULL;
    if (INVALID_FILE_SIZE != file_size)
      buf = (char *) malloc(file_size);
    if (!buf || !ReadFile(cert_file, buf, file_size, &nread, NULL)
        || file_size != nread) {
      HRESULT status = GetLastError();
      CloseHandle(cert_file);
      free(buf);
      ssl_log_error_status(status, "Reading the private key from file failed %s", store_name);
      *error = -5;
      return NULL;
    }
    CloseHandle(cert_file);

    CRYPT_DATA_BLOB blob;
    blob.cbData = nread;
    blob.pbData = (BYTE *) buf;

    wchar_t *pwUCS2 = NULL;
    int pwlen = 0;
    if (passwd) {
      // convert passwd to null terminated wchar_t (Windows UCS2)
      pwlen = strlen(passwd);
      pwUCS2 = (wchar_t *) calloc(pwlen + 1, sizeof(wchar_t));
      int nwc = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, passwd, pwlen, &pwUCS2[0], pwlen);
      if (!nwc) {
        ssl_log_error_status(GetLastError(), "Error converting password from UTF8");
        free(buf);
        free(pwUCS2);
        *error = -6;
        return NULL;
      }
    }

    cert_store = PFXImportCertStore(&blob, pwUCS2, 0);
    if (pwUCS2) {
      SecureZeroMemory(pwUCS2, pwlen * sizeof(wchar_t));
      free(pwUCS2);
    }
    if (cert_store == NULL) {
      ssl_log_error_status(GetLastError(), "Failed to import the file based certificate store");
      free(buf);
      *error = -7;
      return NULL;
    }

    free(buf);
  }

  return cert_store;
}

static bool store_contains(HCERTSTORE store, PCCERT_CONTEXT cert)
{
  DWORD find_type = CERT_FIND_EXISTING; // Require exact match
  PCCERT_CONTEXT tcert = CertFindCertificateInStore(store, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                                    0, find_type, cert, 0);
  if (tcert) {
    CertFreeCertificateContext(tcert);
    return true;
  }
  return false;
}

/* Match the DNS name pattern from the peer certificate against our configured peer
   hostname */
static bool match_dns_pattern(const char *hostname, const char *pattern, int plen)
{
  int slen = (int) strlen(hostname);
  if (memchr( pattern, '*', plen ) == NULL)
    return (plen == slen &&
            pn_strncasecmp( pattern, hostname, plen ) == 0);

  /* dns wildcarded pattern - RFC2818 */
  char plabel[64];   /* max label length < 63 - RFC1034 */
  char slabel[64];

  while (plen > 0 && slen > 0) {
    const char *cptr;
    int len;

    cptr = (const char *) memchr( pattern, '.', plen );
    len = (cptr) ? cptr - pattern : plen;
    if (len > (int) sizeof(plabel) - 1) return false;
    memcpy( plabel, pattern, len );
    plabel[len] = 0;
    if (cptr) ++len;    // skip matching '.'
    pattern += len;
    plen -= len;

    cptr = (const char *) memchr( hostname, '.', slen );
    len = (cptr) ? cptr - hostname : slen;
    if (len > (int) sizeof(slabel) - 1) return false;
    memcpy( slabel, hostname, len );
    slabel[len] = 0;
    if (cptr) ++len;    // skip matching '.'
    hostname += len;
    slen -= len;

    char *star = strchr( plabel, '*' );
    if (!star) {
      if (pn_strcasecmp( plabel, slabel )) return false;
    } else {
      *star = '\0';
      char *prefix = plabel;
      int prefix_len = strlen(prefix);
      char *suffix = star + 1;
      int suffix_len = strlen(suffix);
      if (prefix_len && pn_strncasecmp( prefix, slabel, prefix_len )) return false;
      if (suffix_len && pn_strncasecmp( suffix,
                                     slabel + (strlen(slabel) - suffix_len),
                                     suffix_len )) return false;
    }
  }

  return plen == slen;
}

// Caller must free the returned buffer
static char* wide_to_utf8(LPWSTR wstring)
{
  int len = WideCharToMultiByte(CP_UTF8, 0, wstring, -1, 0, 0, 0, 0);
  if (!len) {
    ssl_log_error_status(GetLastError(), "converting UCS2 to UTF8");
    return NULL;
  }
  char *p = (char *) malloc(len);
  if (!p) return NULL;
  if (WideCharToMultiByte(CP_UTF8, 0, wstring, -1, p, len, 0, 0))
    return p;
  ssl_log_error_status(GetLastError(), "converting UCS2 to UTF8");
  free (p);
  return NULL;
}

static bool server_name_matches(const char *server_name, CERT_EXTENSION *alt_name_ext, PCCERT_CONTEXT cert)
{
  // As for openssl.c: alt names first, then CN
  bool matched = false;

  if (alt_name_ext) {
    CERT_ALT_NAME_INFO* alt_name_info = NULL;
    DWORD size = 0;
    if(!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, szOID_SUBJECT_ALT_NAME2,
                            alt_name_ext->Value.pbData, alt_name_ext->Value.cbData,
                            CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_NOCOPY_FLAG,
                            0, &alt_name_info, &size)) {
      ssl_log_error_status(GetLastError(), "Alternative name match internal error");
      return false;
    }

    int name_ct = alt_name_info->cAltEntry;
    for (int i = 0; !matched && i < name_ct; ++i) {
      if (alt_name_info->rgAltEntry[i].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME) {
        char *alt_name = wide_to_utf8(alt_name_info->rgAltEntry[i].pwszDNSName);
        if (alt_name) {
          matched = match_dns_pattern(server_name, (const char *) alt_name, strlen(alt_name));
          free(alt_name);
        }
      }
    }
    LocalFree(alt_name_info);
  }

  if (!matched) {
    PCERT_INFO info = cert->pCertInfo;
    DWORD len = CertGetNameString(cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, 0, 0);
    char *name = (char *) malloc(len);
    if (name) {
      int count = CertGetNameString(cert, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, name, len);
      if (count)
        matched = match_dns_pattern(server_name, (const char *) name, strlen(name));
      free(name);
    }
  }
  return matched;
}

const char* pn_ssl_get_remote_subject_subfield(pn_ssl_t *ssl0, pn_ssl_cert_subject_subfield field)
{
    return NULL;
}

int pn_ssl_get_cert_fingerprint(pn_ssl_t *ssl0,
                                          char *fingerprint,
                                          size_t fingerprint_length,
                                          pn_ssl_hash_alg hash_alg)
{
    *fingerprint = '\0';
    return -1;
}

static HRESULT verify_peer(pni_ssl_t *ssl, HCERTSTORE root_store, const char *server_name, bool tracing)
{
  // Free/release the following before return:
  PCCERT_CONTEXT peer_cc = 0;
  PCCERT_CONTEXT trust_anchor = 0;
  PCCERT_CHAIN_CONTEXT chain_context = 0;
  wchar_t *nameUCS2 = 0;

  if (server_name && strlen(server_name) > 255) {
    ssl_log_error("invalid server name: %s", server_name);
    return WSAENAMETOOLONG;
  }

  // Get peer's certificate.
  SECURITY_STATUS status;
  status = QueryContextAttributes(&ssl->ctxt_handle, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &peer_cc);
  if (status != SEC_E_OK) {
    ssl_log_error_status(status, "can't obtain remote peer certificate information");
    return status;
  }

  // Build the peer's certificate chain.  Multiple chains may be built but we
  // care about rgpChain[0], which is the best.  Custom root stores are not
  // allowed until W8/server 2012: see CERT_CHAIN_ENGINE_CONFIG.  For now, we
  // manually override to taste.

  // Chain verification functions give false reports for CRL if the trust anchor
  // is not in the official root store.  We ignore CRL completely if it doesn't
  // apply to any untrusted certs in the chain, and defer to SChannel's veto
  // otherwise.  To rely on CRL, the CA must be in both the official system
  // trusted root store and the Proton cred->trust_store.  To defeat CRL, the
  // most distal cert with CRL must be placed in the Proton cred->trust_store.
  // Similarly, certificate usage checking is overly strict at times.

  CERT_CHAIN_PARA desc;
  memset(&desc, 0, sizeof(desc));
  desc.cbSize = sizeof(desc);

  LPSTR usages[] = { szOID_PKIX_KP_SERVER_AUTH };
  DWORD n_usages = sizeof(usages) / sizeof(LPSTR);
  desc.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
  desc.RequestedUsage.Usage.cUsageIdentifier = n_usages;
  desc.RequestedUsage.Usage.rgpszUsageIdentifier = usages;

  if(!CertGetCertificateChain(0, peer_cc, 0, peer_cc->hCertStore, &desc,
                             CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT |
                             CERT_CHAIN_CACHE_END_CERT,
                             0, &chain_context)){
    HRESULT st = GetLastError();
    ssl_log_error_status(st, "Basic certificate chain check failed");
    CertFreeCertificateContext(peer_cc);
    return st;
  }
  if (chain_context->cChain < 1 || chain_context->rgpChain[0]->cElement < 1) {
    ssl_log_error("empty chain with status %x %x", chain_context->TrustStatus.dwErrorStatus,
                 chain_context->TrustStatus.dwInfoStatus);
    return SEC_E_CERT_UNKNOWN;
  }

  int chain_len = chain_context->rgpChain[0]->cElement;
  PCCERT_CONTEXT leaf_cert = chain_context->rgpChain[0]->rgpElement[0]->pCertContext;
  PCCERT_CONTEXT trunk_cert = chain_context->rgpChain[0]->rgpElement[chain_len - 1]->pCertContext;
  if (tracing)
    // See doc for CERT_CHAIN_POLICY_STATUS for bit field error and info status values
    ssl_log_error("status for complete chain: error bits %x info bits %x",
                  chain_context->TrustStatus.dwErrorStatus, chain_context->TrustStatus.dwInfoStatus);

  // Supplement with checks against Proton's trusted_ca_db, custom revocation and usage.
  HRESULT error = 0;
  do {
    // Do not return from this do loop.  Set error = SEC_E_XXX and break.
    bool revocable = false;  // unless we see any untrusted certs that could be
    for (int i = 0; i < chain_len; i++) {
      CERT_CHAIN_ELEMENT *ce = chain_context->rgpChain[0]->rgpElement[i];
      PCCERT_CONTEXT cc = ce->pCertContext;
      if (cc->pCertInfo->dwVersion != CERT_V3) {
        if (tracing)
          ssl_log_error("certificate chain element %d is not version 3", i);
        error = SEC_E_CERT_WRONG_USAGE; // A fossil
        break;
      }

      if (!trust_anchor && store_contains(root_store, cc))
        trust_anchor = CertDuplicateCertificateContext(cc);

      int n_ext = cc->pCertInfo->cExtension;
      for (int ii = 0; ii < n_ext && !revocable && !trust_anchor; ii++) {
        CERT_EXTENSION *p = &cc->pCertInfo->rgExtension[ii];
        // rfc 5280 extensions for revocation
        if (!strcmp(p->pszObjId, szOID_AUTHORITY_INFO_ACCESS) ||
            !strcmp(p->pszObjId, szOID_CRL_DIST_POINTS) ||
            !strcmp(p->pszObjId, szOID_FRESHEST_CRL)) {
          revocable = true;
        }
      }

      if (tracing) {
        char name[512];
        const char *is_anchor = (cc == trust_anchor) ? " trust anchor" : "";
        if (!CertNameToStr(cc->dwCertEncodingType, &cc->pCertInfo->Subject,
                           CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, name, sizeof(name)))
          strcpy(name, "[too long]");
        ssl_log_error("element %d (name: %s)%s error bits %x info bits %x", i, name, is_anchor,
                      ce->TrustStatus.dwErrorStatus, ce->TrustStatus.dwInfoStatus);
      }
    }
    if (error)
      break;

    if (!trust_anchor) {
      // We don't trust any of the certs in the chain, see if the last cert
      // is issued by a Proton trusted CA.
      DWORD flags = CERT_STORE_NO_ISSUER_FLAG || CERT_STORE_SIGNATURE_FLAG ||
        CERT_STORE_TIME_VALIDITY_FLAG;
      trust_anchor = CertGetIssuerCertificateFromStore(root_store, trunk_cert, 0, &flags);
      if (trust_anchor) {
        if (tracing) {
          if (flags & CERT_STORE_SIGNATURE_FLAG)
            ssl_log_error("root certificate signature failure");
          if (flags & CERT_STORE_TIME_VALIDITY_FLAG)
            ssl_log_error("root certificate time validity failure");
        }
        if (flags) {
          CertFreeCertificateContext(trust_anchor);
          trust_anchor = 0;
        }
      }
    }
    if (!trust_anchor) {
      error = SEC_E_UNTRUSTED_ROOT;
      break;
    }

    bool strict_usage = false;
    CERT_EXTENSION *leaf_alt_names = 0;
    if (leaf_cert != trust_anchor) {
      int n_ext = leaf_cert->pCertInfo->cExtension;
      for (int ii = 0; ii < n_ext; ii++) {
        CERT_EXTENSION *p = &leaf_cert->pCertInfo->rgExtension[ii];
        if (!strcmp(p->pszObjId, szOID_ENHANCED_KEY_USAGE))
          strict_usage = true;
        if (!strcmp(p->pszObjId, szOID_SUBJECT_ALT_NAME2))
          if (p->Value.pbData)
            leaf_alt_names = p;
      }
    }

    if (server_name) {
      int len = strlen(server_name);
      nameUCS2 = (wchar_t *) calloc(len + 1, sizeof(wchar_t));
      int nwc = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, server_name, len, &nameUCS2[0], len);
      if (!nwc) {
        error = GetLastError();
        ssl_log_error_status(error, "Error converting server name from UTF8");
        break;
      }
    }

    // SSL-specific parameters (ExtraPolicy below)
    SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_desc;
    memset(&ssl_desc, 0, sizeof(ssl_desc));
    ssl_desc.cbSize = sizeof(ssl_desc);
    ssl_desc.pwszServerName = nameUCS2;
    ssl_desc.dwAuthType = nameUCS2 ? AUTHTYPE_SERVER : AUTHTYPE_CLIENT;
    ssl_desc.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA;
    if (server_name)
      ssl_desc.fdwChecks |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
    if (!revocable)
      ssl_desc.fdwChecks |= SECURITY_FLAG_IGNORE_REVOCATION;
    if (!strict_usage)
      ssl_desc.fdwChecks |= SECURITY_FLAG_IGNORE_WRONG_USAGE;

    // General certificate chain parameters
    CERT_CHAIN_POLICY_PARA chain_desc;
    memset(&chain_desc, 0, sizeof(chain_desc));
    chain_desc.cbSize = sizeof(chain_desc);
    chain_desc.dwFlags = CERT_CHAIN_POLICY_ALLOW_UNKNOWN_CA_FLAG;
    if (!revocable)
      chain_desc.dwFlags |= CERT_CHAIN_POLICY_IGNORE_ALL_REV_UNKNOWN_FLAGS;
    if (!strict_usage)
      chain_desc.dwFlags |= CERT_CHAIN_POLICY_IGNORE_WRONG_USAGE_FLAG;
    chain_desc.pvExtraPolicyPara = &ssl_desc;

    CERT_CHAIN_POLICY_STATUS chain_status;
    memset(&chain_status, 0, sizeof(chain_status));
    chain_status.cbSize = sizeof(chain_status);

    if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, chain_context,
                                          &chain_desc, &chain_status)) {
      error = GetLastError();
      // Failure to complete the check, does not (in)validate the cert.
      ssl_log_error_status(error, "Supplemental certificate chain check failed");
      break;
    }

    if (chain_status.dwError) {
      error = chain_status.dwError;
      if (tracing) {
        ssl_log_error_status(chain_status.dwError, "Certificate chain verification error");
        if (chain_status.lChainIndex == 0 && chain_status.lElementIndex != -1) {
          int idx = chain_status.lElementIndex;
          CERT_CHAIN_ELEMENT *ce = chain_context->rgpChain[0]->rgpElement[idx];
          ssl_log_error("  chain failure at %d error/info: %x %x", idx,
                        ce->TrustStatus.dwErrorStatus, ce->TrustStatus.dwInfoStatus);
        }
      }
      break;
    }

    if (server_name && ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME &&
        !server_name_matches(server_name, leaf_alt_names, leaf_cert)) {
      error = SEC_E_WRONG_PRINCIPAL;
      break;
    }
    else if (ssl->verify_mode == PN_SSL_VERIFY_PEER_NAME && !server_name) {
      ssl_log_error("Error: configuration error: PN_SSL_VERIFY_PEER_NAME configured, but no peer hostname set!");
      error = SEC_E_WRONG_PRINCIPAL;
      break;
    }
  } while (0);

  if (tracing && !error)
    ssl_log_error("peer certificate authenticated");

  // Lots to clean up.
  if (peer_cc)
    CertFreeCertificateContext(peer_cc);
  if (trust_anchor)
    CertFreeCertificateContext(trust_anchor);
  if (chain_context)
    CertFreeCertificateChain(chain_context);
  free(nameUCS2);
  return error;
}

}
