title: AcquireCredentialsHandleA() returns 0x8009030e (No credentials are available in the security package) for PFX file
body: <p>I'm trying to setup server-side encryption using SSPI.  I'm successfully (as far as I can tell) loading a certificate stored as a PFX file, but the call to <code>m_pSSPI-&gt;AcquireCredentialsHandleA()</code> returns <code>0x8009030e</code>.</p>
  <p>This method seems to successfully load the file and return a <code>CERT_CONTEXT</code> object.</p>
  <pre><code>HRESULT CTLSPackage::LoadCertContextFromFilePFX (PCWSTR pcwzFile, PCWSTR pcwzPassword, __deref_out PCCERT_CONTEXT* ppctxCert)
  {
      HRESULT hr;
      HANDLE hFile, hSection = NULL;
      BOOL (WINAPI* pfnPFXIsPFXBlob)(CRYPT_DATA_BLOB*);
      HCERTSTORE (WINAPI* pfnPFXImportCertStore)(CRYPT_DATA_BLOB*, LPCWSTR, DWORD);
      PCCERT_CONTEXT (WINAPI* pfnCertEnumCertificatesInStore)(HCERTSTORE hCertStore, PCCERT_CONTEXT pPrevCertContext);
      CRYPT_DATA_BLOB blob; blob.pbData = NULL;
      HCERTSTORE pfxStore = NULL;
  
      hFile = CreateFile(pcwzFile, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
      CheckIfGetLastError(INVALID_HANDLE_VALUE == hFile);
      blob.cbData = GetFileSize(hFile, NULL);
  
      hSection = CreateFileMapping(hFile, 0, PAGE_READONLY, 0, 0, 0);
      CheckIfGetLastError(NULL == hSection);
  
      blob.pbData = reinterpret_cast&lt;PBYTE&gt;(MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0));
      CheckIfGetLastError(NULL == blob.pbData);
  
      Check(TGetFunction(m_hCrypt32, &quot;PFXIsPFXBlob&quot;, &amp;pfnPFXIsPFXBlob));
      Check(TGetFunction(m_hCrypt32, &quot;PFXImportCertStore&quot;, &amp;pfnPFXImportCertStore));
      Check(TGetFunction(m_hCrypt32, &quot;CertEnumCertificatesInStore&quot;, &amp;pfnCertEnumCertificatesInStore));
  
      CheckIf(!pfnPFXIsPFXBlob(&amp;blob), E_FAIL);
      pfxStore = pfnPFXImportCertStore(&amp;blob, pcwzPassword, CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE);
      CheckIf(NULL == pfxStore, SEC_E_NO_CREDENTIALS);
  
      *ppctxCert = pfnCertEnumCertificatesInStore(pfxStore, NULL);
      CheckIf(NULL == *ppctxCert, SEC_E_NO_CREDENTIALS);
  
  Cleanup:
      if(pfxStore)
      {
          BOOL (WINAPI* pfnCertCloseStore)(HCERTSTORE, DWORD);
          if(SUCCEEDED(TGetFunction(m_hCrypt32, &quot;CertCloseStore&quot;, &amp;pfnCertCloseStore)))
              pfnCertCloseStore(pfxStore, 0);
      }
      if(blob.pbData)
          UnmapViewOfFile(blob.pbData);
      SafeCloseHandle(hSection);
      SafeCloseFileHandle(hFile);
      return hr;
  }
  </code></pre>
  <p>The result is immediately passed to another class method, which makes the failing <code>AcquireCredentialsHandleA()</code> call.</p>
  <pre><code>HRESULT CTLSPackage::AcquireCredentials (__in_opt PCCERT_CONTEXT pCertContext, PCredHandle phCreds)
  {
      SCHANNEL_CRED SchannelCred;
      TimeStamp tsExpiry;
  
      ZeroMemory(&amp;SchannelCred, sizeof(SchannelCred));
  
      SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
      if(pCertContext)
      {
          SchannelCred.cCreds = 1;
          SchannelCred.paCred = &amp;pCertContext;
      }
      SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1 | SP_PROT_TLS1_1 | SP_PROT_TLS1_2;
  
      if(!m_fServer)
          SchannelCred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS | SCH_USE_STRONG_CRYPTO;
  
      //
      // Create an SSPI credential.
      //
  
      return m_pSSPI-&gt;AcquireCredentialsHandleA(
                          NULL,                   // Name of principal
                          m_fServer ? NEGOSSP_NAME_A : UNISP_NAME_A,  // Name of package
                          m_fServer ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
                          NULL,                   // Pointer to logon ID
                          &amp;SchannelCred,          // Package specific data
                          NULL,                   // Pointer to GetKey() func
                          NULL,                   // Value to pass to GetKey()
                          phCreds,                // (out) Cred Handle
                          &amp;tsExpiry);             // (out) Lifetime (optional)
  }
  </code></pre>
  <p>My <code>CTLSPackage::AcquireCredentials()</code> code path is also used for setting up client-side encryption, and that works.  For the server-side path, <code>m_fServer</code> is <code>TRUE</code>.  The <code>m_hCrypt32</code> member was loaded from <code>Crypt32.dll</code>.</p>
  <p>I've cobbled together this code from samples, but I must be missing something for the server case.  I only need to setup SSL/TLS-style encryption, so the &quot;No credentials are available in the security package&quot; error is weird because I have no need for credential authentication.</p>
  <p>Does anyone know what might be missing?  Thanks!</p>