Blame winpr/libwinpr/crypto/crypto.c

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