* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#include "config.h"
-#include "wine/port.h"
-#include "wine/library.h"
-#include "wine/debug.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "wincrypt.h"
+#define WIN32_NO_STATUS
+#define _INC_WINDOWS
+#define COM_NO_WINDOWS_H
+
+#include <config.h>
+//#include "wine/port.h"
+#include <wine/library.h>
+#include <wine/debug.h>
+
+//#include <stdarg.h>
+//#include <stdio.h>
+
+#include <windef.h>
+//#include "winbase.h"
+#include <winreg.h>
+#include <wincrypt.h>
#include "handle.h"
#include "implglue.h"
-#include "objbase.h"
+#include <objbase.h>
+#include <rpcproxy.h>
+#include <aclapi.h>
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
+static HINSTANCE instance;
+
/******************************************************************************
* CRYPTHASH - hash objects
*/
* CRYPTKEY - key objects
*/
#define RSAENH_MAGIC_KEY 0x73620457u
-#define RSAENH_MAX_KEY_SIZE 48
+#define RSAENH_MAX_KEY_SIZE 64
#define RSAENH_MAX_BLOCK_SIZE 24
#define RSAENH_KEYSTATE_IDLE 0
#define RSAENH_KEYSTATE_ENCRYPTING 1
BYTE abInitVector[RSAENH_MAX_BLOCK_SIZE];
BYTE abChainVector[RSAENH_MAX_BLOCK_SIZE];
RSAENH_SCHANNEL_INFO siSChannelInfo;
+ CRYPT_DATA_BLOB blobHmacKey;
} CRYPTKEY;
/******************************************************************************
#define RSAENH_HMAC_DEF_IPAD_CHAR 0x36
#define RSAENH_HMAC_DEF_OPAD_CHAR 0x5c
#define RSAENH_HMAC_DEF_PAD_LEN 64
+#define RSAENH_HMAC_BLOCK_LEN 64
#define RSAENH_DES_EFFECTIVE_KEYLEN 56
#define RSAENH_DES_STORAGE_KEYLEN 64
#define RSAENH_3DES112_EFFECTIVE_KEYLEN 112
{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_384, 384,384, 384,CRYPT_FLAG_SIGNING, 6,"SHA-384", 30,"Secure Hash Algorithm (SHA-384)"},
{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)"},
static BOOL import_key(
HCRYPTPROV hProv,
- CONST BYTE *pbData,
+ const BYTE *pbData,
DWORD dwDataLen,
HCRYPTKEY hPubKey,
DWORD dwFlags,
RSAENH_CPHashData(
HCRYPTPROV hProv,
HCRYPTHASH hHash,
- CONST BYTE *pbData,
+ const BYTE *pbData,
DWORD dwDataLen,
DWORD dwFlags
);
*
* Initializes and destroys the handle table for the CSP's handles.
*/
-int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
+BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, PVOID reserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
+ instance = hInstance;
DisableThreadLibraryCalls(hInstance);
init_handle_table(&handle_table);
break;
case DLL_PROCESS_DETACH:
+ if (reserved) break;
destroy_handle_table(&handle_table);
break;
}
- return 1;
+ return TRUE;
}
/******************************************************************************
* Success: TRUE (pbParam was copied into pbBuffer or pbBuffer is NULL)
* Failure: FALSE (pbBuffer is not large enough to hold pbParam). Last error: ERROR_MORE_DATA
*/
-static inline BOOL copy_param(
- BYTE *pbBuffer, DWORD *pdwBufferSize, CONST BYTE *pbParam, DWORD dwParamSize)
+static inline BOOL copy_param(BYTE *pbBuffer, DWORD *pdwBufferSize, const BYTE *pbParam,
+ DWORD dwParamSize)
{
if (pbBuffer)
{
return TRUE;
}
+static inline KEYCONTAINER* get_key_container(HCRYPTPROV hProv)
+{
+ KEYCONTAINER *pKeyContainer;
+
+ if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
+ (OBJECTHDR**)&pKeyContainer))
+ {
+ SetLastError(NTE_BAD_UID);
+ return NULL;
+ }
+ return pKeyContainer;
+}
+
/******************************************************************************
* get_algid_info [Internal]
*
const PROV_ENUMALGS_EX *iterator;
KEYCONTAINER *pKeyContainer;
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER, (OBJECTHDR**)&pKeyContainer)) {
- SetLastError(NTE_BAD_UID);
- return NULL;
- }
+ if (!(pKeyContainer = get_key_container(hProv))) return NULL;
for (iterator = aProvEnumAlgsEx[pKeyContainer->dwPersonality]; iterator->aiAlgid; iterator++) {
if (iterator->aiAlgid == algid) return iterator;
* NOTES
* Use free_data_blob to release resources occupied by copy_data_blob.
*/
-static inline BOOL copy_data_blob(PCRYPT_DATA_BLOB dst, CONST PCRYPT_DATA_BLOB src) {
+static inline BOOL copy_data_blob(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src)
+{
dst->pbData = HeapAlloc(GetProcessHeap(), 0, src->cbData);
if (!dst->pbData) {
SetLastError(NTE_NO_MEMORY);
* NOTES
* Release resources occupied by concat_data_blobs with free_data_blobs
*/
-static inline BOOL concat_data_blobs(PCRYPT_DATA_BLOB dst, CONST PCRYPT_DATA_BLOB src1,
- CONST PCRYPT_DATA_BLOB src2)
+static inline BOOL concat_data_blobs(PCRYPT_DATA_BLOB dst, const PCRYPT_DATA_BLOB src1,
+ const PCRYPT_DATA_BLOB src2)
{
dst->cbData = src1->cbData + src2->cbData;
dst->pbData = HeapAlloc(GetProcessHeap(), 0, dst->cbData);
* pbData [I] Pointer to data stream to be hashed.
* dwDataLen [I] Length of data stream.
*/
-static inline void update_hash(CRYPTHASH *pCryptHash, CONST BYTE *pbData, DWORD dwDataLen) {
+static inline void update_hash(CRYPTHASH *pCryptHash, const BYTE *pbData, DWORD dwDataLen)
+{
BYTE *pbTemp;
switch (pCryptHash->aiAlgid)
free_key_impl(pCryptKey->aiAlgid, &pCryptKey->context);
free_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom);
free_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom);
+ free_data_blob(&pCryptKey->blobHmacKey);
HeapFree(GetProcessHeap(), 0, pCryptKey);
}
*
* PARAMS
* hProv [I] Handle to the provider to which the created key will belong.
- * aiAlgid [I] The new key shall use the crypto algorithm idenfied by aiAlgid.
+ * aiAlgid [I] The new key shall use the crypto algorithm identified by aiAlgid.
* dwFlags [I] Upper 16 bits give the key length.
* Lower 16 bits: CRYPT_EXPORTABLE, CRYPT_CREATE_SALT,
* CRYPT_NO_SALT
{
HCRYPTKEY hCryptKey;
CRYPTKEY *pCryptKey;
- DWORD dwKeyLen = HIWORD(dwFlags);
+ DWORD dwKeyLen = HIWORD(dwFlags), bKeyLen = dwKeyLen;
const PROV_ENUMALGS_EX *peaAlgidInfo;
*ppCryptKey = NULL;
return (HCRYPTKEY)INVALID_HANDLE_VALUE;
}
break;
-
+
+ case CALG_HMAC:
+ /* Avoid the key length check for HMAC keys, which have unlimited
+ * length.
+ */
+ break;
+
+ case CALG_AES:
+ if (!bKeyLen)
+ {
+ TRACE("missing key len for CALG_AES\n");
+ SetLastError(NTE_BAD_ALGID);
+ return (HCRYPTKEY)INVALID_HANDLE_VALUE;
+ }
+ /* fall through */
default:
if (dwKeyLen % 8 ||
dwKeyLen > peaAlgidInfo->dwMaxLen ||
destroy_key, (OBJECTHDR**)&pCryptKey);
if (hCryptKey != (HCRYPTKEY)INVALID_HANDLE_VALUE)
{
+ KEYCONTAINER *pKeyContainer = get_key_container(hProv);
pCryptKey->aiAlgid = aiAlgid;
pCryptKey->hProv = hProv;
pCryptKey->dwModeBits = 0;
pCryptKey->dwPermissions |= CRYPT_EXPORT;
pCryptKey->dwKeyLen = dwKeyLen >> 3;
pCryptKey->dwEffectiveKeyLen = 0;
- if ((dwFlags & CRYPT_CREATE_SALT) || (dwKeyLen == 40 && !(dwFlags & CRYPT_NO_SALT)))
+
+ /*
+ * For compatibility reasons a 40 bit key on the Enhanced
+ * provider will not have salt
+ */
+ if (pKeyContainer->dwPersonality == RSAENH_PERSONALITY_ENHANCED
+ && (aiAlgid == CALG_RC2 || aiAlgid == CALG_RC4)
+ && (dwFlags & CRYPT_CREATE_SALT) && dwKeyLen == 40)
+ pCryptKey->dwSaltLen = 0;
+ else if ((dwFlags & CRYPT_CREATE_SALT) || (dwKeyLen == 40 && !(dwFlags & CRYPT_NO_SALT)))
pCryptKey->dwSaltLen = 16 /*FIXME*/ - pCryptKey->dwKeyLen;
else
pCryptKey->dwSaltLen = 0;
memset(pCryptKey->abKeyValue, 0, sizeof(pCryptKey->abKeyValue));
memset(pCryptKey->abInitVector, 0, sizeof(pCryptKey->abInitVector));
+ memset(&pCryptKey->siSChannelInfo.saEncAlg, 0, sizeof(pCryptKey->siSChannelInfo.saEncAlg));
+ memset(&pCryptKey->siSChannelInfo.saMACAlg, 0, sizeof(pCryptKey->siSChannelInfo.saMACAlg));
init_data_blob(&pCryptKey->siSChannelInfo.blobClientRandom);
init_data_blob(&pCryptKey->siSChannelInfo.blobServerRandom);
+ init_data_blob(&pCryptKey->blobHmacKey);
switch(aiAlgid)
{
case CALG_AES_192:
case CALG_AES_256:
pCryptKey->dwBlockLen = 16;
- pCryptKey->dwMode = CRYPT_MODE_ECB;
+ pCryptKey->dwMode = CRYPT_MODE_CBC;
break;
case CALG_RSA_KEYX:
pCryptKey->dwBlockLen = dwKeyLen >> 3;
pCryptKey->dwMode = 0;
break;
+
+ case CALG_HMAC:
+ pCryptKey->dwBlockLen = 0;
+ pCryptKey->dwMode = 0;
+ break;
}
*ppCryptKey = pCryptKey;
* dwFlags [I] Flags indicating which keyset to be opened.
* phKey [O] Returned key
*/
-static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, HKEY *phKey)
+static BOOL open_container_key(LPCSTR pszContainerName, DWORD dwFlags, REGSAM access, HKEY *phKey)
{
CHAR szRSABase[MAX_PATH];
HKEY hRootKey;
/* @@ Wine registry key: HKLM\Software\Wine\Crypto\RSA */
/* @@ Wine registry key: HKCU\Software\Wine\Crypto\RSA */
- return RegOpenKeyExA(hRootKey, szRSABase, 0, KEY_READ, phKey) ==
+ return RegOpenKeyExA(hRootKey, szRSABase, 0, access, phKey) ==
ERROR_SUCCESS;
}
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_ENHANCED;
} else if (!strcmp(pVTable->pszProvName, MS_DEF_RSA_SCHANNEL_PROV_A)) {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_SCHANNEL;
- } else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A)) {
+ } else if (!strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_A) ||
+ !strcmp(pVTable->pszProvName, MS_ENH_RSA_AES_PROV_XP_A)) {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_AES;
} else {
pKeyContainer->dwPersonality = RSAENH_PERSONALITY_STRONG;
HCRYPTPROV hKeyContainer;
HCRYPTKEY hCryptKey;
- if (!open_container_key(pszContainerName, dwFlags, &hKey))
+ if (!open_container_key(pszContainerName, dwFlags, KEY_READ, &hKey))
{
SetLastError(NTE_BAD_KEYSET);
return (HCRYPTPROV)INVALID_HANDLE_VALUE;
* Failure: FALSE (NTE_BAD_ALGID)
*/
static BOOL build_hash_signature(BYTE *pbSignature, DWORD dwLen, ALG_ID aiAlgid,
- CONST BYTE *abHashValue, DWORD dwHashLen, DWORD dwFlags)
+ const BYTE *abHashValue, DWORD dwHashLen, DWORD dwFlags)
{
/* These prefixes are meant to be concatenated with hash values of the
* respective kind to form a PKCS #7 DigestInfo. */
static const struct tagOIDDescriptor {
ALG_ID aiAlgid;
DWORD dwLen;
- CONST BYTE abOID[19];
+ 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 } },
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,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
0x05, 0x00, 0x04, 0x30 } },
- { CALG_SHA_384, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
- 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
+ { CALG_SHA_512, 19, { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86,
+ 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
0x05, 0x00, 0x04, 0x40 } },
{ CALG_SSL3_SHAMD5, 0, { 0 } },
{ 0, 0, { 0 } }
* Success: TRUE
* Failure: FALSE
*/
-static BOOL tls1_p(HCRYPTHASH hHMAC, CONST PCRYPT_DATA_BLOB pblobSeed, PBYTE pbBuffer, DWORD dwBufferLen)
+static BOOL tls1_p(HCRYPTHASH hHMAC, const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer,
+ DWORD dwBufferLen)
{
CRYPTHASH *pHMAC;
BYTE abAi[RSAENH_MAX_HASH_SIZE];
* Success: TRUE
* Failure: FALSE
*/
-static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, CONST PCRYPT_DATA_BLOB pblobLabel,
- CONST PCRYPT_DATA_BLOB pblobSeed, PBYTE pbBuffer, DWORD dwBufferLen)
+static BOOL tls1_prf(HCRYPTPROV hProv, HCRYPTPROV hSecret, const PCRYPT_DATA_BLOB pblobLabel,
+ const PCRYPT_DATA_BLOB pblobSeed, BYTE *pbBuffer, DWORD dwBufferLen)
{
HMAC_INFO hmacInfo = { 0, NULL, 0, NULL, 0 };
HCRYPTHASH hHMAC = (HCRYPTHASH)INVALID_HANDLE_VALUE;
* Success: TRUE
* Failure: FALSE (NTE_BAD_LEN, too much data to pad)
*/
-static BOOL pad_data(CONST BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen,
+static BOOL pad_data(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD dwBufferLen,
DWORD dwFlags)
{
DWORD i;
* Success: TRUE
* Failure: FALSE, (NTE_BAD_DATA, no valid PKCS1 padding or buffer too small)
*/
-static BOOL unpad_data(CONST BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen,
+static BOOL unpad_data(const BYTE *abData, DWORD dwDataLen, BYTE *abBuffer, DWORD *dwBufferLen,
DWORD dwFlags)
{
DWORD i;
+ if (dwDataLen < 3)
+ {
+ SetLastError(NTE_BAD_DATA);
+ return FALSE;
+ }
for (i=2; i<dwDataLen; i++)
if (!abData[i])
break;
/******************************************************************************
* CPCreateHash (RSAENH.@)
*
- * CPCreateHash creates and initalizes a new hash object.
+ * CPCreateHash creates and initializes a new hash object.
*
* PARAMS
* hProv [I] Handle to the key container to which the new hash will belong.
SetLastError(NTE_BAD_KEY);
return FALSE;
}
+ if (Algid == CALG_SCHANNEL_MASTER_HASH &&
+ ((!pCryptKey->siSChannelInfo.blobClientRandom.cbData) ||
+ (!pCryptKey->siSChannelInfo.blobServerRandom.cbData)))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
if ((Algid == CALG_TLS1PRF) && (pCryptKey->dwState != RSAENH_KEYSTATE_MASTERKEY)) {
SetLastError(NTE_BAD_KEY_STATE);
/******************************************************************************
* CPDestroyHash (RSAENH.@)
*
- * Releases the handle to a hash object. The object is destroyed if it's reference
+ * Releases the handle to a hash object. The object is destroyed if its reference
* count reaches zero.
*
* PARAMS
/******************************************************************************
* CPDestroyKey (RSAENH.@)
*
- * Releases the handle to a key object. The object is destroyed if it's reference
+ * Releases the handle to a key object. The object is destroyed if its reference
* count reaches zero.
*
* PARAMS
/******************************************************************************
* CPDuplicateHash (RSAENH.@)
*
- * Clones a hash object including it's current state.
+ * Clones a hash object including its current state.
*
* PARAMS
* hUID [I] Handle to the key container the hash belongs to.
/******************************************************************************
* CPDuplicateKey (RSAENH.@)
*
- * Clones a key object including it's current state.
+ * Clones a key object including its current state.
*
* PARAMS
* hUID [I] Handle to the key container the hash belongs to.
*pdwDataLen -= pbData[*pdwDataLen-1];
else {
SetLastError(NTE_BAD_DATA);
+ setup_key(pCryptKey);
return FALSE;
}
}
else {
SetLastError(NTE_BAD_DATA);
+ setup_key(pCryptKey);
return FALSE;
}
}
pBlobHeader->aiKeyAlg = pCryptKey->aiAlgid;
*pKeyLen = pCryptKey->dwKeyLen;
- memcpy(pbKey, &pCryptKey->abKeyValue, pCryptKey->dwKeyLen);
+ memcpy(pbKey, pCryptKey->abKeyValue, pCryptKey->dwKeyLen);
}
*pdwDataLen = dwDataLen;
return TRUE;
{
KEYCONTAINER *pKeyContainer;
- if (lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if ((pKeyContainer = get_key_container(hProv)))
{
store_key_container_keys(pKeyContainer);
store_key_container_permissions(pKeyContainer);
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_private_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen,
+static BOOL import_private_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
{
KEYCONTAINER *pKeyContainer;
CRYPTKEY *pCryptKey;
- CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData;
- CONST RSAPUBKEY *pRSAPubKey = (CONST RSAPUBKEY*)(pBlobHeader+1);
+ const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
+ const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1);
BOOL ret;
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
{
- SetLastError(NTE_BAD_UID);
+ FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
+ SetLastError(NTE_BAD_FLAGS);
return FALSE;
}
+ if (!(pKeyContainer = get_key_container(hProv)))
+ return FALSE;
- if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) ||
- (pRSAPubKey->magic != RSAENH_MAGIC_RSA2) ||
- (dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
- (2 * pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4))))
+ if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)))
+ {
+ ERR("datalen %d not long enough for a BLOBHEADER + RSAPUBKEY\n",
+ dwDataLen);
+ SetLastError(NTE_BAD_DATA);
+ return FALSE;
+ }
+ if (pRSAPubKey->magic != RSAENH_MAGIC_RSA2)
+ {
+ ERR("unexpected magic %08x\n", pRSAPubKey->magic);
+ SetLastError(NTE_BAD_DATA);
+ return FALSE;
+ }
+ if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
+ (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4))))
{
+ DWORD expectedLen = sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
+ (pRSAPubKey->bitlen >> 3) + (5 * ((pRSAPubKey->bitlen+8)>>4));
+
+ ERR("blob too short for pub key: expect %d, got %d\n",
+ expectedLen, dwDataLen);
SetLastError(NTE_BAD_DATA);
return FALSE;
}
*phKey = new_key(hProv, pBlobHeader->aiKeyAlg, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey);
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
setup_key(pCryptKey);
- ret = import_private_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context,
- pRSAPubKey->bitlen/8, pRSAPubKey->pubexp);
+ ret = import_private_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context,
+ pRSAPubKey->bitlen/8, dwDataLen, pRSAPubKey->pubexp);
if (ret) {
if (dwFlags & CRYPT_EXPORTABLE)
pCryptKey->dwPermissions |= CRYPT_EXPORT;
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_public_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen,
+static BOOL import_public_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
{
KEYCONTAINER *pKeyContainer;
CRYPTKEY *pCryptKey;
- CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData;
- CONST RSAPUBKEY *pRSAPubKey = (CONST RSAPUBKEY*)(pBlobHeader+1);
+ const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
+ const RSAPUBKEY *pRSAPubKey = (const RSAPUBKEY*)(pBlobHeader+1);
ALG_ID algID;
BOOL ret;
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
{
- SetLastError(NTE_BAD_UID);
+ FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
+ SetLastError(NTE_BAD_FLAGS);
return FALSE;
}
+ if (!(pKeyContainer = get_key_container(hProv)))
+ return FALSE;
if ((dwDataLen < sizeof(BLOBHEADER) + sizeof(RSAPUBKEY)) ||
(pRSAPubKey->magic != RSAENH_MAGIC_RSA1) ||
*phKey = new_key(hProv, algID, MAKELONG(0,pRSAPubKey->bitlen), &pCryptKey);
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
setup_key(pCryptKey);
- ret = import_public_key_impl((CONST BYTE*)(pRSAPubKey+1), &pCryptKey->context,
+ ret = import_public_key_impl((const BYTE*)(pRSAPubKey+1), &pCryptKey->context,
pRSAPubKey->bitlen >> 3, pRSAPubKey->pubexp);
if (ret) {
if (dwFlags & CRYPT_EXPORTABLE)
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_symmetric_key(HCRYPTPROV hProv, CONST BYTE *pbData,
- DWORD dwDataLen, HCRYPTKEY hPubKey,
- DWORD dwFlags, HCRYPTKEY *phKey)
+static BOOL import_symmetric_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
+ HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
{
CRYPTKEY *pCryptKey, *pPubKey;
- CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData;
- CONST ALG_ID *pAlgid = (CONST ALG_ID*)(pBlobHeader+1);
- CONST BYTE *pbKeyStream = (CONST BYTE*)(pAlgid + 1);
+ const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
+ const ALG_ID *pAlgid = (const ALG_ID*)(pBlobHeader+1);
+ const BYTE *pbKeyStream = (const BYTE*)(pAlgid + 1);
BYTE *pbDecrypted;
DWORD dwKeyLen;
+ if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
+ {
+ FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
+ SetLastError(NTE_BAD_FLAGS);
+ return FALSE;
+ }
if (!lookup_handle(&handle_table, hPubKey, RSAENH_MAGIC_KEY, (OBJECTHDR**)&pPubKey) ||
pPubKey->aiAlgid != CALG_RSA_KEYX)
{
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_plaintext_key(HCRYPTPROV hProv, CONST BYTE *pbData,
- DWORD dwDataLen, DWORD dwFlags,
- HCRYPTKEY *phKey)
+static BOOL import_plaintext_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
+ DWORD dwFlags, HCRYPTKEY *phKey)
{
CRYPTKEY *pCryptKey;
- CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData;
- CONST DWORD *pKeyLen = (CONST DWORD *)(pBlobHeader + 1);
- CONST BYTE *pbKeyStream = (CONST BYTE*)(pKeyLen + 1);
+ const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
+ const DWORD *pKeyLen = (const DWORD *)(pBlobHeader + 1);
+ const BYTE *pbKeyStream = (const BYTE*)(pKeyLen + 1);
if (dwDataLen < sizeof(BLOBHEADER)+sizeof(DWORD)+*pKeyLen)
{
return FALSE;
}
- *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey);
- if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
- return FALSE;
- memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
- setup_key(pCryptKey);
- if (dwFlags & CRYPT_EXPORTABLE)
- pCryptKey->dwPermissions |= CRYPT_EXPORT;
+ if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
+ {
+ *phKey = new_key(hProv, CALG_HMAC, 0, &pCryptKey);
+ if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
+ return FALSE;
+ if (*pKeyLen <= RSAENH_MIN(sizeof(pCryptKey->abKeyValue), RSAENH_HMAC_BLOCK_LEN))
+ {
+ memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
+ pCryptKey->dwKeyLen = *pKeyLen;
+ }
+ else
+ {
+ CRYPT_DATA_BLOB blobHmacKey = { *pKeyLen, (BYTE *)pbKeyStream };
+
+ /* In order to initialize an HMAC key, the key material is hashed,
+ * and the output of the hash function is used as the key material.
+ * Unfortunately, the way the Crypto API is designed, we don't know
+ * the hash algorithm yet, so we have to copy the entire key
+ * material.
+ */
+ if (!copy_data_blob(&pCryptKey->blobHmacKey, &blobHmacKey))
+ {
+ release_handle(&handle_table, *phKey, RSAENH_MAGIC_KEY);
+ *phKey = (HCRYPTKEY)INVALID_HANDLE_VALUE;
+ return FALSE;
+ }
+ }
+ setup_key(pCryptKey);
+ if (dwFlags & CRYPT_EXPORTABLE)
+ pCryptKey->dwPermissions |= CRYPT_EXPORT;
+ }
+ else
+ {
+ *phKey = new_key(hProv, pBlobHeader->aiKeyAlg, *pKeyLen<<19, &pCryptKey);
+ if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE)
+ return FALSE;
+ memcpy(pCryptKey->abKeyValue, pbKeyStream, *pKeyLen);
+ setup_key(pCryptKey);
+ if (dwFlags & CRYPT_EXPORTABLE)
+ pCryptKey->dwPermissions |= CRYPT_EXPORT;
+ }
return TRUE;
}
* Success: TRUE.
* Failure: FALSE.
*/
-static BOOL import_key(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen,
- HCRYPTKEY hPubKey, DWORD dwFlags, BOOL fStoreKey,
- HCRYPTKEY *phKey)
+static BOOL import_key(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen, HCRYPTKEY hPubKey,
+ DWORD dwFlags, BOOL fStoreKey, HCRYPTKEY *phKey)
{
KEYCONTAINER *pKeyContainer;
- CONST BLOBHEADER *pBlobHeader = (CONST BLOBHEADER*)pbData;
+ const BLOBHEADER *pBlobHeader = (const BLOBHEADER*)pbData;
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
- {
- SetLastError(NTE_BAD_UID);
+ if (!(pKeyContainer = get_key_container(hProv)))
return FALSE;
- }
if (dwDataLen < sizeof(BLOBHEADER) ||
pBlobHeader->bVersion != CUR_BLOB_VERSION ||
* Success: TRUE.
* Failure: FALSE.
*/
-BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDataLen,
+BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, const BYTE *pbData, DWORD dwDataLen,
HCRYPTKEY hPubKey, DWORD dwFlags, HCRYPTKEY *phKey)
{
TRACE("(hProv=%08lx, pbData=%p, dwDataLen=%d, hPubKey=%08lx, dwFlags=%08x, phKey=%p)\n",
hProv, pbData, dwDataLen, hPubKey, dwFlags, phKey);
- if (dwFlags & CRYPT_IPSEC_HMAC_KEY)
- {
- FIXME("unimplemented for CRYPT_IPSEC_HMAC_KEY\n");
- SetLastError(NTE_BAD_FLAGS);
- return FALSE;
- }
return import_key(hProv, pbData, dwDataLen, hPubKey, dwFlags, TRUE, phKey);
}
TRACE("(hProv=%08lx, aiAlgid=%d, dwFlags=%08x, phKey=%p)\n", hProv, Algid, dwFlags, phKey);
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if (!(pKeyContainer = get_key_container(hProv)))
{
/* MSDN: hProv not containing valid context handle */
- SetLastError(NTE_BAD_UID);
return FALSE;
}
switch (dwParam)
{
case HP_ALGID:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptHash->aiAlgid,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->aiAlgid,
sizeof(ALG_ID));
case HP_HASHSIZE:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptHash->dwHashSize,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptHash->dwHashSize,
sizeof(DWORD));
case HP_HASHVAL:
case KP_EFFECTIVE_KEYLEN:
switch (pCryptKey->aiAlgid) {
case CALG_RC2:
+ {
+ DWORD keylen, deflen;
+ BOOL ret = TRUE;
+ KEYCONTAINER *pKeyContainer = get_key_container(pCryptKey->hProv);
+
if (!pbData)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- else if (!*(DWORD *)pbData || *(DWORD *)pbData > 1024)
+ keylen = *(DWORD *)pbData;
+ if (!keylen || keylen > 1024)
{
SetLastError(NTE_BAD_DATA);
return FALSE;
}
- else
+
+ /*
+ * The Base provider will force the key length to default
+ * and set an error state if a key length different from
+ * the default is tried.
+ */
+ deflen = aProvEnumAlgsEx[pKeyContainer->dwPersonality]->dwDefaultLen;
+ if (pKeyContainer->dwPersonality == RSAENH_PERSONALITY_BASE
+ && keylen != deflen)
{
- pCryptKey->dwEffectiveKeyLen = *(DWORD *)pbData;
- setup_key(pCryptKey);
+ keylen = deflen;
+ SetLastError(NTE_BAD_DATA);
+ ret = FALSE;
}
- break;
+ pCryptKey->dwEffectiveKeyLen = keylen;
+ setup_key(pCryptKey);
+ return ret;
+ }
default:
SetLastError(NTE_BAD_TYPE);
return FALSE;
case KP_PADDING:
dwValue = PKCS5_PADDING;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwValue, sizeof(DWORD));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
case KP_KEYLEN:
dwValue = pCryptKey->dwKeyLen << 3;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwValue, sizeof(DWORD));
-
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
+
case KP_EFFECTIVE_KEYLEN:
if (pCryptKey->dwEffectiveKeyLen)
dwValue = pCryptKey->dwEffectiveKeyLen;
else
dwValue = pCryptKey->dwKeyLen << 3;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwValue, sizeof(DWORD));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
case KP_BLOCKLEN:
dwValue = pCryptKey->dwBlockLen << 3;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwValue, sizeof(DWORD));
-
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwValue, sizeof(DWORD));
+
case KP_MODE:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptKey->dwMode, sizeof(DWORD));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwMode, sizeof(DWORD));
case KP_MODE_BITS:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptKey->dwModeBits,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwModeBits,
sizeof(DWORD));
-
+
case KP_PERMISSIONS:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptKey->dwPermissions,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->dwPermissions,
sizeof(DWORD));
case KP_ALGID:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&pCryptKey->aiAlgid, sizeof(DWORD));
-
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&pCryptKey->aiAlgid, sizeof(DWORD));
+
default:
SetLastError(NTE_BAD_TYPE);
return FALSE;
* - PP_SIG_KEYSIZE_INC: RSA signature keywidth granularity in bits.
* - PP_KEYX_KEYSIZE_INC: RSA key-exchange keywidth granularity in bits.
* - PP_ENUMALGS{_EX}: Query provider capabilities.
+ * - PP_KEYSET_SEC_DESCR: Retrieve security descriptor on container.
*/
BOOL WINAPI RSAENH_CPGetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData,
DWORD *pdwDataLen, DWORD dwFlags)
* Returning this BLOB seems to satisfy IE. The marked 0x00 seem
* to be 'don't care's. If you know anything more specific about
* this provider parameter, please report to wine-devel@winehq.org */
- static CONST BYTE abWTF[96] = {
+ static const BYTE abWTF[96] = {
0xb0, 0x25, 0x63, 0x86, 0x9c, 0xab, 0xb6, 0x37,
0xe8, 0x82, /**/0x00,/**/ 0x72, 0x06, 0xb2, /**/0x00,/**/ 0x3b,
0x60, 0x35, /**/0x00,/**/ 0x3b, 0x88, 0xce, /**/0x00,/**/ 0x82,
return FALSE;
}
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if (!(pKeyContainer = get_key_container(hProv)))
{
/* MSDN: hProv not containing valid context handle */
- SetLastError(NTE_BAD_UID);
return FALSE;
}
{
case PP_CONTAINER:
case PP_UNIQUE_CONTAINER:/* MSDN says we can return the same value as PP_CONTAINER */
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)pKeyContainer->szName,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szName,
strlen(pKeyContainer->szName)+1);
case PP_NAME:
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)pKeyContainer->szProvName,
+ return copy_param(pbData, pdwDataLen, (const BYTE*)pKeyContainer->szProvName,
strlen(pKeyContainer->szProvName)+1);
case PP_PROVTYPE:
dwTemp = PROV_RSA_FULL;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_KEYSPEC:
dwTemp = AT_SIGNATURE | AT_KEYEXCHANGE;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_KEYSET_TYPE:
dwTemp = pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_KEYSTORAGE:
dwTemp = CRYPT_SEC_DESCR;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_SIG_KEYSIZE_INC:
case PP_KEYX_KEYSIZE_INC:
dwTemp = 8;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_IMPTYPE:
dwTemp = CRYPT_IMPL_SOFTWARE;
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&dwTemp, sizeof(dwTemp));
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&dwTemp, sizeof(dwTemp));
case PP_VERSION:
dwTemp = 0x00000200;
- 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;
return TRUE;
}
- if (!open_container_key("", dwFlags, &hKey))
+ if (!open_container_key("", dwFlags, KEY_READ, &hKey))
{
SetLastError(ERROR_NO_MORE_ITEMS);
return FALSE;
memcpy(provEnumalgs.szName, aProvEnumAlgsEx
[pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr].szName,
20*sizeof(CHAR));
-
- return copy_param(pbData, pdwDataLen, (CONST BYTE*)&provEnumalgs,
+
+ return copy_param(pbData, pdwDataLen, (const BYTE*)&provEnumalgs,
sizeof(PROV_ENUMALGS));
} else {
if (pbData && (*pdwDataLen >= sizeof(PROV_ENUMALGS_EX)))
pKeyContainer->dwEnumAlgsCtr = ((dwFlags & CRYPT_FIRST) == CRYPT_FIRST) ?
0 : pKeyContainer->dwEnumAlgsCtr+1;
-
+
return copy_param(pbData, pdwDataLen,
- (CONST BYTE*)&aProvEnumAlgsEx
+ (const BYTE*)&aProvEnumAlgsEx
[pKeyContainer->dwPersonality][pKeyContainer->dwEnumAlgsCtr],
sizeof(PROV_ENUMALGS_EX));
}
case PP_CRYPT_COUNT_KEY_USE: /* Asked for by IE About dialog */
return copy_param(pbData, pdwDataLen, abWTF, sizeof(abWTF));
+ case PP_KEYSET_SEC_DESCR:
+ {
+ SECURITY_DESCRIPTOR *sd;
+ DWORD err, len, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
+
+ if (!open_container_key(pKeyContainer->szName, flags, KEY_READ, &hKey))
+ {
+ SetLastError(NTE_BAD_KEYSET);
+ return FALSE;
+ }
+
+ err = GetSecurityInfo(hKey, SE_REGISTRY_KEY, dwFlags, NULL, NULL, NULL, NULL, (void **)&sd);
+ RegCloseKey(hKey);
+ if (err)
+ {
+ SetLastError(err);
+ return FALSE;
+ }
+
+ len = GetSecurityDescriptorLength(sd);
+ if (*pdwDataLen >= len) memcpy(pbData, sd, len);
+ else SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ *pdwDataLen = len;
+
+ LocalFree(sd);
+ return TRUE;
+ }
+
default:
/* MSDN: Unknown parameter number in dwParam */
SetLastError(NTE_BAD_TYPE);
switch (GET_ALG_CLASS(Algid))
{
case ALG_CLASS_DATA_ENCRYPT:
+ {
+ int need_padding, copy_len;
*phKey = new_key(hProv, Algid, dwFlags, &pCryptKey);
if (*phKey == (HCRYPTKEY)INVALID_HANDLE_VALUE) return FALSE;
*/
dwLen = RSAENH_MAX_HASH_SIZE;
RSAENH_CPGetHashParam(pCryptHash->hProv, hBaseData, HP_HASHVAL, abHashValue, &dwLen, 0);
-
- if (dwLen < pCryptKey->dwKeyLen) {
+
+ /*
+ * The usage of padding seems to vary from algorithm to algorithm.
+ * For now the only different case found was for AES with 128 bit key.
+ */
+ switch(Algid)
+ {
+ case CALG_AES_128:
+ /* To reduce the chance of regressions we will only deviate
+ * from the old behavior for the tested hash lengths */
+ if (dwLen == 16 || dwLen == 20)
+ {
+ need_padding = 1;
+ break;
+ }
+ default:
+ need_padding = dwLen < pCryptKey->dwKeyLen;
+ }
+
+ copy_len = pCryptKey->dwKeyLen;
+ if (need_padding)
+ {
BYTE pad1[RSAENH_HMAC_DEF_PAD_LEN], pad2[RSAENH_HMAC_DEF_PAD_LEN];
BYTE old_hashval[RSAENH_MAX_HASH_SIZE];
DWORD i;
memcpy(pCryptHash->abHashValue, old_hashval, RSAENH_MAX_HASH_SIZE);
}
+ /*
+ * Padding was not required, we have more hash than needed.
+ * Do we need to use the remaining hash as salt?
+ */
+ else if((dwFlags & CRYPT_CREATE_SALT) &&
+ (Algid == CALG_RC2 || Algid == CALG_RC4))
+ {
+ copy_len += pCryptKey->dwSaltLen;
+ }
memcpy(pCryptKey->abKeyValue, abHashValue,
- RSAENH_MIN(pCryptKey->dwKeyLen, sizeof(pCryptKey->abKeyValue)));
+ RSAENH_MIN(copy_len, sizeof(pCryptKey->abKeyValue)));
break;
-
+ }
case ALG_CLASS_MSG_ENCRYPT:
if (!lookup_handle(&handle_table, pCryptHash->hKey, RSAENH_MAGIC_KEY,
(OBJECTHDR**)&pMasterKey))
{
/* See RFC 2246, chapter 6.3 Key calculation */
case CALG_SCHANNEL_ENC_KEY:
+ if (!pMasterKey->siSChannelInfo.saEncAlg.Algid ||
+ !pMasterKey->siSChannelInfo.saEncAlg.cBits)
+ {
+ SetLastError(NTE_BAD_FLAGS);
+ return FALSE;
+ }
*phKey = new_key(hProv, pMasterKey->siSChannelInfo.saEncAlg.Algid,
MAKELONG(LOWORD(dwFlags),pMasterKey->siSChannelInfo.saEncAlg.cBits),
&pCryptKey);
TRACE("(hProv=%08lx, dwKeySpec=%08x, phUserKey=%p)\n", hProv, dwKeySpec, phUserKey);
- if (!lookup_handle(&handle_table, hProv, RSAENH_MAGIC_CONTAINER,
- (OBJECTHDR**)&pKeyContainer))
+ if (!(pKeyContainer = get_key_container(hProv)))
{
/* MSDN: hProv not containing valid context handle */
- SetLastError(NTE_BAD_UID);
return FALSE;
}
* The actual hash value is queried with CPGetHashParam, which will finalize
* the hash. Updating a finalized hash will fail with a last error NTE_BAD_HASH_STATE.
*/
-BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbData,
+BOOL WINAPI RSAENH_CPHashData(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbData,
DWORD dwDataLen, DWORD dwFlags)
{
CRYPTHASH *pCryptHash;
TRACE("(hProv=%08lx, hHash=%08lx, pbData=%p, dwDataLen=%d, dwFlags=%08x)\n",
hProv, hHash, pbData, dwDataLen, dwFlags);
- if (dwFlags)
+ if (dwFlags & ~CRYPT_USERDATA)
{
SetLastError(NTE_BAD_FLAGS);
return FALSE;
return FALSE;
}
+ if (pCryptKey->aiAlgid == CALG_HMAC && !pCryptKey->dwKeyLen) {
+ HCRYPTHASH hKeyHash;
+ DWORD keyLen;
+
+ if (!RSAENH_CPCreateHash(hProv, ((PHMAC_INFO)pbData)->HashAlgid, 0, 0,
+ &hKeyHash))
+ return FALSE;
+ if (!RSAENH_CPHashData(hProv, hKeyHash, pCryptKey->blobHmacKey.pbData,
+ pCryptKey->blobHmacKey.cbData, 0))
+ {
+ RSAENH_CPDestroyHash(hProv, hKeyHash);
+ return FALSE;
+ }
+ keyLen = sizeof(pCryptKey->abKeyValue);
+ if (!RSAENH_CPGetHashParam(hProv, hKeyHash, HP_HASHVAL, pCryptKey->abKeyValue,
+ &keyLen, 0))
+ {
+ RSAENH_CPDestroyHash(hProv, hKeyHash);
+ return FALSE;
+ }
+ pCryptKey->dwKeyLen = keyLen;
+ RSAENH_CPDestroyHash(hProv, hKeyHash);
+ }
for (i=0; i<RSAENH_MIN(pCryptKey->dwKeyLen,pCryptHash->pHMACInfo->cbInnerString); i++) {
pCryptHash->pHMACInfo->pbInnerString[i] ^= pCryptKey->abKeyValue[i];
}
*/
BOOL WINAPI RSAENH_CPSetProvParam(HCRYPTPROV hProv, DWORD dwParam, BYTE *pbData, DWORD dwFlags)
{
- FIXME("(stub)\n");
- return FALSE;
+ KEYCONTAINER *pKeyContainer;
+ HKEY hKey;
+
+ TRACE("(hProv=%08lx, dwParam=%08x, pbData=%p, dwFlags=%08x)\n", hProv, dwParam, pbData, dwFlags);
+
+ if (!(pKeyContainer = get_key_container(hProv)))
+ return FALSE;
+
+ switch (dwParam)
+ {
+ case PP_KEYSET_SEC_DESCR:
+ {
+ SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)pbData;
+ DWORD err, flags = (pKeyContainer->dwFlags & CRYPT_MACHINE_KEYSET);
+ BOOL def, present;
+ REGSAM access = WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY;
+ PSID owner = NULL, group = NULL;
+ PACL dacl = NULL, sacl = NULL;
+
+ if (!open_container_key(pKeyContainer->szName, flags, access, &hKey))
+ {
+ SetLastError(NTE_BAD_KEYSET);
+ return FALSE;
+ }
+
+ if ((dwFlags & OWNER_SECURITY_INFORMATION && !GetSecurityDescriptorOwner(sd, &owner, &def)) ||
+ (dwFlags & GROUP_SECURITY_INFORMATION && !GetSecurityDescriptorGroup(sd, &group, &def)) ||
+ (dwFlags & DACL_SECURITY_INFORMATION && !GetSecurityDescriptorDacl(sd, &present, &dacl, &def)) ||
+ (dwFlags & SACL_SECURITY_INFORMATION && !GetSecurityDescriptorSacl(sd, &present, &sacl, &def)))
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ err = SetSecurityInfo(hKey, SE_REGISTRY_KEY, dwFlags, owner, group, dacl, sacl);
+ RegCloseKey(hKey);
+ if (err)
+ {
+ SetLastError(err);
+ return FALSE;
+ }
+ return TRUE;
+ }
+ default:
+ FIXME("unimplemented parameter %08x\n", dwParam);
+ return FALSE;
+ }
}
/******************************************************************************
*pdwSigLen = pCryptKey->dwKeyLen;
if (sDescription) {
- if (!RSAENH_CPHashData(hProv, hHash, (CONST BYTE*)sDescription,
+ if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription,
(DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0))
{
goto out;
* Success: TRUE (Signature is valid)
* Failure: FALSE (GetLastError() == NTE_BAD_SIGNATURE, if signature is invalid)
*/
-BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, CONST BYTE *pbSignature,
+BOOL WINAPI RSAENH_CPVerifySignature(HCRYPTPROV hProv, HCRYPTHASH hHash, const BYTE *pbSignature,
DWORD dwSigLen, HCRYPTKEY hPubKey, LPCWSTR sDescription,
DWORD dwFlags)
{
}
if (sDescription) {
- if (!RSAENH_CPHashData(hProv, hHash, (CONST BYTE*)sDescription,
+ if (!RSAENH_CPHashData(hProv, hHash, (const BYTE*)sDescription,
(DWORD)lstrlenW(sDescription)*sizeof(WCHAR), 0))
{
return FALSE;
goto cleanup;
}
- if (!build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags)) {
+ if (build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags) &&
+ !memcmp(pbDecrypted, pbConstructed, dwSigLen)) {
+ res = TRUE;
goto cleanup;
}
- if (memcmp(pbDecrypted, pbConstructed, dwSigLen)) {
- SetLastError(NTE_BAD_SIGNATURE);
+ if (!(dwFlags & CRYPT_NOHASHOID) &&
+ build_hash_signature(pbConstructed, dwSigLen, aiAlgid, abHashValue, dwHashLen, dwFlags|CRYPT_NOHASHOID) &&
+ !memcmp(pbDecrypted, pbConstructed, dwSigLen)) {
+ res = TRUE;
goto cleanup;
}
-
- res = TRUE;
+
+ SetLastError(NTE_BAD_SIGNATURE);
+
cleanup:
HeapFree(GetProcessHeap(), 0, pbConstructed);
HeapFree(GetProcessHeap(), 0, pbDecrypted);
return res;
}
-static const WCHAR szProviderKeys[6][116] = {
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ','B','a','s',
- 'e',' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
- 'o','v','i','d','e','r',' ','v','1','.','0',0 },
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
- 'E','n','h','a','n','c','e','d',
- ' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
- 'o','v','i','d','e','r',' ','v','1','.','0',0 },
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ','S','t','r','o','n','g',
- ' ','C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r',
- 'o','v','i','d','e','r',0 },
- { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'C','r','y','p','t','o','g','r','a','p','h','y','\\','D','e','f','a','u','l','t','s','\\',
- 'P','r','o','v','i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
- 'R','S','A',' ','S','C','h','a','n','n','e','l',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 },
- { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'C','r','y','p','t','o','g','r','a','p','h','y','\\','D','e','f','a','u','l','t','s','\\',
- 'P','r','o','v','i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
- 'E','n','h','a','n','c','e','d',' ','R','S','A',' ','a','n','d',' ','A','E','S',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',0 },
- { 'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
- 'C','r','y','p','t','o','g','r','a','p','h','y','\\','D','e','f','a','u','l','t','s','\\',
- 'P','r','o','v','i','d','e','r','\\','M','i','c','r','o','s','o','f','t',' ',
- 'E','n','h','a','n','c','e','d',' ','R','S','A',' ','a','n','d',' ','A','E','S',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ','P','r','o','v','i','d','e','r',
- ' ','(','P','r','o','t','o','t','y','p','e',')',0 }
-};
-static const WCHAR szDefaultKeys[3][65] = {
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','0','1',0 },
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','1','2',0 },
- { 'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\','C','r','y','p','t','o','g','r',
- 'a','p','h','y','\\','D','e','f','a','u','l','t','s','\\','P','r','o','v',
- 'i','d','e','r',' ','T','y','p','e','s','\\','T','y','p','e',' ','0','2','4',0 }
-};
-
-
/******************************************************************************
* DllRegisterServer (RSAENH.@)
- *
- * Dll self registration.
- *
- * PARAMS
- *
- * RETURNS
- * Success: S_OK.
- * Failure: != S_OK
- *
- * NOTES
- * Registers the following keys:
- * - HKLM\Software\Microsoft\Cryptography\Defaults\Provider\
- * Microsoft Base Cryptographic Provider v1.0
- * - HKLM\Software\Microsoft\Cryptography\Defaults\Provider\
- * Microsoft Enhanced Cryptographic Provider
- * - HKLM\Software\Microsoft\Cryptography\Defaults\Provider\
- * Microsoft Strong Cryptographpic Provider
- * - HKLM\Software\Microsoft\Cryptography\Defaults\Provider Types\Type 001
*/
HRESULT WINAPI DllRegisterServer(void)
{
- HKEY key;
- DWORD dp;
- long apiRet;
- int i;
-
- for (i=0; i<6; i++) {
- apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szProviderKeys[i], 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
-
- if (apiRet == ERROR_SUCCESS)
- {
- if (dp == REG_CREATED_NEW_KEY)
- {
- static const WCHAR szImagePath[] = { 'I','m','a','g','e',' ','P','a','t','h',0 };
- static const WCHAR szRSABase[] = { 'r','s','a','e','n','h','.','d','l','l',0 };
- static const WCHAR szType[] = { 'T','y','p','e',0 };
- static const WCHAR szSignature[] = { 'S','i','g','n','a','t','u','r','e',0 };
- DWORD type, sign;
-
- switch(i)
- {
- case 3:
- type=PROV_RSA_SCHANNEL;
- break;
- case 4:
- case 5:
- type=PROV_RSA_AES;
- break;
- default:
- type=PROV_RSA_FULL;
- break;
- }
- sign = 0xdeadbeef;
- RegSetValueExW(key, szImagePath, 0, REG_SZ, (const BYTE *)szRSABase,
- (lstrlenW(szRSABase) + 1) * sizeof(WCHAR));
- RegSetValueExW(key, szType, 0, REG_DWORD, (LPBYTE)&type, sizeof(type));
- RegSetValueExW(key, szSignature, 0, REG_BINARY, (LPBYTE)&sign, sizeof(sign));
- }
- RegCloseKey(key);
- }
- }
-
- for (i=0; i<3; i++) {
- apiRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, szDefaultKeys[i], 0, NULL,
- REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, &dp);
- if (apiRet == ERROR_SUCCESS)
- {
- if (dp == REG_CREATED_NEW_KEY)
- {
- static const WCHAR szName[] = { 'N','a','m','e',0 };
- static const WCHAR szRSAName[3][54] = {
- { 'M','i','c','r','o','s','o','f','t',' ',
- 'E','n','h','a','n','c','e','d',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
- 'P','r','o','v','i','d','e','r',' ','v','1','.','0',0 },
- { 'M','i','c','r','o','s','o','f','t',' ','R','S','A',' ',
- 'S','C','h','a','n','n','e','l',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
- 'P','r','o','v','i','d','e','r',0 },
- { 'M','i','c','r','o','s','o','f','t',' ','E','n','h','a','n','c','e','d',' ',
- 'R','S','A',' ','a','n','d',' ','A','E','S',' ',
- 'C','r','y','p','t','o','g','r','a','p','h','i','c',' ',
- 'P','r','o','v','i','d','e','r',0 } };
- static const WCHAR szTypeName[] = { 'T','y','p','e','N','a','m','e',0 };
- static const WCHAR szRSATypeName[3][38] = {
- { 'R','S','A',' ','F','u','l','l',' ',
- '(','S','i','g','n','a','t','u','r','e',' ','a','n','d',' ',
- 'K','e','y',' ','E','x','c','h','a','n','g','e',')',0 },
- { 'R','S','A',' ','S','C','h','a','n','n','e','l',0 },
- { 'R','S','A',' ','F','u','l','l',' ','a','n','d',' ','A','E','S',0 } };
-
- RegSetValueExW(key, szName, 0, REG_SZ,
- (const BYTE *)szRSAName[i], lstrlenW(szRSAName[i])*sizeof(WCHAR)+sizeof(WCHAR));
- RegSetValueExW(key, szTypeName, 0, REG_SZ,
- (const BYTE *)szRSATypeName[i], lstrlenW(szRSATypeName[i])*sizeof(WCHAR)+sizeof(WCHAR));
- }
- }
- RegCloseKey(key);
- }
-
- return HRESULT_FROM_WIN32(apiRet);
+ return __wine_register_resources( instance );
}
/******************************************************************************
* DllUnregisterServer (RSAENH.@)
- *
- * Dll self unregistration.
- *
- * PARAMS
- *
- * RETURNS
- * Success: S_OK
- *
- * NOTES
- * For the relevant keys see DllRegisterServer.
*/
HRESULT WINAPI DllUnregisterServer(void)
{
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[0]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[1]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[2]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[3]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[4]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szProviderKeys[5]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[0]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[1]);
- RegDeleteKeyW(HKEY_LOCAL_MACHINE, szDefaultKeys[2]);
- return S_OK;
+ return __wine_unregister_resources( instance );
}