|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* WinPR: Windows Portable Runtime
|
|
Packit |
1fb8d4 |
* Cryptography API (CryptoAPI)
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2012-2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
1fb8d4 |
* you may not use this file except in compliance with the License.
|
|
Packit |
1fb8d4 |
* You may obtain a copy of the License at
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
1fb8d4 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
1fb8d4 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
1fb8d4 |
* See the License for the specific language governing permissions and
|
|
Packit |
1fb8d4 |
* limitations under the License.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
1fb8d4 |
#include "config.h"
|
|
Packit |
1fb8d4 |
#endif
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crypto.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* CryptAcquireCertificatePrivateKey
|
|
Packit |
1fb8d4 |
* CryptBinaryToStringA
|
|
Packit |
1fb8d4 |
* CryptBinaryToStringW
|
|
Packit |
1fb8d4 |
* CryptCloseAsyncHandle
|
|
Packit |
1fb8d4 |
* CryptCreateAsyncHandle
|
|
Packit |
1fb8d4 |
* CryptCreateKeyIdentifierFromCSP
|
|
Packit |
1fb8d4 |
* CryptDecodeMessage
|
|
Packit |
1fb8d4 |
* CryptDecodeObject
|
|
Packit |
1fb8d4 |
* CryptDecodeObjectEx
|
|
Packit |
1fb8d4 |
* CryptDecryptAndVerifyMessageSignature
|
|
Packit |
1fb8d4 |
* CryptDecryptMessage
|
|
Packit |
1fb8d4 |
* CryptEncodeObject
|
|
Packit |
1fb8d4 |
* CryptEncodeObjectEx
|
|
Packit |
1fb8d4 |
* CryptEncryptMessage
|
|
Packit |
1fb8d4 |
* CryptEnumKeyIdentifierProperties
|
|
Packit |
1fb8d4 |
* CryptEnumOIDFunction
|
|
Packit |
1fb8d4 |
* CryptEnumOIDInfo
|
|
Packit |
1fb8d4 |
* CryptExportPKCS8
|
|
Packit |
1fb8d4 |
* CryptExportPublicKeyInfo
|
|
Packit |
1fb8d4 |
* CryptExportPublicKeyInfoEx
|
|
Packit |
1fb8d4 |
* CryptExportPublicKeyInfoFromBCryptKeyHandle
|
|
Packit |
1fb8d4 |
* CryptFindCertificateKeyProvInfo
|
|
Packit |
1fb8d4 |
* CryptFindLocalizedName
|
|
Packit |
1fb8d4 |
* CryptFindOIDInfo
|
|
Packit |
1fb8d4 |
* CryptFormatObject
|
|
Packit |
1fb8d4 |
* CryptFreeOIDFunctionAddress
|
|
Packit |
1fb8d4 |
* CryptGetAsyncParam
|
|
Packit |
1fb8d4 |
* CryptGetDefaultOIDDllList
|
|
Packit |
1fb8d4 |
* CryptGetDefaultOIDFunctionAddress
|
|
Packit |
1fb8d4 |
* CryptGetKeyIdentifierProperty
|
|
Packit |
1fb8d4 |
* CryptGetMessageCertificates
|
|
Packit |
1fb8d4 |
* CryptGetMessageSignerCount
|
|
Packit |
1fb8d4 |
* CryptGetOIDFunctionAddress
|
|
Packit |
1fb8d4 |
* CryptGetOIDFunctionValue
|
|
Packit |
1fb8d4 |
* CryptHashCertificate
|
|
Packit |
1fb8d4 |
* CryptHashCertificate2
|
|
Packit |
1fb8d4 |
* CryptHashMessage
|
|
Packit |
1fb8d4 |
* CryptHashPublicKeyInfo
|
|
Packit |
1fb8d4 |
* CryptHashToBeSigned
|
|
Packit |
1fb8d4 |
* CryptImportPKCS8
|
|
Packit |
1fb8d4 |
* CryptImportPublicKeyInfo
|
|
Packit |
1fb8d4 |
* CryptImportPublicKeyInfoEx
|
|
Packit |
1fb8d4 |
* CryptImportPublicKeyInfoEx2
|
|
Packit |
1fb8d4 |
* CryptInitOIDFunctionSet
|
|
Packit |
1fb8d4 |
* CryptInstallDefaultContext
|
|
Packit |
1fb8d4 |
* CryptInstallOIDFunctionAddress
|
|
Packit |
1fb8d4 |
* CryptLoadSip
|
|
Packit |
1fb8d4 |
* CryptMemAlloc
|
|
Packit |
1fb8d4 |
* CryptMemFree
|
|
Packit |
1fb8d4 |
* CryptMemRealloc
|
|
Packit |
1fb8d4 |
* CryptMsgCalculateEncodedLength
|
|
Packit |
1fb8d4 |
* CryptMsgClose
|
|
Packit |
1fb8d4 |
* CryptMsgControl
|
|
Packit |
1fb8d4 |
* CryptMsgCountersign
|
|
Packit |
1fb8d4 |
* CryptMsgCountersignEncoded
|
|
Packit |
1fb8d4 |
* CryptMsgDuplicate
|
|
Packit |
1fb8d4 |
* CryptMsgEncodeAndSignCTL
|
|
Packit |
1fb8d4 |
* CryptMsgGetAndVerifySigner
|
|
Packit |
1fb8d4 |
* CryptMsgGetParam
|
|
Packit |
1fb8d4 |
* CryptMsgOpenToDecode
|
|
Packit |
1fb8d4 |
* CryptMsgOpenToEncode
|
|
Packit |
1fb8d4 |
* CryptMsgSignCTL
|
|
Packit |
1fb8d4 |
* CryptMsgUpdate
|
|
Packit |
1fb8d4 |
* CryptMsgVerifyCountersignatureEncoded
|
|
Packit |
1fb8d4 |
* CryptMsgVerifyCountersignatureEncodedEx
|
|
Packit |
1fb8d4 |
* CryptQueryObject
|
|
Packit |
1fb8d4 |
* CryptRegisterDefaultOIDFunction
|
|
Packit |
1fb8d4 |
* CryptRegisterOIDFunction
|
|
Packit |
1fb8d4 |
* CryptRegisterOIDInfo
|
|
Packit |
1fb8d4 |
* CryptRetrieveTimeStamp
|
|
Packit |
1fb8d4 |
* CryptSetAsyncParam
|
|
Packit |
1fb8d4 |
* CryptSetKeyIdentifierProperty
|
|
Packit |
1fb8d4 |
* CryptSetOIDFunctionValue
|
|
Packit |
1fb8d4 |
* CryptSignAndEncodeCertificate
|
|
Packit |
1fb8d4 |
* CryptSignAndEncryptMessage
|
|
Packit |
1fb8d4 |
* CryptSignCertificate
|
|
Packit |
1fb8d4 |
* CryptSignMessage
|
|
Packit |
1fb8d4 |
* CryptSignMessageWithKey
|
|
Packit |
1fb8d4 |
* CryptSIPAddProvider
|
|
Packit |
1fb8d4 |
* CryptSIPCreateIndirectData
|
|
Packit |
1fb8d4 |
* CryptSIPGetCaps
|
|
Packit |
1fb8d4 |
* CryptSIPGetSignedDataMsg
|
|
Packit |
1fb8d4 |
* CryptSIPLoad
|
|
Packit |
1fb8d4 |
* CryptSIPPutSignedDataMsg
|
|
Packit |
1fb8d4 |
* CryptSIPRemoveProvider
|
|
Packit |
1fb8d4 |
* CryptSIPRemoveSignedDataMsg
|
|
Packit |
1fb8d4 |
* CryptSIPRetrieveSubjectGuid
|
|
Packit |
1fb8d4 |
* CryptSIPRetrieveSubjectGuidForCatalogFile
|
|
Packit |
1fb8d4 |
* CryptSIPVerifyIndirectData
|
|
Packit |
1fb8d4 |
* CryptUninstallDefaultContext
|
|
Packit |
1fb8d4 |
* CryptUnregisterDefaultOIDFunction
|
|
Packit |
1fb8d4 |
* CryptUnregisterOIDFunction
|
|
Packit |
1fb8d4 |
* CryptUnregisterOIDInfo
|
|
Packit |
1fb8d4 |
* CryptUpdateProtectedState
|
|
Packit |
1fb8d4 |
* CryptVerifyCertificateSignature
|
|
Packit |
1fb8d4 |
* CryptVerifyCertificateSignatureEx
|
|
Packit |
1fb8d4 |
* CryptVerifyDetachedMessageHash
|
|
Packit |
1fb8d4 |
* CryptVerifyDetachedMessageSignature
|
|
Packit |
1fb8d4 |
* CryptVerifyMessageHash
|
|
Packit |
1fb8d4 |
* CryptVerifyMessageSignature
|
|
Packit |
1fb8d4 |
* CryptVerifyMessageSignatureWithKey
|
|
Packit |
1fb8d4 |
* CryptVerifyTimeStampSignature
|
|
Packit |
1fb8d4 |
* DbgInitOSS
|
|
Packit |
1fb8d4 |
* DbgPrintf
|
|
Packit |
1fb8d4 |
* PFXExportCertStore
|
|
Packit |
1fb8d4 |
* PFXExportCertStore2
|
|
Packit |
1fb8d4 |
* PFXExportCertStoreEx
|
|
Packit |
1fb8d4 |
* PFXImportCertStore
|
|
Packit |
1fb8d4 |
* PFXIsPFXBlob
|
|
Packit |
1fb8d4 |
* PFXVerifyPassword
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifndef _WIN32
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "crypto.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
#include <winpr/crypto.h>
|
|
Packit |
1fb8d4 |
#include <winpr/collections.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static wListDictionary* g_ProtectedMemoryBlocks = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BYTE* pCipherText;
|
|
Packit |
1fb8d4 |
size_t cbOut, cbFinal;
|
|
Packit |
1fb8d4 |
WINPR_CIPHER_CTX* enc = NULL;
|
|
Packit |
1fb8d4 |
BYTE randomKey[256];
|
|
Packit |
1fb8d4 |
WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!g_ProtectedMemoryBlocks)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
g_ProtectedMemoryBlocks = ListDictionary_New(TRUE);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!g_ProtectedMemoryBlocks)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*)calloc(1, sizeof(WINPR_PROTECTED_MEMORY_BLOCK));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pMemBlock)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pMemBlock->pData = pData;
|
|
Packit |
1fb8d4 |
pMemBlock->cbData = cbData;
|
|
Packit |
1fb8d4 |
pMemBlock->dwFlags = dwFlags;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
winpr_RAND(pMemBlock->salt, 8);
|
|
Packit |
1fb8d4 |
winpr_RAND(randomKey, sizeof(randomKey));
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey,
|
|
Packit Service |
5a9772 |
sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
SecureZeroMemory(randomKey, sizeof(randomKey));
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
cbOut = pMemBlock->cbData + 16 - 1;
|
|
Packit Service |
5a9772 |
pCipherText = (BYTE*)malloc(cbOut);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pCipherText)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if ((enc = winpr_Cipher_New(WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key,
|
|
Packit Service |
5a9772 |
pMemBlock->iv)) == NULL)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
if (!winpr_Cipher_Update(enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut))
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
if (!winpr_Cipher_Final(enc, pCipherText + cbOut, &cbFinal))
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
winpr_Cipher_Free(enc);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData);
|
|
Packit |
1fb8d4 |
free(pCipherText);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock);
|
|
Packit |
1fb8d4 |
out:
|
|
Packit Service |
5a9772 |
free(pMemBlock);
|
|
Packit Service |
5a9772 |
free(pCipherText);
|
|
Packit |
1fb8d4 |
winpr_Cipher_Free(enc);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
BYTE* pPlainText = NULL;
|
|
Packit |
1fb8d4 |
size_t cbOut, cbFinal;
|
|
Packit |
1fb8d4 |
WINPR_CIPHER_CTX* dec = NULL;
|
|
Packit |
1fb8d4 |
WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = NULL;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!g_ProtectedMemoryBlocks)
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
pMemBlock =
|
|
Packit Service |
5a9772 |
(WINPR_PROTECTED_MEMORY_BLOCK*)ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pMemBlock)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
cbOut = pMemBlock->cbData + 16 - 1;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
pPlainText = (BYTE*)malloc(cbOut);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pPlainText)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
if ((dec = winpr_Cipher_New(WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT, pMemBlock->key,
|
|
Packit Service |
5a9772 |
pMemBlock->iv)) == NULL)
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
if (!winpr_Cipher_Update(dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut))
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
if (!winpr_Cipher_Final(dec, pPlainText + cbOut, &cbFinal))
|
|
Packit |
1fb8d4 |
goto out;
|
|
Packit |
1fb8d4 |
winpr_Cipher_Free(dec);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
|
|
Packit |
1fb8d4 |
SecureZeroMemory(pPlainText, pMemBlock->cbData);
|
|
Packit |
1fb8d4 |
free(pPlainText);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
ListDictionary_Remove(g_ProtectedMemoryBlocks, pData);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
free(pMemBlock);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
out:
|
|
Packit |
1fb8d4 |
free(pPlainText);
|
|
Packit |
1fb8d4 |
free(pMemBlock);
|
|
Packit |
1fb8d4 |
winpr_Cipher_Free(dec);
|
|
Packit |
1fb8d4 |
return FALSE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptProtectData(DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy,
|
|
Packit Service |
5a9772 |
PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags,
|
|
Packit Service |
5a9772 |
DATA_BLOB* pDataOut)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptUnprotectData(DATA_BLOB* pDataIn, LPWSTR* ppszDataDescr, DATA_BLOB* pOptionalEntropy,
|
|
Packit Service |
5a9772 |
PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags,
|
|
Packit Service |
5a9772 |
DATA_BLOB* pDataOut)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptStringToBinaryW(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary,
|
|
Packit Service |
5a9772 |
DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
BOOL CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary,
|
|
Packit Service |
5a9772 |
DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
BOOL CryptBinaryToStringW(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString,
|
|
Packit Service |
5a9772 |
DWORD* pcchString)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString,
|
|
Packit Service |
5a9772 |
DWORD* pcchString)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
return TRUE;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#endif
|