diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c index 0bc4fda24c8..c42bb18d6e4 100644 --- a/dlls/crypt32/tests/cert.c +++ b/dlls/crypt32/tests/cert.c @@ -3064,12 +3064,97 @@ static void testVerifySubjectCert(void) CertFreeCertificateContext(context1); } +static const BYTE rootWithKeySignAndCRLSign[] = { +0x30,0x82,0x01,0xdf,0x30,0x82,0x01,0x4c,0xa0,0x03,0x02,0x01,0x02,0x02,0x10, +0x5b,0xc7,0x0b,0x27,0x99,0xbb,0x2e,0x99,0x47,0x9d,0x45,0x4e,0x7c,0x1a,0xca, +0xe8,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x10,0x31, +0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31, +0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30, +0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35, +0x39,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05, +0x43,0x65,0x72,0x74,0x31,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48, +0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00,0x30,0x81,0x89, +0x02,0x81,0x81,0x00,0xad,0x7e,0xca,0xf3,0xe5,0x99,0xc2,0x2a,0xca,0x50,0x82, +0x7c,0x2d,0xa4,0x81,0xcd,0x0d,0x0d,0x86,0xd7,0xd8,0xb2,0xde,0xc5,0xc3,0x34, +0x9e,0x07,0x78,0x08,0x11,0x12,0x2d,0x21,0x0a,0x09,0x07,0x14,0x03,0x7a,0xe7, +0x3b,0x58,0xf1,0xde,0x3e,0x01,0x25,0x93,0xab,0x8f,0xce,0x1f,0xc1,0x33,0x91, +0xfe,0x59,0xb9,0x3b,0x9e,0x95,0x12,0x89,0x8e,0xc3,0x4b,0x98,0x1b,0x99,0xc5, +0x07,0xe2,0xdf,0x15,0x4c,0x39,0x76,0x06,0xad,0xdb,0x16,0x06,0x49,0xba,0xcd, +0x0f,0x07,0xd6,0xea,0x27,0xa6,0xfe,0x3d,0x88,0xe5,0x97,0x45,0x72,0xb6,0x1c, +0xc0,0x1c,0xb1,0xa2,0x89,0xe8,0x37,0x9e,0xf6,0x2a,0xcf,0xd5,0x1f,0x2f,0x35, +0x5e,0x8f,0x3a,0x9c,0x61,0xb1,0xf1,0x6c,0xff,0x8c,0xb2,0x2f,0x02,0x03,0x01, +0x00,0x01,0xa3,0x42,0x30,0x40,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01, +0xff,0x04,0x04,0x03,0x02,0x00,0x06,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01, +0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d, +0x0e,0x04,0x16,0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0, +0x58,0xff,0x98,0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x09,0x06,0x05,0x2b, +0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x81,0x81,0x00,0x74,0xcb,0x21,0xfd,0x2d, +0x25,0xdc,0xa5,0xaa,0xa1,0x26,0xdc,0x8b,0x40,0x11,0x64,0xae,0x5c,0x71,0x3c, +0x28,0xbc,0xf9,0xb3,0xcb,0xa5,0x94,0xb2,0x8d,0x4c,0x23,0x2b,0x9b,0xde,0x2c, +0x4c,0x30,0x04,0xc6,0x88,0x10,0x2f,0x53,0xfd,0x6c,0x82,0xf1,0x13,0xfb,0xda, +0x27,0x75,0x25,0x48,0xe4,0x72,0x09,0x2a,0xee,0xb4,0x1e,0xc9,0x55,0xf5,0xf7, +0x82,0x91,0xd8,0x4b,0xe4,0x3a,0xfe,0x97,0x87,0xdf,0xfb,0x15,0x5a,0x12,0x3e, +0x12,0xe6,0xad,0x40,0x0b,0xcf,0xee,0x1a,0x44,0xe0,0x83,0xb2,0x67,0x94,0xd4, +0x2e,0x7c,0xf2,0x06,0x9d,0xb3,0x3b,0x7e,0x2f,0xda,0x25,0x66,0x7e,0xa7,0x1f, +0x45,0xd4,0xf5,0xe3,0xdf,0x2a,0xf1,0x18,0x28,0x20,0xb5,0xf8,0xf5,0x8d,0x7a, +0x2e,0x84,0xee }; +static const BYTE eeCert[] = { +0x30,0x82,0x01,0x93,0x30,0x81,0xfd,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, +0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, +0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65, +0x72,0x74,0x31,0x30,0x1e,0x17,0x0d,0x30,0x37,0x30,0x35,0x30,0x31,0x30,0x30, +0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x37,0x31,0x30,0x30,0x31,0x30,0x30, +0x30,0x30,0x30,0x30,0x5a,0x30,0x10,0x31,0x0e,0x30,0x0c,0x06,0x03,0x55,0x04, +0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x32,0x30,0x81,0x9f,0x30,0x0d,0x06,0x09, +0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8d,0x00, +0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xb8,0x52,0xda,0xc5,0x4b,0x3f,0xe5,0x33, +0x0e,0x67,0x5f,0x48,0x21,0xdc,0x7e,0xef,0x37,0x33,0xba,0xff,0xb4,0xc6,0xdc, +0xb6,0x17,0x8e,0x20,0x55,0x07,0x12,0xd2,0x7b,0x3c,0xce,0x30,0xc5,0xa7,0x48, +0x9f,0x6e,0xfe,0xb8,0xbe,0xdb,0x9f,0x9b,0x17,0x60,0x16,0xde,0xc6,0x8b,0x47, +0xd1,0x57,0x71,0x3c,0x93,0xfc,0xbd,0xec,0x44,0x32,0x3b,0xb9,0xcf,0x6b,0x05, +0x72,0xa7,0x87,0x8e,0x7e,0xd4,0x9a,0x87,0x1c,0x2f,0xb7,0x82,0x40,0xfc,0x6a, +0x80,0x83,0x68,0x28,0xce,0x84,0xf4,0x0b,0x2e,0x44,0xcb,0x53,0xac,0x85,0x85, +0xb5,0x46,0x36,0x98,0x3c,0x10,0x02,0xaa,0x02,0xbc,0x8b,0xa2,0x23,0xb2,0xd3, +0x51,0x9a,0x22,0x4a,0xe3,0xaa,0x4e,0x7c,0xda,0x38,0xcf,0x49,0x98,0x72,0xa3, +0x02,0x03,0x01,0x00,0x01,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d, +0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x22,0xf1,0x66,0x00,0x79,0xd2, +0xe6,0xb2,0xb2,0xf7,0x2f,0x98,0x92,0x7d,0x73,0xc3,0x6c,0x5c,0x77,0x20,0xe3, +0xbf,0x3e,0xe0,0xb3,0x5c,0x68,0xb4,0x9b,0x3a,0x41,0xae,0x94,0xa0,0x80,0x3a, +0xfe,0x5d,0x7a,0x56,0x87,0x85,0x44,0x45,0xcf,0xa6,0xd3,0x10,0xe7,0x73,0x41, +0xf2,0x7f,0x88,0x85,0x91,0x8e,0xe6,0xec,0xe2,0xce,0x08,0xbc,0xa5,0x76,0xe5, +0x4d,0x1d,0xb7,0x70,0x31,0xdd,0xc9,0x9a,0x15,0x32,0x11,0x5a,0x4e,0x62,0xc8, +0xd1,0xf8,0xec,0x46,0x39,0x5b,0xe7,0x67,0x1f,0x58,0xe8,0xa1,0xa0,0x5b,0xf7, +0x8a,0x6d,0x5f,0x91,0x18,0xd4,0x90,0x85,0xff,0x30,0xc7,0xca,0x9c,0xc6,0x92, +0xb0,0xca,0x16,0xc4,0xa4,0xc0,0xd6,0xe8,0xff,0x15,0x19,0xd1,0x30,0x61,0xf3, +0xef,0x9f }; +static const BYTE rootSignedCRL[] = { +0x30,0x82,0x01,0x1d,0x30,0x81,0x87,0x02,0x01,0x01,0x30,0x0d,0x06,0x09,0x2a, +0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x10,0x31,0x0e,0x30, +0x0c,0x06,0x03,0x55,0x04,0x03,0x13,0x05,0x43,0x65,0x72,0x74,0x31,0x17,0x0d, +0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d, +0x30,0x37,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30,0x14, +0x30,0x12,0x02,0x01,0x01,0x17,0x0d,0x30,0x37,0x30,0x39,0x30,0x31,0x30,0x30, +0x30,0x30,0x30,0x30,0x5a,0xa0,0x2d,0x30,0x2b,0x30,0x0a,0x06,0x03,0x55,0x1d, +0x14,0x04,0x03,0x02,0x01,0x01,0x30,0x1d,0x06,0x03,0x55,0x1d,0x23,0x04,0x16, +0x04,0x14,0x14,0x8c,0x16,0xbb,0xbe,0x70,0xa2,0x28,0x89,0xa0,0x58,0xff,0x98, +0xbd,0xa8,0x24,0x2b,0x8a,0xe9,0x9a,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, +0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9b,0x2b,0x99,0x0d, +0x16,0x83,0x93,0x54,0x29,0x3a,0xa6,0x53,0x5d,0xf8,0xa6,0x73,0x9f,0x2a,0x45, +0x39,0x91,0xff,0x91,0x1c,0x27,0x06,0xe8,0xdb,0x72,0x3f,0x66,0x89,0x15,0x68, +0x55,0xd5,0x49,0x63,0xa6,0x00,0xe9,0x66,0x9c,0x97,0xf9,0xb3,0xb3,0x2b,0x1b, +0xc7,0x79,0x46,0xa8,0xd8,0x2b,0x78,0x27,0xa0,0x70,0x02,0x81,0xc6,0x40,0xb3, +0x76,0x32,0x65,0x4c,0xf8,0xff,0x1d,0x41,0x6e,0x16,0x09,0xa2,0x8a,0x7b,0x0c, +0xd0,0xa6,0x9b,0x61,0xa3,0x7c,0x02,0x91,0x79,0xdf,0x6a,0x5e,0x88,0x95,0x66, +0x33,0x17,0xcb,0x5a,0xd2,0xdc,0x89,0x05,0x62,0x97,0x60,0x73,0x7b,0x2c,0x1a, +0x90,0x20,0x73,0x24,0x9f,0x45,0x22,0x4b,0xc1,0x33,0xd1,0xda,0xd8,0x7e,0x1b, +0x3d,0x74,0xd6,0x3b }; + static void testVerifyRevocation(void) { BOOL ret; CERT_REVOCATION_STATUS status = { 0 }; - PCCERT_CONTEXT cert = CertCreateCertificateContext(X509_ASN_ENCODING, - bigCert, sizeof(bigCert)); + PCCERT_CONTEXT certs[2]; + CERT_REVOCATION_PARA revPara = { sizeof(revPara), 0 }; /* Crash ret = CertVerifyRevocation(0, 0, 0, NULL, 0, NULL, NULL); @@ -3085,16 +3170,87 @@ static void testVerifyRevocation(void) ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); ret = CertVerifyRevocation(2, 0, 0, NULL, 0, NULL, &status); ok(ret, "CertVerifyRevocation failed: %08x\n", GetLastError()); + certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, bigCert, + sizeof(bigCert)); SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(0, 0, 1, (void **)&cert, 0, NULL, &status); + ret = CertVerifyRevocation(0, 0, 1, (void **)certs, 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); SetLastError(0xdeadbeef); - ret = CertVerifyRevocation(0, 2, 1, (void **)&cert, 0, NULL, &status); + ret = CertVerifyRevocation(0, 2, 1, (void **)certs, 0, NULL, &status); ok(!ret && GetLastError() == CRYPT_E_NO_REVOCATION_DLL, "Expected CRYPT_E_NO_REVOCATION_DLL, got %08x\n", GetLastError()); - CertFreeCertificateContext(cert); + CertFreeCertificateContext(certs[0]); + + certs[0] = CertCreateCertificateContext(X509_ASN_ENCODING, + rootWithKeySignAndCRLSign, sizeof(rootWithKeySignAndCRLSign)); + certs[1] = CertCreateCertificateContext(X509_ASN_ENCODING, + eeCert, sizeof(eeCert)); + /* The root cert itself can't be checked for revocation */ + SetLastError(0xdeadbeef); + ret = CertVerifyRevocation(X509_ASN_ENCODING, 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 = CertVerifyRevocation(X509_ASN_ENCODING, CERT_CONTEXT_REVOCATION_TYPE, + 1, (void **)&certs[1], 0, NULL, &status); + todo_wine + ok(!ret && GetLastError() == CRYPT_E_REVOCATION_OFFLINE, + "expected CRYPT_E_REVOCATION_OFFLINE, got %08x\n", GetLastError()); + todo_wine + ok(status.dwError == CRYPT_E_REVOCATION_OFFLINE, + "expected CRYPT_E_REVOCATION_OFFLINE, 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 = CertVerifyRevocation(X509_ASN_ENCODING, 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, + rootSignedCRL, sizeof(rootSignedCRL), CERT_STORE_ADD_ALWAYS, NULL); + SetLastError(0xdeadbeef); + ret = CertVerifyRevocation(X509_ASN_ENCODING, 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 = CertVerifyRevocation(X509_ASN_ENCODING, 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); + 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); + CertCloseStore(revPara.hCrlStore, 0); + CertFreeCertificateContext(certs[1]); + CertFreeCertificateContext(certs[0]); } static BYTE privKey[] = {