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