{CALG_AES_192, 192,192, 192,0, 8,"AES-192", 39,"Advanced Encryption Standard (AES-192)"},
{CALG_AES_256, 256,256, 256,0, 8,"AES-256", 39,"Advanced Encryption Standard (AES-256)"},
{CALG_SHA, 160,160, 160,CRYPT_FLAG_SIGNING, 6,"SHA-1", 30,"Secure Hash Algorithm (SHA-1)"},
+ {CALG_SHA_256, 256,256, 256,CRYPT_FLAG_SIGNING, 6,"SHA-256", 30,"Secure Hash Algorithm (SHA-256)"},
+ {CALG_SHA_384, 384,384, 384,CRYPT_FLAG_SIGNING, 6,"SHA-384", 30,"Secure Hash Algorithm (SHA-284)"},
+ {CALG_SHA_512, 512,512, 512,CRYPT_FLAG_SIGNING, 6,"SHA-512", 30,"Secure Hash Algorithm (SHA-512)"},
{CALG_MD2, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD2", 23,"Message Digest 2 (MD2)"},
{CALG_MD4, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD4", 23,"Message Digest 4 (MD4)"},
{CALG_MD5, 128,128, 128,CRYPT_FLAG_SIGNING, 4,"MD5", 23,"Message Digest 5 (MD5)"},
static void store_key_container_permissions(KEYCONTAINER *pKeyContainer)
{
HKEY hKey;
- DWORD dwFlags;
-
- /* On WinXP, persistent keys are stored in a file located at:
- * $AppData$\\Microsoft\\Crypto\\RSA\\$SID$\\some_hex_string
- */
-
- if (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET)
- dwFlags = CRYPTPROTECT_LOCAL_MACHINE;
- else
- dwFlags = 0;
if (create_container_key(pKeyContainer, KEY_WRITE, &hKey))
{
store_key_container_permissions(pKeyContainer);
release_key_container_keys(pKeyContainer);
}
+ else
+ release_key_container_keys(pKeyContainer);
HeapFree( GetProcessHeap(), 0, pKeyContainer );
}
(OBJECTHDR**)&pKeyContainer))
return (HCRYPTPROV)INVALID_HANDLE_VALUE;
+ /* read_key_value calls import_key, which calls import_private_key,
+ * which implicitly installs the key value into the appropriate key
+ * container key. Thus the ref count is incremented twice, once for
+ * the output key value, and once for the implicit install, and needs
+ * to be decremented to balance the two.
+ */
if (read_key_value(hKeyContainer, hKey, AT_KEYEXCHANGE,
dwProtectFlags, &hCryptKey))
- pKeyContainer->hKeyExchangeKeyPair = hCryptKey;
+ release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY);
if (read_key_value(hKeyContainer, hKey, AT_SIGNATURE,
dwProtectFlags, &hCryptKey))
- pKeyContainer->hSignatureKeyPair = hCryptKey;
+ release_handle(&handle_table, hCryptKey, RSAENH_MAGIC_KEY);
}
return hKeyContainer;
static const struct tagOIDDescriptor {
ALG_ID aiAlgid;
DWORD dwLen;
- CONST BYTE abOID[18];
- } aOIDDescriptor[5] = {
+ CONST BYTE abOID[19];
+ } aOIDDescriptor[] = {
{ CALG_MD2, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 } },
{ CALG_MD4, 18, { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48,
0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 } },
{ CALG_SHA, 15, { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 } },
+ { CALG_SHA_256, 19, { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x20 } },
+ { CALG_SHA_384, 19, { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x30 } },
+ { CALG_SHA_384, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ 0x05, 0x00, 0x04, 0x40 } },
+ { CALG_SSL3_SHAMD5, 0, { 0 } },
{ 0, 0, { 0 } }
};
DWORD dwIdxOID, i, j;
if (pCryptKey) {
new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen);
setup_key(pCryptKey);
- RSAENH_CPDestroyKey(hProv, pKeyContainer->hSignatureKeyPair);
- copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY,
- &pKeyContainer->hSignatureKeyPair);
+ release_and_install_key(hProv, *phKey,
+ &pKeyContainer->hSignatureKeyPair,
+ FALSE);
}
break;
if (pCryptKey) {
new_key_impl(pCryptKey->aiAlgid, &pCryptKey->context, pCryptKey->dwKeyLen);
setup_key(pCryptKey);
- RSAENH_CPDestroyKey(hProv, pKeyContainer->hKeyExchangeKeyPair);
- copy_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY,
- &pKeyContainer->hKeyExchangeKeyPair);
+ release_and_install_key(hProv, *phKey,
+ &pKeyContainer->hKeyExchangeKeyPair,
+ FALSE);
}
break;
setup_key(pCryptKey);
return TRUE;
+ case KP_SALT:
+ switch (pCryptKey->aiAlgid) {
+ case CALG_RC2:
+ case CALG_RC4:
+ if (!pbData)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ /* MSDN: the base provider always sets eleven bytes of
+ * salt value.
+ */
+ memcpy(pCryptKey->abKeyValue + pCryptKey->dwKeyLen,
+ pbData, 11);
+ pCryptKey->dwSaltLen = 11;
+ setup_key(pCryptKey);
+ /* Strange but true: salt length reset to 0 after setting
+ * it via KP_SALT.
+ */
+ pCryptKey->dwSaltLen = 0;
+ break;
+ default:
+ SetLastError(NTE_BAD_KEY);
+ return FALSE;
+ }
+ return TRUE;
+
case KP_SALT_EX:
{
CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)pbData;
pCryptKey->dwBlockLen);
case KP_SALT:
- return copy_param(pbData, pdwDataLen,
- &pCryptKey->abKeyValue[pCryptKey->dwKeyLen], pCryptKey->dwSaltLen);
+ switch (pCryptKey->aiAlgid) {
+ case CALG_RC2:
+ case CALG_RC4:
+ return copy_param(pbData, pdwDataLen,
+ &pCryptKey->abKeyValue[pCryptKey->dwKeyLen],
+ pCryptKey->dwSaltLen);
+ default:
+ SetLastError(NTE_BAD_KEY);
+ return FALSE;
+ }
case KP_PADDING:
dwValue = PKCS5_PADDING;
LPCWSTR sDescription, DWORD dwFlags, BYTE *pbSignature,
DWORD *pdwSigLen)
{
- HCRYPTKEY hCryptKey;
+ HCRYPTKEY hCryptKey = (HCRYPTKEY)INVALID_HANDLE_VALUE;
CRYPTKEY *pCryptKey;
DWORD dwHashLen;
BYTE abHashValue[RSAENH_MAX_HASH_SIZE];
ALG_ID aiAlgid;
+ BOOL ret = FALSE;
TRACE("(hProv=%08lx, hHash=%08lx, dwKeySpec=%08x, sDescription=%s, dwFlags=%08x, "
"pbSignature=%p, pdwSigLen=%p)\n", hProv, hHash, dwKeySpec, debugstr_w(sDescription),
(OBJECTHDR**)&pCryptKey))
{
SetLastError(NTE_NO_KEY);
- return FALSE;
+ goto out;
}
if (!pbSignature) {
*pdwSigLen = pCryptKey->dwKeyLen;
- return TRUE;
+ ret = TRUE;
+ goto out;
}
if (pCryptKey->dwKeyLen > *pdwSigLen)
{
SetLastError(ERROR_MORE_DATA);
*pdwSigLen = pCryptKey->dwKeyLen;
- return FALSE;
+ goto out;
}
*pdwSigLen = pCryptKey->dwKeyLen;
if (!RSAENH_CPHashData(hProv, hHash, (CONST BYTE*)sDescription,
(DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0))
{
- return FALSE;
+ goto out;
}
}
dwHashLen = sizeof(DWORD);
- if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) return FALSE;
+ if (!RSAENH_CPGetHashParam(hProv, hHash, HP_ALGID, (BYTE*)&aiAlgid, &dwHashLen, 0)) goto out;
dwHashLen = RSAENH_MAX_HASH_SIZE;
- if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) return FALSE;
+ if (!RSAENH_CPGetHashParam(hProv, hHash, HP_HASHVAL, abHashValue, &dwHashLen, 0)) goto out;
if (!build_hash_signature(pbSignature, *pdwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) {
- return FALSE;
+ goto out;
}
- return encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature, RSAENH_ENCRYPT);
+ ret = encrypt_block_impl(pCryptKey->aiAlgid, PK_PRIVATE, &pCryptKey->context, pbSignature, pbSignature, RSAENH_ENCRYPT);
+out:
+ RSAENH_CPDestroyKey(hProv, hCryptKey);
+ return ret;
}
/******************************************************************************