Commit e40af1cc authored by Michael Jung's avatar Michael Jung Committed by Alexandre Julliard

Implemented CPGetProvParam's PP_ENUMCONTAINERS parameter type.

Added corresponding test. Removed some tabs that slipped in with the last patch.
parent 34400353
...@@ -119,6 +119,7 @@ typedef struct tagKEYCONTAINER ...@@ -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 ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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() ...@@ -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) ...@@ -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();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment