dssenh/tests: Added signature tests on the DSSENH cryptographic service provider.
This commit is contained in:
parent
0dab059797
commit
681af11ee1
|
@ -742,6 +742,256 @@ static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
|
|||
ok(result, "Expected release of the provider.\n");
|
||||
}
|
||||
|
||||
struct signature_test {
|
||||
const BYTE *privateKey;
|
||||
DWORD keyLen;
|
||||
BYTE* signData;
|
||||
DWORD dataLen;
|
||||
};
|
||||
|
||||
static const char dataToSign1[] = "Put your hands up for Cryptography :)";
|
||||
static const char dataToSign2[] = "With DSSENH implemented, applications requiring it will now work.";
|
||||
static const char dataToSign3[] = "";
|
||||
|
||||
static const BYTE AT_SIGNATURE_PrivateKey[] = {
|
||||
0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
|
||||
0x01,0xd1,0xfc,0x7a,0x70,0x53,0xb2,0x48, 0x70,0x23,0x19,0x1f,0x3c,0xe1,0x26,0x14,
|
||||
0x7e,0x9f,0x0f,0x7f,0x33,0x5e,0x2b,0xf7, 0xca,0x01,0x74,0x8c,0xb4,0xfd,0xf6,0x44,
|
||||
0x95,0x35,0x56,0xaa,0x4d,0x62,0x48,0xe2, 0xd1,0xa2,0x7e,0x6e,0xeb,0xd6,0xcc,0x7c,
|
||||
0xe8,0xfd,0x21,0x9a,0xa2,0xfd,0x7a,0x9d, 0x1a,0x38,0x69,0x87,0x39,0x5a,0x91,0xc0,
|
||||
0x52,0x2b,0x9f,0x2a,0x54,0x78,0x37,0x82, 0x9a,0x70,0x57,0xab,0xec,0x93,0x8e,0xac,
|
||||
0x73,0x04,0xe8,0x53,0x72,0x72,0x32,0xc6, 0xcb,0xef,0x47,0x98,0x3c,0x56,0x49,0x62,
|
||||
0xcb,0xbb,0xe7,0x34,0x84,0xa6,0x72,0x3a, 0xbe,0x26,0x46,0x86,0xca,0xcb,0x35,0x62,
|
||||
0x4f,0x19,0x18,0x0b,0xb0,0x78,0xae,0xd5, 0x42,0xdf,0x26,0xdb,0x85,0x63,0x77,0x85,
|
||||
0x01,0x3b,0x32,0xbe,0x5c,0xf8,0x05,0xc8, 0xde,0x17,0x7f,0xb9,0x03,0x82,0xfa,0xf1,
|
||||
0x9e,0x32,0x73,0xfa,0x8d,0xea,0xa3,0x30, 0x48,0xe2,0xdf,0x5a,0xcb,0x83,0x3d,0xff,
|
||||
0x56,0xe9,0xc0,0x94,0xf8,0x6d,0xb3,0xaf, 0x4a,0x97,0xb9,0x43,0x0e,0xd4,0x28,0x98,
|
||||
0x57,0x2e,0x3a,0xca,0xde,0x6f,0x45,0x0d, 0xfb,0x58,0xec,0x78,0x34,0x2e,0x46,0x4d,
|
||||
0xfe,0x98,0x02,0xbb,0xef,0x07,0x1a,0x13, 0xb6,0xc2,0x2c,0x06,0xd9,0x0c,0xc4,0xb0,
|
||||
0x4c,0x3a,0xfc,0x01,0x63,0xb5,0x5a,0x5d, 0x2d,0x9c,0x47,0x04,0x67,0x51,0xf2,0x52,
|
||||
0xf5,0x82,0x36,0xeb,0x6e,0x66,0x58,0x4c, 0x10,0x2c,0x29,0x72,0x4a,0x6f,0x6b,0x6c,
|
||||
0xe0,0x93,0x31,0x42,0xf6,0xda,0xfa,0x5b, 0x22,0x43,0x9b,0x1a,0x98,0x71,0xe7,0x41,
|
||||
0x74,0xe9,0x12,0xa4,0x1f,0x27,0x0a,0x63, 0x94,0x49,0xd7,0xad,0xa5,0xc4,0x5c,0xc3,
|
||||
0xc9,0x70,0xb3,0x7b,0x16,0xb6,0x1d,0xd4, 0x09,0xc4,0x9a,0x46,0x2d,0x0e,0x75,0x07,
|
||||
0x31,0x7b,0xed,0x45,0xcd,0x99,0x84,0x14, 0xf1,0x01,0x00,0x00,0x93,0xd5,0xa3,0xe4,
|
||||
0x34,0x05,0xeb,0x98,0x3b,0x5f,0x2f,0x11, 0xa4,0xa5,0xc4,0xff,0xfb,0x22,0x7c,0x54
|
||||
};
|
||||
|
||||
static const BYTE DSS_SIGN_PrivateKey[] = {
|
||||
0x07,0x02,0x00,0x00,0x00,0x22,0x00,0x00, 0x44,0x53,0x53,0x32,0x00,0x04,0x00,0x00,
|
||||
0xf7,0x9e,0x89,0xa2,0xcd,0x0b,0x61,0xe0, 0xa3,0xe5,0x86,0x6b,0x04,0x98,0x80,0x9c,
|
||||
0x36,0xc2,0x76,0x4e,0x22,0xd5,0x21,0xaa, 0x03,0x59,0xf4,0x95,0xb2,0x11,0x1f,0xa0,
|
||||
0xc5,0xfc,0xbe,0x5d,0x1f,0x2e,0xf4,0x36, 0x40,0x48,0x81,0x51,0xb4,0x25,0x86,0xe0,
|
||||
0x98,0xc8,0x4d,0xa0,0x08,0x99,0xa1,0x00, 0x45,0x1b,0x75,0x6b,0x0d,0x3e,0x7d,0x13,
|
||||
0xd7,0x23,0x32,0x08,0xf4,0xeb,0x27,0x9e, 0xe9,0x05,0x5d,0xac,0xc8,0xd7,0x62,0x13,
|
||||
0x43,0x2a,0x69,0x65,0xdc,0xe6,0x52,0xf9, 0x6a,0xe8,0x07,0xcf,0x3e,0xf8,0xc9,0x1d,
|
||||
0x8e,0xdf,0x4e,0x9a,0xd1,0x48,0xf2,0xda, 0x9e,0xfa,0x92,0x5f,0x6d,0x57,0xf2,0xa4,
|
||||
0x5f,0x60,0xce,0x92,0x7a,0x80,0x39,0x21, 0x9d,0x4d,0x3a,0x60,0x76,0x4c,0x2f,0xc0,
|
||||
0xd3,0xf4,0x14,0x03,0x03,0x05,0xa9,0x0c, 0x57,0x72,0x4f,0x60,0x3c,0xe9,0x09,0x54,
|
||||
0x0c,0x2a,0x56,0xda,0x30,0xb6,0x2e,0x6a, 0x96,0x7f,0x4a,0x8f,0x83,0x0a,0xb9,0x5c,
|
||||
0xff,0x84,0xfa,0x0e,0x85,0x81,0x46,0xe9, 0x1c,0xbb,0x78,0x1d,0x78,0x25,0x00,0x8c,
|
||||
0x78,0x56,0x68,0xe4,0x06,0x37,0xcc,0xc7, 0x22,0x27,0xee,0x0e,0xf8,0xca,0xfc,0x72,
|
||||
0x0e,0xd6,0xe6,0x90,0x30,0x66,0x22,0xe2, 0xa2,0xbf,0x2e,0x35,0xbc,0xe7,0xd6,0x24,
|
||||
0x6a,0x3d,0x06,0xe8,0xe2,0xbe,0x96,0xcc, 0x9a,0x08,0x06,0xb5,0x44,0x83,0xb0,0x7b,
|
||||
0x70,0x7b,0x2d,0xc3,0x46,0x9a,0xc5,0x6b, 0xd9,0xde,0x9a,0x24,0xc9,0xea,0xf5,0x28,
|
||||
0x69,0x8a,0x17,0xca,0xdf,0xc4,0x0e,0xa3, 0x08,0x22,0x99,0xd2,0x27,0xdc,0x9b,0x08,
|
||||
0x54,0x4a,0xf9,0xb1,0x74,0x3a,0x9d,0xd9, 0xc2,0x82,0x21,0xf5,0x97,0x04,0x90,0x37,
|
||||
0xda,0xd9,0xdc,0x19,0xad,0x83,0xcd,0x35, 0xb0,0x4e,0x06,0x68,0xd1,0x69,0x7e,0x73,
|
||||
0x93,0xbe,0xa5,0x05,0xb3,0xcc,0xd2,0x51, 0x3c,0x00,0x00,0x00,0x16,0xe1,0xac,0x17,
|
||||
0xdc,0x68,0xae,0x03,0xad,0xf7,0xb9,0xca, 0x0d,0xca,0x27,0xef,0x76,0xda,0xe5,0xcb
|
||||
};
|
||||
|
||||
static const struct signature_test dssSign_data[] = {
|
||||
{AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
|
||||
{AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
|
||||
{AT_SIGNATURE_PrivateKey, sizeof(AT_SIGNATURE_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)},
|
||||
{DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign1, sizeof(dataToSign1)},
|
||||
{DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign2, sizeof(dataToSign2)},
|
||||
{DSS_SIGN_PrivateKey, sizeof(DSS_SIGN_PrivateKey), (BYTE *)dataToSign3, sizeof(dataToSign3)}
|
||||
};
|
||||
|
||||
static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *tests, int testLen)
|
||||
{
|
||||
HCRYPTHASH hHash1, hHash2;
|
||||
HCRYPTKEY privKey = 0, pubKey = 0;
|
||||
BYTE pubKeyBuffer[512];
|
||||
BYTE signValue1[40], signValue2[40];
|
||||
BYTE hashValue1[40], hashValue2[40];
|
||||
DWORD hashLen1, hashLen2, pubKeyLen;
|
||||
DWORD dataLen1, dataLen2;
|
||||
BOOL result;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < testLen; i++)
|
||||
{
|
||||
DWORD signLen1 = tests[i].dataLen;
|
||||
DWORD signLen2 = tests[i].dataLen;
|
||||
|
||||
/* Get a private key of array specified ALG_ID */
|
||||
result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
|
||||
ok(result, "Failed to imported key, got %x\n", GetLastError());
|
||||
|
||||
/* Create hash object and add data for signature 1 */
|
||||
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
|
||||
ok(result, "Failed to create a hash, got %x\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash1, tests[i].signData, signLen1, 0);
|
||||
ok(result, "Failed to add data to hash, got %x\n", GetLastError());
|
||||
|
||||
/* Create hash object and add data for signature 2 */
|
||||
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
|
||||
ok(result, "Failed to create a hash, got %x\n", GetLastError());
|
||||
|
||||
result = CryptHashData(hHash2, tests[i].signData, signLen2, 0);
|
||||
ok(result, "Failed to add data to hash, got %x\n", GetLastError());
|
||||
|
||||
/* Acquire hash length and hash value */
|
||||
dataLen1 = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHash1, HP_HASHSIZE, (BYTE *)&hashLen1, &dataLen1, 0);
|
||||
ok(result, "Failed to get hash length, got %x\n", GetLastError());
|
||||
|
||||
result = CryptGetHashParam(hHash1, HP_HASHVAL, hashValue1, &hashLen1, 0);
|
||||
ok(result, "Failed to return hash value.\n");
|
||||
|
||||
dataLen2 = sizeof(DWORD);
|
||||
result = CryptGetHashParam(hHash2, HP_HASHSIZE, (BYTE *)&hashLen2, &dataLen2, 0);
|
||||
ok(result, "Failed to get hash length, got %x\n", GetLastError());
|
||||
|
||||
result = CryptGetHashParam(hHash2, HP_HASHVAL, hashValue2, &hashLen2, 0);
|
||||
ok(result, "Failed to return hash value.\n");
|
||||
|
||||
/* Compare hashes to ensure they are the same */
|
||||
ok(hashLen1 == hashLen2, "Hash lengths were not the same.");
|
||||
ok(!memcmp(hashValue1, hashValue2, hashLen2), "Hashes were not identical.\n");
|
||||
|
||||
/* Sign hash 1 */
|
||||
result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, NULL, &signLen1);
|
||||
ok(result, "Failed to get signature length, got %x\n", GetLastError());
|
||||
ok(signLen1 == 40, "Expected a 40-byte signature, got %d\n", signLen1);
|
||||
|
||||
result = CryptSignHash(hHash1, AT_SIGNATURE, NULL, 0, signValue1, &signLen1);
|
||||
ok(result, "Failed to sign hash, got %x\n", GetLastError());
|
||||
|
||||
/* Sign hash 2 */
|
||||
result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, NULL, &signLen2);
|
||||
ok(result, "Failed to get signature length, got %x\n", GetLastError());
|
||||
ok(signLen2 == 40, "Expected a 40-byte signature, got %d\n", signLen2);
|
||||
|
||||
result = CryptSignHash(hHash2, AT_SIGNATURE, NULL, 0, signValue2, &signLen2);
|
||||
ok(result, "Failed to sign hash2, got %x\n", GetLastError());
|
||||
|
||||
/* Compare signatures to ensure they are both different, because every DSS signature
|
||||
should be different even if the input hash data is identical */
|
||||
ok(memcmp(signValue1, signValue2, signLen2), "Expected two different signatures from "
|
||||
"the same hash input.");
|
||||
|
||||
result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, NULL, &pubKeyLen);
|
||||
ok(result, "Failed to acquire public key length, got %x\n", GetLastError());
|
||||
|
||||
/* Export the public key */
|
||||
result = CryptExportKey(privKey, 0, PUBLICKEYBLOB, 0, pubKeyBuffer, &pubKeyLen);
|
||||
ok(result, "Failed to export public key, got %x\n", GetLastError());
|
||||
|
||||
result = CryptDestroyHash(hHash1);
|
||||
ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
|
||||
result = CryptDestroyHash(hHash2);
|
||||
ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
|
||||
|
||||
/* Destroy the private key */
|
||||
result = CryptDestroyKey(privKey);
|
||||
ok(result, "Failed to destroy private key, got %x\n", GetLastError());
|
||||
|
||||
/* Import the public key we obtained earlier */
|
||||
result = CryptImportKey(hProv, pubKeyBuffer, pubKeyLen, 0, 0, &pubKey);
|
||||
ok(result, "Failed to import public key, got %x\n", GetLastError());
|
||||
|
||||
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash1);
|
||||
ok(result, "Failed to create hash, got %x\n", GetLastError());
|
||||
|
||||
/* Hash the data to compare with the signed hash */
|
||||
result = CryptHashData(hHash1, tests[i].signData, tests[i].dataLen, 0);
|
||||
ok(result, "Failed to add data to hash1, got %x\n", GetLastError());
|
||||
|
||||
/* Verify signed hash 1 */
|
||||
result = CryptVerifySignature(hHash1, signValue1, sizeof(signValue1), pubKey, NULL, 0);
|
||||
ok(result, "Failed to verify signature, got %x\n", GetLastError());
|
||||
|
||||
result = CryptCreateHash(hProv, CALG_SHA, 0, 0, &hHash2);
|
||||
ok(result, "Failed to create hash, got %x\n", GetLastError());
|
||||
|
||||
/* Hash the data to compare with the signed hash */
|
||||
result = CryptHashData(hHash2, tests[i].signData, tests[i].dataLen, 0);
|
||||
ok(result, "Failed to add data to hash2, got %x\n", GetLastError());
|
||||
|
||||
/* Verify signed hash 2 */
|
||||
result = CryptVerifySignature(hHash2, signValue2, sizeof(signValue2), pubKey, NULL, 0);
|
||||
ok(result, "Failed to verify signature, got %x\n", GetLastError());
|
||||
|
||||
result = CryptDestroyHash(hHash1);
|
||||
ok(result, "Failed to destroy hash1, got %x\n", GetLastError());
|
||||
result = CryptDestroyHash(hHash2);
|
||||
ok(result, "Failed to destroy hash2, got %x\n", GetLastError());
|
||||
|
||||
/* Destroy the public key */
|
||||
result = CryptDestroyKey(pubKey);
|
||||
ok(result, "Failed to destroy public key, got %x\n", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
static void test_verify_signature(void)
|
||||
{
|
||||
HCRYPTPROV hProv = 0;
|
||||
BOOL result;
|
||||
|
||||
/* acquire base dss provider */
|
||||
result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_PROV_A, PROV_DSS, 0);
|
||||
if(!result)
|
||||
{
|
||||
skip("DSSENH is currently not available, skipping signature verification tests.\n");
|
||||
return;
|
||||
}
|
||||
ok(result, "Failed to acquire CSP.\n");
|
||||
|
||||
test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
|
||||
|
||||
result = CryptReleaseContext(hProv, 0);
|
||||
ok(result, "Failed to release CSP provider.\n");
|
||||
|
||||
/* acquire diffie hellman dss provider */
|
||||
result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DSS_DH_PROV, PROV_DSS_DH, 0);
|
||||
ok(result, "Failed to acquire CSP.\n");
|
||||
|
||||
test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
|
||||
|
||||
result = CryptReleaseContext(hProv, 0);
|
||||
ok(result, "Failed to release CSP provider.\n");
|
||||
|
||||
/* acquire enhanced dss provider */
|
||||
SetLastError(0xdeadbeef);
|
||||
result = CryptAcquireContextA(&hProv, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, 0);
|
||||
if(!result && GetLastError() == NTE_KEYSET_NOT_DEF)
|
||||
{
|
||||
win_skip("DSSENH and Schannel provider is broken on WinNT4, skipping signature "
|
||||
"verification tests.\n");
|
||||
return;
|
||||
}
|
||||
ok(result, "Failed to acquire CSP.\n");
|
||||
|
||||
test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
|
||||
|
||||
result = CryptReleaseContext(hProv, 0);
|
||||
ok(result, "Failed to release CSP provider.\n");
|
||||
|
||||
/* acquire schannel dss provider */
|
||||
result = CryptAcquireContextA(&hProv, NULL, MS_DEF_DH_SCHANNEL_PROV, PROV_DH_SCHANNEL, 0);
|
||||
ok(result, "Failed to acquire CSP.\n");
|
||||
|
||||
test_signhash_array(hProv, dssSign_data, TESTLEN(dssSign_data));
|
||||
|
||||
result = CryptReleaseContext(hProv, 0);
|
||||
ok(result, "Failed to release CSP provider.\n");
|
||||
}
|
||||
|
||||
START_TEST(dssenh)
|
||||
{
|
||||
test_acquire_context();
|
||||
|
@ -749,4 +999,5 @@ START_TEST(dssenh)
|
|||
test_hash(hash_data, TESTLEN(hash_data));
|
||||
test_data_encryption(encrypt_data, TESTLEN(encrypt_data));
|
||||
test_cipher_modes(ciphermode_data, TESTLEN(ciphermode_data));
|
||||
test_verify_signature();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue