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); }
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; }
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; }
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); }
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; }