Implemented CPGetProvParam's PP_ENUMCONTAINERS parameter type.
Added corresponding test. Removed some tabs that slipped in with the last patch.
This commit is contained in:
parent
3440035341
commit
e40af1ccd0
|
@ -119,6 +119,7 @@ typedef struct tagKEYCONTAINER
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
DWORD dwPersonality;
|
DWORD dwPersonality;
|
||||||
DWORD dwEnumAlgsCtr;
|
DWORD dwEnumAlgsCtr;
|
||||||
|
DWORD dwEnumContainersCtr;
|
||||||
CHAR szName[MAX_PATH];
|
CHAR szName[MAX_PATH];
|
||||||
CHAR szProvName[MAX_PATH];
|
CHAR szProvName[MAX_PATH];
|
||||||
HCRYPTKEY hKeyExchangeKeyPair;
|
HCRYPTKEY hKeyExchangeKeyPair;
|
||||||
|
@ -977,6 +978,24 @@ static HCRYPTPROV new_key_container(PCHAR pszContainerName, DWORD dwFlags, PVTab
|
||||||
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
|
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The new key container has to be inserted into the CSP immediately
|
||||||
|
* after creation to be available for CPGetProvParam's PP_ENUMCONTAINERS. */
|
||||||
|
if (!(dwFlags & CRYPT_VERIFYCONTEXT)) {
|
||||||
|
BYTE szRSABase[MAX_PATH];
|
||||||
|
HKEY hRootKey, hKey;
|
||||||
|
|
||||||
|
sprintf(szRSABase, RSAENH_REGKEY, pKeyContainer->szName);
|
||||||
|
|
||||||
|
if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET) {
|
||||||
|
hRootKey = HKEY_LOCAL_MACHINE;
|
||||||
|
} else {
|
||||||
|
hRootKey = HKEY_CURRENT_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCreateKeyA(hRootKey, szRSABase, &hKey);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return hKeyContainer;
|
return hKeyContainer;
|
||||||
|
@ -1862,10 +1881,10 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
|
||||||
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
|
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
|
||||||
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
|
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
|
||||||
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
|
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
|
||||||
if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
|
if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
|
||||||
SetLastError(NTE_BAD_KEY);
|
SetLastError(NTE_BAD_KEY);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dwBufLen < pCryptKey->dwBlockLen) {
|
if (dwBufLen < pCryptKey->dwBlockLen) {
|
||||||
SetLastError(ERROR_MORE_DATA);
|
SetLastError(ERROR_MORE_DATA);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1982,10 +2001,10 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
|
||||||
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
|
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_STREAM) {
|
||||||
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
|
encrypt_stream_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, *pdwDataLen);
|
||||||
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
|
} else if (GET_ALG_TYPE(pCryptKey->aiAlgid) == ALG_TYPE_RSA) {
|
||||||
if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
|
if (pCryptKey->aiAlgid == CALG_RSA_SIGN) {
|
||||||
SetLastError(NTE_BAD_KEY);
|
SetLastError(NTE_BAD_KEY);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData, RSAENH_DECRYPT);
|
encrypt_block_impl(pCryptKey->aiAlgid, &pCryptKey->context, pbData, pbData, RSAENH_DECRYPT);
|
||||||
if (!unpad_data(pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE;
|
if (!unpad_data(pbData, pCryptKey->dwBlockLen, pbData, pdwDataLen, dwFlags)) return FALSE;
|
||||||
Final = TRUE;
|
Final = TRUE;
|
||||||
|
@ -2717,6 +2736,8 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
|
||||||
KEYCONTAINER *pKeyContainer;
|
KEYCONTAINER *pKeyContainer;
|
||||||
PROV_ENUMALGS provEnumalgs;
|
PROV_ENUMALGS provEnumalgs;
|
||||||
DWORD dwTemp;
|
DWORD dwTemp;
|
||||||
|
BYTE szRSABase[MAX_PATH];
|
||||||
|
HKEY hKey, hRootKey;
|
||||||
|
|
||||||
/* This is for dwParam 41, which does not seem to be documented
|
/* This is for dwParam 41, which does not seem to be documented
|
||||||
* on MSDN. IE6 SP1 asks for it in the 'About' dialog, however.
|
* on MSDN. IE6 SP1 asks for it in the 'About' dialog, however.
|
||||||
|
@ -2763,7 +2784,48 @@ BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
|
||||||
case PP_KEYX_KEYSIZE_INC:
|
case PP_KEYX_KEYSIZE_INC:
|
||||||
dwTemp = 8;
|
dwTemp = 8;
|
||||||
return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
|
return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
|
||||||
|
|
||||||
|
case PP_ENUMCONTAINERS:
|
||||||
|
if ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) pKeyContainer->dwEnumContainersCtr = 0;
|
||||||
|
|
||||||
|
if (!pbData) {
|
||||||
|
*pdwDataLen = (DWORD)MAX_PATH + 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(szRSABase, RSAENH_REGKEY, "");
|
||||||
|
|
||||||
|
if (dwFlags & CRYPT_MACHINE_KEYSET) {
|
||||||
|
hRootKey = HKEY_LOCAL_MACHINE;
|
||||||
|
} else {
|
||||||
|
hRootKey = HKEY_CURRENT_USER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegOpenKeyExA(hRootKey, szRSABase, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwTemp = *pdwDataLen;
|
||||||
|
switch (RegEnumKeyExA(hKey, pKeyContainer->dwEnumContainersCtr, pbData, &dwTemp,
|
||||||
|
NULL, NULL, NULL, NULL))
|
||||||
|
{
|
||||||
|
case ERROR_MORE_DATA:
|
||||||
|
*pdwDataLen = (DWORD)MAX_PATH + 1;
|
||||||
|
|
||||||
|
case ERROR_SUCCESS:
|
||||||
|
pKeyContainer->dwEnumContainersCtr++;
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
case ERROR_NO_MORE_ITEMS:
|
||||||
|
default:
|
||||||
|
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
case PP_ENUMALGS:
|
case PP_ENUMALGS:
|
||||||
case PP_ENUMALGS_EX:
|
case PP_ENUMALGS_EX:
|
||||||
if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) ||
|
if (((pKeyContainer->dwEnumAlgsCtr >= RSAENH_MAX_ENUMALGS-1) ||
|
||||||
|
|
|
@ -1366,6 +1366,31 @@ void test_schannel_provider()
|
||||||
CryptReleaseContext(hProv, 0);
|
CryptReleaseContext(hProv, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_enum_container()
|
||||||
|
{
|
||||||
|
BYTE abContainerName[256];
|
||||||
|
DWORD dwBufferLen;
|
||||||
|
BOOL result, fFound = FALSE;
|
||||||
|
|
||||||
|
/* If PP_ENUMCONTAINERS is queried with CRYPT_FIRST and abData == NULL, it returns
|
||||||
|
* the maximum legal length of container names (which is MAX_PATH + 1 == 261) */
|
||||||
|
result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, NULL, &dwBufferLen, CRYPT_FIRST);
|
||||||
|
ok (result && dwBufferLen == MAX_PATH + 1, "%08lx\n", GetLastError());
|
||||||
|
|
||||||
|
/* If the result fits into abContainerName dwBufferLen is left untouched */
|
||||||
|
dwBufferLen = (DWORD)sizeof(abContainerName);
|
||||||
|
result = CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, CRYPT_FIRST);
|
||||||
|
ok (result && dwBufferLen == (DWORD)sizeof(abContainerName), "%08lx\n", GetLastError());
|
||||||
|
|
||||||
|
/* We only check, if the currently open 'winetest' container is among the enumerated. */
|
||||||
|
do {
|
||||||
|
if (!strcmp(abContainerName, "winetest")) fFound = TRUE;
|
||||||
|
dwBufferLen = (DWORD)sizeof(abContainerName);
|
||||||
|
} while (CryptGetProvParam(hProv, PP_ENUMCONTAINERS, abContainerName, &dwBufferLen, 0));
|
||||||
|
|
||||||
|
ok (fFound && GetLastError() == ERROR_NO_MORE_ITEMS, "%d, %08lx\n", fFound, GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(rsaenh)
|
START_TEST(rsaenh)
|
||||||
{
|
{
|
||||||
if (!init_environment())
|
if (!init_environment())
|
||||||
|
@ -1384,6 +1409,7 @@ START_TEST(rsaenh)
|
||||||
test_import_private();
|
test_import_private();
|
||||||
test_verify_signature();
|
test_verify_signature();
|
||||||
test_rsa_encrypt();
|
test_rsa_encrypt();
|
||||||
|
test_enum_container();
|
||||||
clean_up_environment();
|
clean_up_environment();
|
||||||
test_schannel_provider();
|
test_schannel_provider();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue