DWORD AlmacenCertificadoCAPI::eliminarCRL(const ArsCadena &emisor)
{
	DWORD 	ret;
	PCCRL_CONTEXT crl;
	LPBYTE	bytesEmisor, emisorActual;
	DWORD	lenBytesEmisor, lenEmisorActual;
	bool	error, terminado, esEmisorBuscado;

	if (handle != NULL && emisor != "")
	{
		// convierto el emisor
		lenBytesEmisor = emisor.longitud() / 2;
		bytesEmisor = new BYTE[lenBytesEmisor];
		ConversorDatos::StrToByte(emisor, bytesEmisor, lenBytesEmisor);

		// cargar y recorrer las CRLs disponibles dentro del almacén
		crl = NULL;
		ret = 0;
		error = false;
		do
		{
			crl = CertEnumCRLsInStore(handle, crl);
			terminado = (crl == NULL);

			if (!terminado)
			{
				emisorActual = crl->pCrlInfo->Issuer.pbData;
				lenEmisorActual = crl->pCrlInfo->Issuer.cbData;

				esEmisorBuscado  = lenEmisorActual == lenBytesEmisor;
				esEmisorBuscado &=  (0 == memcmp(emisorActual, bytesEmisor, lenBytesEmisor));

				if (esEmisorBuscado)
				{
					if (CertDeleteCRLFromStore(crl))
					{
						ret++;
						// para reiniciar la búsqueda.
						crl = NULL;
					}
					else
					{
						error = true;
						terminado = true;
					}
				}
			}
		}
		while (!terminado);

		if (error)
			ret = (DWORD) -2;

		delete [] bytesEmisor;
	}
	else
		ret = (DWORD) -1;

	return (ret);
}
Пример #2
0
PCCRL_CONTEXT WINAPI CertFindCRLInStore(HCERTSTORE hCertStore,
 DWORD dwCertEncodingType, DWORD dwFindFlags, DWORD dwFindType,
 const void *pvFindPara, PCCRL_CONTEXT pPrevCrlContext)
{
    PCCRL_CONTEXT ret;
    CrlCompareFunc compare;

    TRACE("(%p, %d, %d, %d, %p, %p)\n", hCertStore, dwCertEncodingType,
	 dwFindFlags, dwFindType, pvFindPara, pPrevCrlContext);

    switch (dwFindType)
    {
    case CRL_FIND_ANY:
        compare = compare_crl_any;
        break;
    case CRL_FIND_ISSUED_BY:
        compare = compare_crl_issued_by;
        break;
    case CRL_FIND_EXISTING:
        compare = compare_crl_existing;
        break;
    case CRL_FIND_ISSUED_FOR:
        compare = compare_crl_issued_for;
        break;
    default:
        FIXME("find type %08x unimplemented\n", dwFindType);
        compare = NULL;
    }

    if (compare)
    {
        BOOL matches = FALSE;

        ret = pPrevCrlContext;
        do {
            ret = CertEnumCRLsInStore(hCertStore, ret);
            if (ret)
                matches = compare(ret, dwFindType, dwFindFlags, pvFindPara);
        } while (ret != NULL && !matches);
        if (!ret)
            SetLastError(CRYPT_E_NOT_FOUND);
    }
    else
    {
        SetLastError(CRYPT_E_NOT_FOUND);
        ret = NULL;
    }
    return ret;
}
Пример #3
0
static BOOL CRYPT_SavePKCSToMem(HCERTSTORE store,
 DWORD dwMsgAndCertEncodingType, void *handle)
{
    CERT_BLOB *blob = handle;
    CRYPT_SIGNED_INFO signedInfo = { 0 };
    PCCERT_CONTEXT cert = NULL;
    PCCRL_CONTEXT crl = NULL;
    DWORD size;
    BOOL ret = TRUE;

    TRACE("(%d, %p)\n", blob->pbData ? blob->cbData : 0, blob->pbData);

    do {
        cert = CertEnumCertificatesInStore(store, cert);
        if (cert)
            signedInfo.cCertEncoded++;
    } while (cert);
    if (signedInfo.cCertEncoded)
    {
        signedInfo.rgCertEncoded = CryptMemAlloc(
         signedInfo.cCertEncoded * sizeof(CERT_BLOB));
        if (!signedInfo.rgCertEncoded)
        {
            SetLastError(ERROR_OUTOFMEMORY);
            ret = FALSE;
        }
        else
        {
            DWORD i = 0;

            do {
                cert = CertEnumCertificatesInStore(store, cert);
                if (cert)
                {
                    signedInfo.rgCertEncoded[i].cbData = cert->cbCertEncoded;
                    signedInfo.rgCertEncoded[i].pbData = cert->pbCertEncoded;
                    i++;
                }
            } while (cert);
        }
    }

    do {
        crl = CertEnumCRLsInStore(store, crl);
        if (crl)
            signedInfo.cCrlEncoded++;
    } while (crl);
    if (signedInfo.cCrlEncoded)
    {
        signedInfo.rgCrlEncoded = CryptMemAlloc(
         signedInfo.cCrlEncoded * sizeof(CERT_BLOB));
        if (!signedInfo.rgCrlEncoded)
        {
            SetLastError(ERROR_OUTOFMEMORY);
            ret = FALSE;
        }
        else
        {
            DWORD i = 0;

            do {
                crl = CertEnumCRLsInStore(store, crl);
                if (crl)
                {
                    signedInfo.rgCrlEncoded[i].cbData = crl->cbCrlEncoded;
                    signedInfo.rgCrlEncoded[i].pbData = crl->pbCrlEncoded;
                    i++;
                }
            } while (crl);
        }
    }
    if (ret)
    {
        ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, NULL, &size);
        if (ret)
        {
            if (!blob->pbData)
                blob->cbData = size;
            else if (blob->cbData < size)
            {
                blob->cbData = size;
                SetLastError(ERROR_MORE_DATA);
                ret = FALSE;
            }
            else
            {
                blob->cbData = size;
                ret = CRYPT_AsnEncodeCMSSignedInfo(&signedInfo, blob->pbData,
                 &blob->cbData);
            }
        }
    }
    CryptMemFree(signedInfo.rgCertEncoded);
    CryptMemFree(signedInfo.rgCrlEncoded);
    TRACE("returning %d\n", ret);
    return ret;
}
Пример #4
0
static void test_crypt_ui_wiz_import(void)
{
    BOOL ret;
    CRYPTUI_WIZ_IMPORT_SRC_INFO info;
    HCERTSTORE store;
    PCCERT_CONTEXT cert;
    PCCRL_CONTEXT crl;
    DWORD count;

    if (!pCryptUIWizImport)
    {
        skip("No CryptUIWizImport\n");
        return;
    }

    /* Set CBT hook to disallow MessageBox and wizard creation in current
     * thread.
     */
    hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());

    /* Brings up UI.  Cancelling yields ret = 1. */
    if (0)
    {
        pCryptUIWizImport(0, 0, NULL, NULL, NULL);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, NULL, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    memset(&info, 0, sizeof(info));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSize = sizeof(info);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    /* Check allowed vs. given type mismatches */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCertificateContext(info.u.pCertContext);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT;
    info.u.pCRLContext = CertCreateCRLContext(X509_ASN_ENCODING,
     signedCRL, sizeof(signedCRL));
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, NULL);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertFreeCRLContext(info.u.pCRLContext);
    /* Imports the following cert--self-signed, with no basic constraints set--
     * to the CA store.  Puts up a dialog at the end if it succeeds or fails.
     */
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT;
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find v1CertWithValidPubKey in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);
    /* Imports the following cert--not self-signed, with a basic constraints2
     * extensions--to the "AddressBook" store.  Puts up a dialog at the end if
     * it succeeds or fails.
     */
    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert3, sizeof(iTunesCert3));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert3 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    /* Displays the wizard, but disables the "Certificate store" edit and
     * the Browse button.  Confusingly, the "Place all certificates in the
     * following store" radio button is not disabled.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, NULL);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, X509_ASN_ENCODING, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    /* Displays the wizard, but sets the "Certificate store" edit to the
     * string "Determined by the program", and disables it and the Browse
     * button, as well as the "Automatically select the certificate store
     * based on the type of certificate" radio button.
     */
    if (0)
    {
        ret = pCryptUIWizImport(CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0,
         NULL, &info, store);
        ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    }
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE, 0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    ret = find_and_delete_cert_in_store(store, info.u.pCertContext);
    ok(ret ||
     broken(!ret) /* Win9x/NT4 */,
     "expected to find iTunesCert3 in memory store\n");
    CertFreeCertificateContext(info.u.pCertContext);
    CertCloseStore(store, 0);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert1, sizeof(iTunesCert1));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
         'B','o','o','k',0 };
        HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);

        if (addressBook)
        {
            ret = find_and_delete_cert_in_store(addressBook,
             info.u.pCertContext);
            ok(ret ||
             broken(!ret),  /* Windows 2000 and earlier */
             "expected to find iTunesCert1 in AddressBook store\n");
            CertCloseStore(addressBook, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
     iTunesCert2, sizeof(iTunesCert2));
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI, 0, NULL, &info, NULL);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        static const WCHAR CA[] = { 'C','A',0 };
        HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
         CERT_SYSTEM_STORE_CURRENT_USER, CA);

        if (ca)
        {
            ret = find_and_delete_cert_in_store(ca, info.u.pCertContext);
            ok(ret ||
             broken(!ret) /* Win9x/NT4 */,
             "expected to find iTunesCert2 in CA store\n");
            CertCloseStore(ca, 0);
        }
    }
    CertFreeCertificateContext(info.u.pCertContext);

    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    info.dwSubjectChoice = CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE;
    /* The ALLOW flags aren't allowed with a store as the source if the source
     * contains types other than those allowed.
     */
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI |
     CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE |
     CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL, 0, NULL,
     &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* If the ALLOW flags match the content of the store, the store can be
     * imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCertificateToStore(info.u.hCertStore, X509_ASN_ENCODING,
     v1CertWithValidPubKey, sizeof(v1CertWithValidPubKey),
     CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 1, "expected 1 cert, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 0, "expected 0 CRLs, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    /* Again, if the ALLOW flags match the content of the store, the store can
     * be imported.
     */
    info.u.hCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    CertAddEncodedCRLToStore(info.u.hCertStore, X509_ASN_ENCODING, signedCRL,
     sizeof(signedCRL), CERT_STORE_ADD_ALWAYS, NULL);
    store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
     CERT_STORE_CREATE_NEW_FLAG, NULL);
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CRL,
     0, NULL, &info, store);
    ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
    if (ret)
    {
        count = 0;
        cert = NULL;
        do {
            cert = CertEnumCertificatesInStore(store, cert);
            if (cert)
                count++;
        } while (cert);
        ok(count == 0, "expected 0 certs, got %d\n", count);
        count = 0;
        crl = NULL;
        do {
            crl = CertEnumCRLsInStore(store, crl);
            if (crl)
                count++;
        } while (crl);
        ok(count == 1, "expected 1 CRL, got %d\n", count);
    }
    SetLastError(0xdeadbeef);
    ret = pCryptUIWizImport(CRYPTUI_WIZ_NO_UI | CRYPTUI_WIZ_IMPORT_ALLOW_CERT,
     0, NULL, &info, store);
    ok(!ret && GetLastError() == E_INVALIDARG,
     "expected E_INVALIDARG, got %08x\n", GetLastError());
    CertCloseStore(store, 0);
    CertCloseStore(info.u.hCertStore, 0);

    UnhookWindowsHookEx(hook);
}
Пример #5
0
my_bool ma_schannel_verify_certs(SC_CTX *sctx, DWORD dwCertFlags)
{
  SECURITY_STATUS sRet;
  DWORD flags;
  MARIADB_PVIO *pvio= sctx->mysql->net.pvio;
  PCCERT_CONTEXT pServerCert= NULL;
  PCCERT_CONTEXT ca_CTX = NULL;
  PCCRL_CONTEXT crl_CTX = NULL;
  my_bool is_Ok = 0;

  if ((sRet= QueryContextAttributes(&sctx->ctxt, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pServerCert)) != SEC_E_OK)
  {
    ma_schannel_set_sec_error(pvio, sRet);
    return 0;
  }

  if (ca_Check)
  {
    flags = CERT_STORE_SIGNATURE_FLAG |
      CERT_STORE_TIME_VALIDITY_FLAG;

    while ((ca_CTX = CertFindCertificateInStore(ca_CertStore, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
      0, CERT_FIND_ANY, 0, ca_CTX)) && !is_Ok)
    {
      if (sRet = CertVerifySubjectCertificateContext(pServerCert, ca_CTX, &flags))
        is_Ok = 1;
    }

    if (ca_CTX)
      CertFreeCertificateContext(ca_CTX);

    if (!is_Ok)
    {
      ma_schannel_set_win_error(pvio);
      return 0;
    }

    if (flags)
    {
      if ((flags & CERT_STORE_SIGNATURE_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Certificate signature check failed");
      else if ((flags & CERT_STORE_REVOCATION_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "certificate was revoked");
      else if ((flags & CERT_STORE_TIME_VALIDITY_FLAG) != 0)
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "certificate has expired");
      else
        pvio->set_error(sctx->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "Unknown error during certificate validation");
      return 0;
    }
  }

  /* Check if none of the certificates in the certificate chain have been revoked. */
  if (crl_Check)
  {
    while ((crl_CTX = CertEnumCRLsInStore(crl_CertStore, crl_CTX)))
    {
      PCRL_INFO Info[1];

      Info[0] = crl_CTX->pCrlInfo;
      if (!(CertVerifyCRLRevocation(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
        pServerCert->pCertInfo,
        1, Info)))
      {
        CertFreeCRLContext(crl_CTX);
        pvio->set_error(pvio->mysql, CR_SSL_CONNECTION_ERROR, SQLSTATE_UNKNOWN, "CRL Revocation failed");
        return 0;
      }
    }
    CertFreeCRLContext(crl_CTX);
  }
  return 1;
}