bool AlmacenCertificadoCAPI::almacenarCRL(const ArsCadena &nombreFichero, const void* datos, DWORD lenDatos) { // el nombre del fichero no se usa bool ret; if (handle != NULL && datos != NULL && lenDatos > 0) { ret = (bool) CertAddEncodedCRLToStore(handle, TIPO_CODIFICACION, (BYTE*) datos, lenDatos, CERT_STORE_ADD_REPLACE_EXISTING, NULL); } else ret = false; return (ret); }
static PWINECRYPT_CERTSTORE CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { PWINECRYPT_CERTSTORE store = NULL; HCRYPTMSG msg = (HCRYPTMSG)pvPara; PWINECRYPT_CERTSTORE memStore; TRACE("(%ld, %08x, %p)\n", hCryptProv, dwFlags, pvPara); memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); if (memStore) { BOOL ret; DWORD size, count, i; size = sizeof(count); ret = CryptMsgGetParam(msg, CMSG_CERT_COUNT_PARAM, 0, &count, &size); for (i = 0; ret && i < count; i++) { size = 0; ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, NULL, &size); if (ret) { LPBYTE buf = CryptMemAlloc(size); if (buf) { ret = CryptMsgGetParam(msg, CMSG_CERT_PARAM, i, buf, &size); if (ret) ret = CertAddEncodedCertificateToStore(memStore, X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, NULL); CryptMemFree(buf); } } } size = sizeof(count); ret = CryptMsgGetParam(msg, CMSG_CRL_COUNT_PARAM, 0, &count, &size); for (i = 0; ret && i < count; i++) { size = 0; ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, NULL, &size); if (ret) { LPBYTE buf = CryptMemAlloc(size); if (buf) { ret = CryptMsgGetParam(msg, CMSG_CRL_PARAM, i, buf, &size); if (ret) ret = CertAddEncodedCRLToStore(memStore, X509_ASN_ENCODING, buf, size, CERT_STORE_ADD_ALWAYS, NULL); CryptMemFree(buf); } } } if (ret) { CERT_STORE_PROV_INFO provInfo = { 0 }; provInfo.cbSize = sizeof(provInfo); provInfo.cStoreProvFunc = sizeof(msgProvFuncs) / sizeof(msgProvFuncs[0]); provInfo.rgpvStoreProvFunc = msgProvFuncs; provInfo.hStoreProv = CryptMsgDuplicate(msg); store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo); /* Msg store doesn't need crypto provider, so close it */ if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(hCryptProv, 0); } else CertCloseStore(memStore, 0); } TRACE("returning %p\n", store); return store; }
int _tmain(int argc, _TCHAR* argv[]) { LONG retval; Params p; LPVOID cert, crl; DWORD certSz = 0, crlSz = 0, index = 0, disp = 0; HKEY rootKey = NULL, storesKey = NULL, key = NULL; HCERTSTORE hCertStore = NULL; TCHAR root[MAX_REG_KEY_LEN]; // Get params if (!GetParams(&p, argc, argv)) { _tprintf(TEXT("Usage:\n")); _tprintf(TEXT("%s hive crt.cer [/CRL crl.crl] [/Store store]\n\n"), argv[0]); _tprintf(TEXT("hive\ta registry hive for HKLM\\SOFTWARE (user hives not supported)\n")); _tprintf(TEXT(" found at Windows\\System32\\config\\SOFTWARE (cannot use be an in-use hive)\n")); _tprintf(TEXT("crt.cer\tthe certificate to import\n")); _tprintf(TEXT("crl.crl\tif provided adds a CRL as well\n")); _tprintf(TEXT("store\tthe store to import to, defaults to ROOT\n\n")); return -1; } // Enable privileges if (!EnablePriv(SE_TAKE_OWNERSHIP_NAME) || !EnablePriv(SE_BACKUP_NAME) || !EnablePriv(SE_RESTORE_NAME)) { return LastError(TEXT("Failed to enable take ownership, backup, and restore privileges"), NULL); } // Read the certificate file if ((cert = Read(p.cert, &certSz)) == NULL) { return LastError(TEXT("Failed to read certificate file '%s'"), p.cert); } // Read the CRL file if (p.crl && ((crl = Read(p.crl, &crlSz)) == NULL)) { LocalFree(cert); return LastError(TEXT("Failed to read the CRL file '%s'"), p.crl); } // Find a subkey that's available _tcsncpy(root, TEXT("TEMPHIVE"), MAX_REG_KEY_LEN); if ((retval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, root, 0, KEY_READ, &key)) != ERROR_FILE_NOT_FOUND) { if (retval != ERROR_SUCCESS) { LocalFree(crl); LocalFree(cert); return Error(TEXT("Failed to find subkey to load hive"), NULL, retval); } RegCloseKey(key); _sntprintf(root, MAX_REG_KEY_LEN, TEXT("TEMPHIVE%u"), index++); } key = NULL; // Load the hive if ((retval = RegLoadKey(HKEY_LOCAL_MACHINE, root, p.hive)) != ERROR_SUCCESS) { LocalFree(cert); if (crl) LocalFree(crl); return Error(TEXT("Failed to load hive file '%s'"), p.hive, retval); } // Open the HKLM\TEMPHIVE\Microsoft\SystemCertificates if ((retval = RegOpenKeyEx(HKEY_LOCAL_MACHINE, root, 0, KEY_ALL_ACCESS, &rootKey)) != ERROR_SUCCESS) { Error(TEXT("Failed to get root key '%s'"), root, retval); } else if ((retval = RegOpenKeyEx(rootKey, TEXT("Microsoft\\SystemCertificates"), 0, KEY_ALL_ACCESS, &storesKey)) != ERROR_SUCCESS) { Error(TEXT("Failed to get stores key: %u\n"), NULL, retval); // Create/Open the registry certificate store } else if ((retval = RegCreateKeyEx(storesKey, p.store, 0, NULL, REG_OPTION_BACKUP_RESTORE, KEY_ALL_ACCESS, NULL, &key, &disp)) != ERROR_SUCCESS) { Error(TEXT("Failed to create store key '%s'"), p.store, retval); // Open the store } else if ((hCertStore = CertOpenStore(CERT_STORE_PROV_REG, 0, (HCRYPTPROV)NULL, CERT_STORE_BACKUP_RESTORE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, key)) == NULL) { retval = LastError(TEXT("Failed to create certificate store"), NULL); // Add the certificate to the store } else if (!CertAddEncodedCertificateToStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert, certSz, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { retval = LastError(TEXT("Failed add certificate to store"), NULL); // Add the crl to the store } else if (crl && !CertAddEncodedCRLToStore(hCertStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, crl, crlSz, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { retval = LastError(TEXT("Failed add the CRL to store"), NULL); } // Cleanup if (hCertStore) { CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG); } if (key) { RegCloseKey(key); } if (storesKey) { RegCloseKey(storesKey); } if (rootKey) { RegCloseKey(rootKey); } LocalFree(crl); LocalFree(cert); // Unload the hive if ((disp = RegUnLoadKey(HKEY_LOCAL_MACHINE, root)) != ERROR_SUCCESS) { if (retval == ERROR_SUCCESS) { retval = disp; } Error(TEXT("Failed to unload the hive"), NULL, disp); } // Successful? Yeah! if (retval == ERROR_SUCCESS) { if (p.crl) { _tprintf(TEXT("Successfully added %s and %s to the %s store in %s\n\n"), p.cert, p.crl, p.store, p.hive); } else { _tprintf(TEXT("Successfully added %s to the %s store in %s\n\n"), p.cert, p.store, p.hive); } } return retval; }
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); }
static void test_verifyRevocation(void) { HMODULE hCryptNet = GetModuleHandleA("cryptnet.dll"); BOOL ret; CERT_REVOCATION_STATUS status = { sizeof(status), 0 }; PCCERT_CONTEXT certs[2]; CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 }; FILETIME time; pCertVerifyRevocation = (void *)GetProcAddress(hCryptNet, "CertDllVerifyRevocation"); if (!pCertVerifyRevocation) { win_skip("no CertDllVerifyRevocation\n"); return; } if (0) { /* Crash */ pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL); } SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, 0, 0, NULL, 0, NULL, &status); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(X509_ASN_ENCODING, 0, 0, NULL, 0, NULL, &status); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 0, NULL, 0, NULL, &status); ok(!ret && GetLastError() == E_INVALIDARG, "expected E_INVALIDARG, got %08x\n", GetLastError()); certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, sizeof(bigCert)); SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)certs, 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); CertFreeCertificateContext(certs[0]); certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign)); certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, revokedCert, sizeof(revokedCert)); /* The root cert itself can't be checked for revocation */ SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)certs, 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Neither can the end cert */ SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Both certs together can't, either (they're not CRLs) */ SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 2, (void **)certs, 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Now add a CRL to the hCrlStore */ revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING, rootSignedCRLWithBadAKI, sizeof(rootSignedCRLWithBadAKI), CERT_STORE_ADD_ALWAYS, NULL); SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 2, (void **)certs, 0, &revPara, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Specifying CERT_VERIFY_REV_CHAIN_FLAG doesn't change things either */ SetLastError(0xdeadbeef); ret = pCertVerifyRevocation(0, CERT_CONTEXT_REVOCATION_TYPE, 2, (void **)certs, CERT_VERIFY_REV_CHAIN_FLAG, &revPara, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK, "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Again, specifying the issuer cert: no change */ revPara.pIssuerCert = certs[0]; SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); /* Win2k thinks the cert is revoked, and it is, except the CRL contains a * bad authority key ID extension and can't be matched with the issuer * cert, hence the revocation status should be unknown. */ if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND) { win_skip("CERT_CONTEXT_REVOCATION_TYPE unsupported, skipping\n"); return; } ok(!ret && (GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || broken(GetLastError() == CRYPT_E_REVOKED /* Win2k */)), "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || broken(status.dwError == CRYPT_E_REVOKED /* Win2k */), "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); /* Specifying the time to check: still no change */ SystemTimeToFileTime(&oct2007, &time); revPara.pftTimeToUse = &time; ret = pCertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret, "Expected failure\n"); ok(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK || broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */ "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", GetLastError()); ok(status.dwError == CRYPT_E_NO_REVOCATION_CHECK || broken(GetLastError() == CRYPT_E_REVOKED), /* W2K SP3/SP4 */ "expected CRYPT_E_NO_REVOCATION_CHECK, got %08x\n", status.dwError); ok(status.dwIndex == 0, "expected index 0, got %d\n", status.dwIndex); CertCloseStore(revPara.hCrlStore, 0); /* Test again with a valid CRL. This time, the cert should be revoked when * the time is after the validity period of the CRL, or considered * "revocation offline" when the checked time precedes the validity * period of the CRL. */ revPara.hCrlStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); ret = CertAddEncodedCRLToStore(revPara.hCrlStore, X509_ASN_ENCODING, rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL); ok(ret, "CertAddEncodedCRLToStore failed: %08x\n", GetLastError()); revPara.pftTimeToUse = NULL; SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOKED || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOKED, got %08x\n", GetLastError()); revPara.pftTimeToUse = &time; SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOKED || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOKED, got %08x\n", GetLastError()); SystemTimeToFileTime(&may2007, &time); SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); CertFreeCertificateContext(certs[1]); /* Test again with a valid CRL and an un-revoked cert. No matter the * time checked, it's reported as revocation offline. */ certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, unRevokedCert, sizeof(unRevokedCert)); ok(certs[1] != NULL, "CertCreateCertificateContext failed: %08x\n", GetLastError()); revPara.pftTimeToUse = NULL; SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); revPara.pftTimeToUse = &time; SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); SystemTimeToFileTime(&may2007, &time); SetLastError(0xdeadbeef); ret = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, 1, (void **)&certs[1], 0, &revPara, &status); ok(!ret && (GetLastError() == CRYPT_E_REVOCATION_OFFLINE || broken(GetLastError() == CRYPT_E_NO_REVOCATION_CHECK /* NT4 */)), "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); CertCloseStore(revPara.hCrlStore, 0); CertFreeCertificateContext(certs[1]); CertFreeCertificateContext(certs[0]); }