void CWE327_Use_Broken_Crypto__w32_RC5_11_bad() { if(globalReturnsTrue()) { { FILE *pFile; HCRYPTPROV hCryptProv; HCRYPTKEY hKey; HCRYPTHASH hHash; char password[100]; size_t passwordLen; char toBeDecrypted[100]; DWORD toBeDecryptedLen = sizeof(toBeDecrypted)-1; /* Read the password from the console */ printLine("Enter the password: "******"fgets() failed"); /* Restore NUL terminator if fgets fails */ password[0] = '\0'; } /* The next 3 lines remove the carriage return from the string that is * inserted by fgets() */ passwordLen = strlen(password); if (passwordLen > 0) { password[passwordLen-1] = '\0'; } /* Read the data to be decrypted from a file */ pFile = fopen("encrypted.txt", "rb"); if (pFile == NULL) { exit(1); } if (fread(toBeDecrypted, sizeof(char), 100, pFile) != 100) { fclose(pFile); exit(1); } toBeDecrypted[99] = '\0'; /* Try to get a context with and without a new key set */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) { printLine("Error in acquiring cryptographic context"); exit(1); } } /* Create Hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { printLine("Error in creating hash"); exit(1); } /* Hash the password */ if(!CryptHashData(hHash, (BYTE *) password, passwordLen, 0)) { printLine("Error in hashing password"); exit(1); } /* Derive a RC5 key from the Hashed password */ if(!CryptDeriveKey(hCryptProv, CALG_RC5, hHash, 0, &hKey)) { printLine("Error in CryptDeriveKey"); exit(1); } /* FLAW: Decrypt using RC5 */ if(!CryptDecrypt(hKey, 0, 1, 0, (BYTE *)toBeDecrypted, &toBeDecryptedLen)) { printLine("Error in decryption"); exit(1); } /* Ensure the plaintext is NUL-terminated */ toBeDecrypted[toBeDecryptedLen] = '\0'; printLine(toBeDecrypted); /* Cleanup */ if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } if (pFile) { fclose(pFile); } } } }
void rust_win32_rand_release(HCRYPTPROV hProv) { win32_require (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0)); }
/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */ static void goodB2G1() { char * data; char dataBuffer[100] = ""; data = dataBuffer; if(STATIC_CONST_TRUE) { { FILE *pFile; pFile = fopen("passwords.txt", "r"); if (pFile != NULL) { /* POTENTIAL FLAW: Read the password from a file */ if (fgets(data, 100, pFile) == NULL) { data[0] = '\0'; } fclose(pFile); } else { data[0] = '\0'; } } } if(STATIC_CONST_FALSE) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { { HANDLE pHandle; char * username = "******"; char * domain = "Domain"; char hashData[100] = HASH_INPUT; HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; do { BYTE payload[(100 - 1) * sizeof(char)]; /* same size as data except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexChars(payload, sizeof(payload), data); /* Wipe the hex string, to prevent it from being given to LogonUserA if * any of the crypto calls fail. */ SecureZeroMemory(data, 100 * sizeof(char)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into data and NUL-terminate */ memcpy(data, payload, payloadBytes); data[payloadBytes / sizeof(char)] = '\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* FIX: Decrypt the password before using it for authentication */ if (LogonUserA( username, domain, data, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
void CWE321_Hard_Coded_Cryptographic_Key__w32_char_61_bad() { char * cryptoKey; char cryptoKeyBuffer[100] = ""; cryptoKey = cryptoKeyBuffer; cryptoKey = CWE321_Hard_Coded_Cryptographic_Key__w32_char_61b_badSource(cryptoKey); { HCRYPTPROV hCryptProv; HCRYPTKEY hKey; HCRYPTHASH hHash; char toBeEncrypted[] = "String to be encrypted"; DWORD encryptedLen = strlen(toBeEncrypted)*sizeof(char); BYTE encrypted[200]; /* buffer should be larger than toBeEncrypted to have room for IV and padding */ /* Copy plaintext (without NUL terminator) into byte buffer */ memcpy(encrypted, toBeEncrypted, encryptedLen); /* Try to get a context with and without a new key set */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_AES, 0)) { if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) { printLine("Error in acquiring cryptographic context"); exit(1); } } /* Create Hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { printLine("Error in creating hash"); exit(1); } /* Hash the cryptoKey */ if(!CryptHashData(hHash, (BYTE *) cryptoKey, strlen(cryptoKey)*sizeof(char), 0)) { printLine("Error in hashing cryptoKey"); exit(1); } /* Derive an AES key from the Hashed cryptoKey */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { printLine("Error in CryptDeriveKey"); exit(1); } /* POTENTIAL FLAW: Possibly using a hardcoded crypto key */ /* Use the derived key to encrypt something */ if(!CryptEncrypt(hKey, (HCRYPTHASH)NULL, 1, 0, encrypted, &encryptedLen, sizeof(encrypted))) { printLine("Error in CryptEncrypt"); exit(1); } /* use encrypted block */ printBytesLine(encrypted, encryptedLen); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } }
int KSI_PKITruststore_verifyRawSignature(KSI_CTX *ctx, const unsigned char *data, unsigned data_len, const char *algoOid, const unsigned char *signature, unsigned signature_len, const KSI_PKICertificate *certificate) { int res = KSI_UNKNOWN_ERROR; ALG_ID algorithm=0; HCRYPTPROV hCryptProv = 0; PCCERT_CONTEXT subjectCert = NULL; HCRYPTKEY publicKey = 0; DWORD i=0; BYTE *little_endian_pkcs1= NULL; DWORD pkcs1_len = 0; HCRYPTHASH hash = 0; char buf[1024]; KSI_ERR_clearErrors(ctx); if (ctx == NULL || data == NULL || signature == NULL || signature_len >= UINT_MAX || algoOid == NULL || certificate == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } algorithm = algIdFromOID(algoOid); if (algorithm == 0) { KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL); goto cleanup; } // Get the CSP context if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){ KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf))); KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get cryptographic provider."); goto cleanup; } // Get the public key from the issuer certificate subjectCert = certificate->x509; if (!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING,&subjectCert->pCertInfo->SubjectPublicKeyInfo,&publicKey)){ KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf))); KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Failed to read PKI public key."); goto cleanup; } /*Convert big-endian to little-endian PKCS#1 signature*/ pkcs1_len = signature_len; little_endian_pkcs1 = (BYTE*)KSI_malloc(pkcs1_len); if (little_endian_pkcs1 == NULL){ KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL); goto cleanup; } for (i=0; i<pkcs1_len; i++){ little_endian_pkcs1[pkcs1_len-1-i] = signature[i]; } // Create the hash object and hash input data. if (!CryptCreateHash(hCryptProv, algorithm, 0, 0, &hash)){ KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf))); KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to create hasher."); goto cleanup; } if (!CryptHashData(hash, (BYTE*)data, data_len,0)){ KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf))); KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to hash data."); goto cleanup; } /*Verify the signature. The format MUST be PKCS#1*/ if (!CryptVerifySignature(hash, (BYTE*)little_endian_pkcs1, pkcs1_len, publicKey, NULL, 0)){ DWORD error = GetLastError(); const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf)); KSI_LOG_debug(ctx, "%s", errmsg); if (error == NTE_BAD_SIGNATURE) KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Invalid PKI signature."); else if (error == NTE_NO_MEMORY) KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, "Unable to verify PKI signature. CSP out of memory."); else KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, errmsg); goto cleanup; } KSI_LOG_debug(certificate->ctx, "CryptoAPI: PKI signature verified successfully."); res = KSI_OK; cleanup: KSI_free(little_endian_pkcs1); if (hCryptProv) CryptReleaseContext(hCryptProv, 0); if (hash) CryptDestroyHash(hash); return res; }
HRESULT modmd5(LPSTR *hexhash) { HRESULT hRes; HANDLE hFile = NULL; DEBUG_MODULE_PARAMETERS ModParams; HCRYPTPROV hCryptProv = NULL; HCRYPTHASH hHash = NULL; BYTE *pbHashData = NULL; BYTE buffer[BUFSIZE]; DWORD cbHash; DWORD cbRead = 0; BOOL bResult = FALSE; /* msdn: returns parameters for modules in the target. */ hRes=g_ExtSymbols->GetModuleParameters(1, &g_Base, 0, &ModParams); if(FAILED(hRes)) { dprintf("[sync] modcheck: failed get module parameters\n"); return E_FAIL; } dprintf("[sync] modcheck:\n" " File: %s\n" " Size: 0x%x\n" " TimeDateStamp: 0x%x\n", g_NameBuffer, ModParams.Size, ModParams.TimeDateStamp); hRes=E_FAIL; hFile = CreateFile(g_NameBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile == INVALID_HANDLE_VALUE) { dprintf("[sync] failed at opening file: %d\n", GetLastError()); return hRes; } if (!(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))) { dprintf("[sync] CryptAcquireContext failed\n"); goto Exit; } if (!(CryptCreateHash(hCryptProv, CALG_MD5, NULL, NULL, &hHash))) { dprintf("[sync] CryptCreateHash failed\n"); goto Exit; } while (bResult = ReadFile(hFile, buffer, BUFSIZE, &cbRead, NULL)) { if (cbRead == 0) break; if (!(CryptHashData(hHash, buffer, cbRead, NULL))) { dprintf("[sync] CryptHashData failed\n"); goto Exit; } } if (!bResult) { dprintf("[sync] ReadFile failed\n"); goto Exit; } if (!(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &cbHash, 0))) { dprintf("[sync] CryptGetHashParam failed\n"); goto Exit; } pbHashData = (BYTE *) malloc(cbHash); if (pbHashData==NULL){ dprintf("[sync] failed at allocate buffer: %d\n", GetLastError()); goto Exit; } if (!(CryptGetHashParam(hHash, HP_HASHVAL, pbHashData, &cbHash, 0))) { dprintf("[sync] CryptGetHashParam failed\n"); goto Exit; } hRes = ToHexString((const byte *)pbHashData, (unsigned int)cbHash, hexhash); Exit: if (hFile) CloseHandle(hFile); if (pbHashData) free(pbHashData); if (hHash) CryptDestroyHash(hHash); if (hCryptProv) CryptReleaseContext(hCryptProv,0); return hRes; }
/* * SfcIsFileLegit * * Purpose: * * Verify file to be legit ZeroAccess signed binary. * * Verification algorithm (as for current version) * * 1. Open dll file, read it to the allocated buffer, read extended attribute VER, * containing retL packet data regarding file FileName, TimeStamp, FileSize, * Signature (unusued in this verification); * * 2. Import required RSA key (hardcoded in the bot); * * 3. Calc MD5 for FileName+TimeStamp+FileSize values; * * 4. Find resource [1] in dll file, which is embedded signature used to check; * * 5. Remember PE header CRC value, set it to zero in PE file buffer; * * 6. Copy embedded signature [1] to preallocated buffer, zero it in PE file buffer; * * 7. Update MD5 for PE file buffer (excluding PE CRC and signature); * * 8. Use result MD5 as hash value; * * 9. Verify embedded signature. * * If anything from the above fail - file is not legit by ZeroAccess opinion. * * If you copy ZeroAccess downloaded files without copying EA data, it cannot be verified. * */ NTSTATUS SfcIsFileLegit( _In_ LPWSTR lpFileName, _In_ PBYTE BotKey, _In_ DWORD BotKeySize ) { BOOL cond = FALSE; PVOID pBuffer; MD5_CTX context; ZA_FILEHEADER zaHeader; HCRYPTPROV lh_prov = 0; HCRYPTKEY lh_key = 0; HANDLE hFile = NULL; NTSTATUS status = STATUS_UNSUCCESSFUL; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING usFileName; SIZE_T memIO = 0; if ( (lpFileName == NULL) || (BotKey == NULL) || (BotKeySize == 0) ) { return status; } RtlSecureZeroMemory(&usFileName, sizeof(usFileName)); do { if (RtlDosPathNameToNtPathName_U(lpFileName, &usFileName, NULL, NULL) == FALSE) break; InitializeObjectAttributes(&ObjectAttributes, &usFileName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = NtOpenFile(&hFile, FILE_GENERIC_READ, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ); if (!NT_SUCCESS(status)) break; RtlFreeUnicodeString(&usFileName); RtlSecureZeroMemory(&zaHeader, sizeof(zaHeader)); if (!SfNtfsQueryFileHeaderFromEa(hFile, &zaHeader)) { status = STATUS_EA_LIST_INCONSISTENT; break; } status = STATUS_UNSUCCESSFUL; memIO = zaHeader.Size; pBuffer = NULL; if ( (NT_SUCCESS(NtAllocateVirtualMemory(NtCurrentProcess(), &pBuffer, 0, &memIO, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) && (pBuffer != NULL) ) { if (NT_SUCCESS(NtReadFile(hFile, NULL, NULL, NULL, &IoStatusBlock, pBuffer, zaHeader.Size, NULL, NULL))) { if (CryptAcquireContext(&lh_prov, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (CryptImportKey(lh_prov, (const BYTE *)BotKey, BotKeySize, 0, 0, &lh_key)) { RtlSecureZeroMemory(&context, sizeof(context)); MD5Init(&context); MD5Update(&context, (UCHAR*)&zaHeader, (UINT)3 * sizeof(ULONG)); //note: ZA_FILEHEADER without signature if (SfcVerifyFile(lh_prov, lh_key, &context, pBuffer, zaHeader.Size)) status = STATUS_SUCCESS; CryptDestroyKey(lh_key); } CryptReleaseContext(lh_prov, 0); } } memIO = 0; NtFreeVirtualMemory(NtCurrentProcess(), &pBuffer, &memIO, MEM_RELEASE); } NtClose(hFile); hFile = NULL; } while (cond); if (hFile != NULL) NtClose(hFile); if (usFileName.Buffer != NULL) { RtlFreeUnicodeString(&usFileName); } return status; }
/* goodG2B() - use goodsource and badsink by changing the conditions on the for statements */ static void goodG2B() { int h; wchar_t * cryptoKey; wchar_t cryptoKeyBuffer[100] = L""; cryptoKey = cryptoKeyBuffer; for(h = 0; h < 1; h++) { { size_t cryptoKeyLen = wcslen(cryptoKey); /* if there is room in cryptoKey, read into it from the console */ if(100-cryptoKeyLen > 1) { /* FIX: Obtain the hash input from the console */ if (fgetws(cryptoKey+cryptoKeyLen, (int)(100-cryptoKeyLen), stdin) == NULL) { printLine("fgetws() failed"); /* Restore NUL terminator if fgetws fails */ cryptoKey[cryptoKeyLen] = L'\0'; } /* The next 3 lines remove the carriage return from the string that is * inserted by fgetws() */ cryptoKeyLen = wcslen(cryptoKey); if (cryptoKeyLen > 0) { cryptoKey[cryptoKeyLen-1] = L'\0'; } } } } { HCRYPTPROV hCryptProv; HCRYPTKEY hKey; HCRYPTHASH hHash; wchar_t toBeEncrypted[] = L"String to be encrypted"; DWORD encryptedLen = wcslen(toBeEncrypted)*sizeof(wchar_t); BYTE encrypted[200]; /* buffer should be larger than toBeEncrypted to have room for IV and padding */ /* Copy plaintext (without NUL terminator) into byte buffer */ memcpy(encrypted, toBeEncrypted, encryptedLen); /* Try to get a context with and without a new key set */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_AES, 0)) { if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_AES, CRYPT_NEWKEYSET)) { printLine("Error in acquiring cryptographic context"); exit(1); } } /* Create Hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { printLine("Error in creating hash"); exit(1); } /* Hash the cryptoKey */ if(!CryptHashData(hHash, (BYTE *) cryptoKey, wcslen(cryptoKey)*sizeof(wchar_t), 0)) { printLine("Error in hashing cryptoKey"); exit(1); } /* Derive an AES key from the Hashed cryptoKey */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { printLine("Error in CryptDeriveKey"); exit(1); } /* POTENTIAL FLAW: Possibly using a hardcoded crypto key */ /* Use the derived key to encrypt something */ if(!CryptEncrypt(hKey, (HCRYPTHASH)NULL, 1, 0, encrypted, &encryptedLen, sizeof(encrypted))) { printLine("Error in CryptEncrypt"); exit(1); } /* use encrypted block */ printBytesLine(encrypted, encryptedLen); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } }
int KSI_DataHasher_open(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, KSI_DataHasher **hasher) { int res = KSI_UNKNOWN_ERROR; KSI_DataHasher *tmp_hasher = NULL; CRYPTO_HASH_CTX *tmp_cryptoCTX = NULL; HCRYPTPROV tmp_CSP = 0; KSI_ERR_clearErrors(ctx); if (ctx == NULL || hasher == NULL){ res = KSI_INVALID_ARGUMENT; goto cleanup; } /*Test if hash algorithm is valid*/ if (!KSI_isHashAlgorithmSupported(algo_id)) { KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL); goto cleanup; } /*Create new abstract data hasher object*/ tmp_hasher = KSI_new(KSI_DataHasher); if (tmp_hasher == NULL) { KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL); goto cleanup; } tmp_hasher->hashContext = NULL; tmp_hasher->ctx = ctx; tmp_hasher->algorithm = algo_id; tmp_hasher->closeExisting = closeExisting; /*Create new helper context for crypto api*/ res = CRYPTO_HASH_CTX_new(&tmp_cryptoCTX); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } /*Create new crypto service provider (CSP)*/ if (!CryptAcquireContext(&tmp_CSP, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){ char errm[1024]; KSI_snprintf(errm, sizeof(errm), "Wincrypt Error (%d)", GetLastError()); KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, errm); goto cleanup; } /*Set CSP in helper struct*/ tmp_cryptoCTX->pt_CSP = tmp_CSP; /*Set helper struct in abstract struct*/ tmp_hasher->hashContext = tmp_cryptoCTX; res = KSI_DataHasher_reset(tmp_hasher); if (res != KSI_OK) { KSI_pushError(ctx, res, NULL); goto cleanup; } *hasher = tmp_hasher; tmp_hasher = NULL; tmp_cryptoCTX = NULL; tmp_CSP = 0; res = KSI_OK; cleanup: KSI_DataHasher_free(tmp_hasher); if (tmp_CSP) CryptReleaseContext(tmp_CSP, 0); CRYPTO_HASH_CTX_free(tmp_cryptoCTX); return res; }
uint8_t ntru_rand_wincrypt_release(NtruRandContext *rand_ctx) { HCRYPTPROV *hCryptProv = (HCRYPTPROV*)rand_ctx->state; uint8_t result = CryptReleaseContext(*hCryptProv, 0); free(hCryptProv); return result; }
void _cdecl main(void) { INT iReturn = 0; HCRYPTPROV hProv = 0; LPSTR pszContainerName = NULL; DWORD cbContainerName = 0; HCRYPTKEY hKey; // Attempt to acquire a handle to the default key container. if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) { if(GetLastError() != NTE_BAD_KEYSET) { // Some sort of error occured. printf("Error opening default key container!\n"); goto Error; } // Create default key container. if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { printf("Error creating default key container!\n"); goto Error; } // Get size of the name of the default key container name. if(CryptGetProvParam(hProv, PP_CONTAINER, NULL, &cbContainerName, 0)) { // Allocate buffer to receive default key container name. pszContainerName = malloc(cbContainerName); if(pszContainerName) { // Get name of default key container name. if(!CryptGetProvParam(hProv, PP_CONTAINER, (PBYTE)pszContainerName, &cbContainerName, 0)) { // Error getting default key container name. pszContainerName[0] = 0; } } } printf("Create key container '%s'\n", pszContainerName ? pszContainerName : ""); // Free container name buffer (if created) if(pszContainerName) { free(pszContainerName); } } // Attempt to get handle to signature key. if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) { if(GetLastError() != NTE_NO_KEY) { printf("Error %x during CryptGetUserKey!\n", GetLastError()); goto Error; } // Create signature key pair. printf("Create signature key pair\n"); if(!CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey)) { printf("Error %x during CryptGenKey!\n", GetLastError()); goto Error; } } // Close key handle CryptDestroyKey(hKey); // Attempt to get handle to exchange key. if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey)) { if(GetLastError() != NTE_NO_KEY) { printf("Error %x during CryptGetUserKey!\n", GetLastError()); goto Error; } // Create key exchange key pair. printf("Create key exchange key pair\n"); if(!CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey)) { printf("Error %x during CryptGenKey!\n", GetLastError()); goto Error; } } // Close key handle CryptDestroyKey(hKey); printf("OK\n"); Exit: // Close the context (if open) if(hProv) { CryptReleaseContext(hProv, 0); } exit(iReturn); Error: iReturn = 1; goto Exit; }
BOOL CreateSignatureHMACSHA1(wstring src, wstring secretKey, wstring& signature) { signature = L""; string hashSrc = ""; string hashKey = ""; WtoUTF8(src, hashSrc); WtoUTF8(secretKey, hashKey); HCRYPTPROV cryptProv = NULL; HCRYPTHASH cryptHash = NULL; BYTE key[65]; DWORD keySize = 0; BYTE ipad[65]; BYTE opad[65]; ZeroMemory(key, 65); ZeroMemory(ipad, 65); ZeroMemory(opad, 65); BYTE* firstHash = NULL; DWORD firstHashSize = 0; BYTE* secondHash = NULL; DWORD secondHashSize = 0; WCHAR* base64 = NULL; DWORD base64Size = 0; if ( CryptAcquireContext(&cryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE ){ goto Err_End; } if( hashKey.size() > 64 ){ if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, (BYTE*)hashKey.c_str(), (DWORD)hashKey.length(), 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &keySize, 0 ) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, key, &keySize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; }else{ keySize = (DWORD)hashKey.size(); memcpy(key, hashKey.c_str(), keySize); } memcpy(ipad, key, keySize); memcpy(opad, key, keySize); for( int i=0; i<64; i++ ){ ipad[i] ^= 0x36; opad[i] ^= 0x5c; } if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, ipad, 64, 0) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, (BYTE*)hashSrc.c_str(), (DWORD)hashSrc.size(), 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &firstHashSize, 0 ) == FALSE ){ goto Err_End; } firstHash = new BYTE[firstHashSize]; if( CryptGetHashParam(cryptHash, HP_HASHVAL, firstHash, &firstHashSize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, opad, 64, 0) == FALSE ){ goto Err_End; } if( CryptHashData(cryptHash, firstHash, firstHashSize, 0) == FALSE ){ goto Err_End; } if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &secondHashSize, 0 ) == FALSE ){ goto Err_End; } secondHash = new BYTE[secondHashSize]; if( CryptGetHashParam(cryptHash, HP_HASHVAL, secondHash, &secondHashSize, 0 ) == FALSE ){ goto Err_End; } CryptDestroyHash(cryptHash); cryptHash = NULL; //Base64 if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, NULL, &base64Size ) == FALSE){ goto Err_End; } base64 = new WCHAR[ base64Size + 1 ]; if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, base64, &base64Size ) == FALSE ){ goto Err_End; } signature = base64; //最後に\r\n入ってしまうみたいなので除去 Replace(signature, L"\r\n", L""); Err_End: SAFE_DELETE_ARRAY(base64); SAFE_DELETE_ARRAY(secondHash); SAFE_DELETE_ARRAY(firstHash); if( cryptHash !=NULL ){ CryptDestroyHash(cryptHash); } if( cryptProv != NULL ){ CryptReleaseContext(cryptProv, 0); } if( signature.size() > 0 ){ return TRUE; }else{ return FALSE; } }
//----------------------------------------------------------------------------- // swCryptTerm() //----------------------------------------------------------------------------- // Libération du CSP //----------------------------------------------------------------------------- void swCryptTerm() { TRACE((TRACE_ENTER,_F_,"")); if (ghProv!=NULL) { CryptReleaseContext(ghProv,0); ghProv=NULL; } TRACE((TRACE_LEAVE,_F_,"")); }
char * mit_krb5_pkinit_cert_hash_str(const mit_krb5_data *cert) { #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H CC_SHA1_CTX ctx; char *outstr, *cpOut; unsigned char digest[CC_SHA1_DIGEST_LENGTH]; unsigned i; LOG_ENTRY(); CC_SHA1_Init(&ctx); CC_SHA1_Update(&ctx, cert->data, cert->length); CC_SHA1_Final(digest, &ctx); cpOut = outstr = (char *)malloc((2 * CC_SHA1_DIGEST_LENGTH) + 1); if(outstr == NULL) return NULL; for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++, cpOut += 2) sprintf(cpOut, "%02X", (unsigned)digest[i]); *cpOut = '\0'; return outstr; #elif defined(_WIN32) HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; char *outstr = NULL; char *outpos; size_t cch_left; BYTE *hash = NULL; DWORD hashSize = 0; DWORD len, i; LOG_ENTRY(); if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SIG, CRYPT_VERIFYCONTEXT)) { LOG_LASTERROR("CryptAcquireContext failed"); goto done; } if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { LOG_LASTERROR("CryptCreateHash failed"); goto done; } if (!CryptHashData(hHash, (BYTE *) cert->data, cert->length, 0)) { LOG_LASTERROR("CryptHashData failed"); goto done; } len = sizeof(hashSize); if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) &hashSize, &len, 0)) { LOG_LASTERROR("CryptGetHashParam failed while getting hash size"); goto done; } hash = malloc(hashSize); if (hash == NULL) { goto done; } len = hashSize; if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &len, 0)) { LOG_LASTERROR("CryptGetHashParam failed while getting hash"); goto done; } outstr = malloc(hashSize * 2 + 1); if (outstr == NULL) { goto done; } outpos = outstr; cch_left = hashSize * 2 + 1; for (i = 0; i < hashSize; i++) { StringCchPrintfExA(outpos, cch_left, &outpos, &cch_left, STRSAFE_FILL_ON_FAILURE, "%02X", (unsigned) hash[i]); } *outpos = '\0'; done: if (hHash != 0) CryptDestroyHash(hHash); if (hProv != 0) CryptReleaseContext(hProv, 0); if (hash != NULL) free(hash); return outstr; #endif }
isc_result_t isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) { isc_result_t ret; isc_entropysource_t *source; HCRYPTPROV hcryptprov; DWORD errval; BOOL err; REQUIRE(VALID_ENTROPY(ent)); REQUIRE(fname != NULL); LOCK(&ent->lock); source = NULL; /* * The first time we just try to acquire the context */ err = CryptAcquireContext(&hcryptprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!err){ errval = GetLastError(); ret = ISC_R_IOERROR; goto errout; } source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t)); if (source == NULL) { ret = ISC_R_NOMEMORY; goto closecontext; } /* * From here down, no failures can occur. */ source->magic = SOURCE_MAGIC; source->type = ENTROPY_SOURCETYPE_FILE; source->ent = ent; source->total = 0; source->bad = ISC_FALSE; memset(source->name, 0, sizeof(source->name)); ISC_LINK_INIT(source, link); source->sources.file.handle = hcryptprov; /* * Hook it into the entropy system. */ ISC_LIST_APPEND(ent->sources, source, link); ent->nsources++; UNLOCK(&ent->lock); return (ISC_R_SUCCESS); closecontext: CryptReleaseContext(hcryptprov, 0); errout: if (source != NULL) isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t)); UNLOCK(&ent->lock); return (ret); }
/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ static void goodB2G2() { wchar_t * password; wchar_t passwordBuffer[100] = L""; password = passwordBuffer; if(GLOBAL_CONST_TRUE) { { WSADATA wsaData; int wsaDataInit = 0; int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET connectSocket = INVALID_SOCKET; size_t passwordLen = wcslen(password); do { if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(IP_ADDRESS); service.sin_port = htons(TCP_PORT); if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed, make sure to recv one * less char than is in the recv_buf in order to append a terminator */ /* POTENTIAL FLAW: Reading sensitive data from the network */ recvResult = recv(connectSocket, (char*)(password + passwordLen), (100 - passwordLen - 1) * sizeof(wchar_t), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ password[passwordLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(password, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(password, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (connectSocket != INVALID_SOCKET) { closesocket(connectSocket); } if (wsaDataInit) { WSACleanup(); } } } if(GLOBAL_CONST_TRUE) { { HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as password except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), password); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(password, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } /* FIX: Decrypt the password */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into password and NUL-terminate */ memcpy(password, payload, payloadBytes); password[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Use the password in LogonUser() to establish that it is "sensitive" */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
int_t main(void) { error_t error; size_t length; int_t ret; WSADATA wsaData; HOSTENT *host; SOCKADDR_IN addr; HCRYPTPROV hProvider; YarrowContext yarrowContext; char_t buffer[512]; uint8_t seed[32]; //Socket descriptor SOCKET sock = SOCKET_ERROR; //SSL/TLS context TlsContext *tlsContext = NULL; //Credentials char_t *clientCert = NULL; size_t clientCertLength = 0; char_t *clientPrivateKey = NULL; size_t clientPrivateKeyLength = 0; char_t *trustedCaList = NULL; size_t trustedCaListLength = 0; //Start-up message TRACE_INFO("******************************\r\n"); TRACE_INFO("*** CycloneSSL Client Demo ***\r\n"); TRACE_INFO("******************************\r\n"); TRACE_INFO("\r\n"); //Acquire cryptographic context ret = CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT); //Any error to report? if(!ret) { //Debug message TRACE_ERROR("Error: Cannot acquire cryptographic context (%d)\r\n", GetLastError()); //Exit immediately return ERROR_FAILURE; } //Generate a random seed ret = CryptGenRandom(hProvider, sizeof(seed), seed); //Any error to report? if(!ret) { //Debug message TRACE_ERROR("Error: Failed to generate random data (%d)\r\n", GetLastError()); //Exit immediately return ERROR_FAILURE; } //Release cryptographic context CryptReleaseContext(hProvider, 0); //PRNG initialization error = yarrowInit(&yarrowContext); //Any error to report? if(error) { //Debug message TRACE_ERROR("Error: PRNG initialization failed (%d)\r\n", error); //Exit immediately return ERROR_FAILURE; } //Properly seed the PRNG error = yarrowSeed(&yarrowContext, seed, sizeof(seed)); //Any error to report? if(error) { //Debug message TRACE_ERROR("Error: Failed to seed PRNG (%d)\r\n", error); //Exit immediately return error; } //Winsock initialization ret = WSAStartup(MAKEWORD(2, 2), &wsaData); //Any error to report? if(ret) { //Debug message TRACE_ERROR("Error: Winsock initialization failed (%d)\r\n", ret); //Exit immediately return ERROR_FAILURE; } //Start of exception handling block do { //Debug message TRACE_INFO("Loading credentials...\r\n"); //Load trusted CA certificates error = readPemFile(APP_CA_CERT_BUNDLE, &trustedCaList, &trustedCaListLength); //Any error to report? if(error) break; //Load client's certificate error = readPemFile(APP_CLIENT_CERT, &clientCert, &clientCertLength); //Any error to report? if(error) break; //Load client's private key error = readPemFile(APP_CLIENT_PRIVATE_KEY, &clientPrivateKey, &clientPrivateKeyLength); //Any error to report? if(error) break; //Debug message TRACE_INFO("Trying to resolve %s...\r\n", APP_SERVER_NAME); //Resolve server name host = gethostbyname(APP_SERVER_NAME); //Failed to resolve server name? if(!host) { //Debug message TRACE_ERROR("Error: Cannot resolve server name (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Open a socket sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //Failed to open socket? if(sock < 0) { //Debug message TRACE_ERROR("Error: Cannot open socket (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Destination address addr.sin_family = host->h_addrtype; memcpy(&addr.sin_addr, host->h_addr, host->h_length); addr.sin_port = htons(APP_SERVER_PORT); //Connect to the SSL server ret = connect(sock, (PSOCKADDR) &addr, sizeof(addr)); //Connection with server failed? if(ret < 0) { //Debug message TRACE_ERROR("Error: Failed to connect (%d)\r\n", WSAGetLastError()); //Report an error error = ERROR_FAILURE; //Exit immediately break; } //Initialize SSL/TLS context tlsContext = tlsInit(); //Initialization failed? if(!tlsContext) { //Report an error error = ERROR_OUT_OF_MEMORY; //Exit immediately break; } //Bind TLS to the relevant socket error = tlsSetSocket(tlsContext, sock); //Any error to report? if(error) break; //Select client operation mode error = tlsSetConnectionEnd(tlsContext, TLS_CONNECTION_END_CLIENT); //Any error to report? if(error) break; //Set the PRNG algorithm to be used error = tlsSetPrng(tlsContext, YARROW_PRNG_ALGO, &yarrowContext); //Any error to report? if(error) break; #if (APP_SET_CIPHER_SUITES == ENABLED) //Preferred cipher suite list error = tlsSetCipherSuites(tlsContext, cipherSuites, arraysize(cipherSuites)); //Any error to report? if(error) break; #endif #if (APP_SET_SERVER_NAME == ENABLED) //Set the fully qualified domain name of the server error = tlsSetServerName(tlsContext, APP_SERVER_NAME); //Any error to report? if(error) break; #endif #if (APP_SET_TRUSTED_CA_LIST == ENABLED) //Import the list of trusted CA certificates error = tlsSetTrustedCaList(tlsContext, trustedCaList, trustedCaListLength); //Any error to report? if(error) break; #endif #if (APP_SET_CLIENT_CERT == ENABLED) //Import the client's certificate error = tlsAddCertificate(tlsContext, clientCert, clientCertLength, clientPrivateKey, clientPrivateKeyLength); //Any error to report? if(error) break; #endif //Establish a secure session error = tlsConnect(tlsContext); //TLS handshake failure? if(error) break; //Format HTTP request sprintf(buffer, "GET %s HTTP/1.0\r\nHost: %s:%u\r\n\r\n", APP_REQUEST_URI, APP_SERVER_NAME, APP_SERVER_PORT); //Debug message TRACE_INFO("\r\n"); TRACE_INFO("HTTP request:\r\n%s", buffer); //Send the request error = tlsWrite(tlsContext, buffer, strlen(buffer), 0); //Any error to report? if(error) break; //Debug message TRACE_INFO("HTTP response:\r\n"); //Read the whole response while(1) { //Read data error = tlsRead(tlsContext, buffer, sizeof(buffer) - 1, &length, 0); //End of stream? if(error) break; //Properly terminate the string with a NULL character buffer[length] = '\0'; //Debug message TRACE_INFO("%s", buffer); } //Successfull processing error = NO_ERROR; //End of exception handling block } while(0); //Terminate TLS session tlsFree(tlsContext); //Close socket if necessary if(sock >= 0) closesocket(sock); //Free previously allocated resources free(trustedCaList); free(clientCert); free(clientPrivateKey); //Release PRNG context yarrowRelease(&yarrowContext); //Winsock related cleanup WSACleanup(); //Dumps all the memory blocks in the heap when a memory leak has occurred _CrtDumpMemoryLeaks(); //Wait for the user to press a key system("pause"); //Return status code return error; }
/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ static void goodB2G2Sink(wchar_t * password) { if(goodB2G2Static) { { HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as password except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), password); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(password, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } /* FIX: Decrypt the password */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into password and NUL-terminate */ memcpy(password, payload, payloadBytes); password[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Use the password in LogonUser() to establish that it is "sensitive" */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
my_bool ma_schannel_load_private_key(MARIADB_PVIO *pvio, CERT_CONTEXT *ctx, char *key_file) { DWORD der_buffer_len= 0; LPBYTE der_buffer= NULL; DWORD priv_key_len= 0; LPBYTE priv_key= NULL; HCRYPTPROV crypt_prov= 0; HCRYPTKEY crypt_key= 0; CERT_KEY_CONTEXT kpi={ 0 }; my_bool rc= 0; /* load private key into der binary object */ if (!(der_buffer= ma_schannel_load_pem(pvio, key_file, &der_buffer_len))) return 0; /* determine required buffer size for decoded private key */ if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, der_buffer, der_buffer_len, 0, NULL, NULL, &priv_key_len)) { ma_schannel_set_win_error(pvio); goto end; } /* allocate buffer for decoded private key */ if (!(priv_key= LocalAlloc(0, priv_key_len))) { pvio->set_error(pvio->mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, NULL); goto end; } /* decode */ if (!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, PKCS_RSA_PRIVATE_KEY, der_buffer, der_buffer_len, 0, NULL, priv_key, &priv_key_len)) { ma_schannel_set_win_error(pvio); goto end; } /* Acquire context */ if (!CryptAcquireContext(&crypt_prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { ma_schannel_set_win_error(pvio); goto end; } /* ... and import the private key */ if (!CryptImportKey(crypt_prov, priv_key, priv_key_len, 0, 0, (HCRYPTKEY *)&crypt_key)) { ma_schannel_set_win_error(pvio); goto end; } kpi.hCryptProv= crypt_prov; kpi.dwKeySpec = AT_KEYEXCHANGE; kpi.cbSize= sizeof(kpi); /* assign private key to certificate context */ if (CertSetCertificateContextProperty(ctx, CERT_KEY_CONTEXT_PROP_ID, 0, &kpi)) rc= 1; else ma_schannel_set_win_error(pvio); end: if (der_buffer) LocalFree(der_buffer); if (priv_key) { if (crypt_key) CryptDestroyKey(crypt_key); LocalFree(priv_key); if (!rc) if (crypt_prov) CryptReleaseContext(crypt_prov, 0); } return rc; }
/* good2() reverses the bodies in the if statement */ static void good2() { if(staticTrue) { { HCRYPTPROV hCryptProv; HCRYPTHASH hHash; FILE *pFile = NULL; char password[PASSWORD_INPUT_SIZE]; UCHAR savedHash[SHA512_SUM_SIZE], calcHash[SHA512_SUM_SIZE]; DWORD hashSize; char *replace; size_t i; pFile = fopen("password.txt", "r"); if (pFile == NULL) { exit(1); } for (i = 0; i < SHA512_SUM_SIZE; i++) { ULONG val; if (fscanf(pFile, "%02x", &val) != 1) { fclose(pFile); exit(1); } if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */ { fclose(pFile); exit(1); } savedHash[i] = (UCHAR)val; } fclose(pFile); if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL) { exit(1); } replace = strchr(password, '\r'); if (replace) { *replace = '\0'; } replace = strchr(password, '\n'); if (replace) { *replace = '\0'; } if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0)) { exit(1); } /* FIX: use a non-reversible hash (SHA-512) */ if (!CryptCreateHash(hCryptProv, CALG_SHA_512, 0, 0, &hHash)) { CryptReleaseContext(hCryptProv, 0); exit(1); } /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags, * the password hash was not securely transmitted (via one form or another), * that may raise flags */ if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } hashSize = SHA512_SUM_SIZE; if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } if (memcmp(savedHash, calcHash, SHA512_SUM_SIZE * sizeof(UCHAR)) == 0) { printLine("Access granted"); } else { printLine("Access denied"); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } } }
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv, DWORD dwFlags, const void *pvPara) { HCERTSTORE store = 0; LPCWSTR fileName = (LPCWSTR)pvPara; DWORD access, create; HANDLE file; TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName)); if (!fileName) { SetLastError(ERROR_PATH_NOT_FOUND); return NULL; } if ((dwFlags & CERT_STORE_READONLY_FLAG) && (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)) { SetLastError(E_INVALIDARG); return NULL; } access = GENERIC_READ; if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG) access |= GENERIC_WRITE; if (dwFlags & CERT_STORE_CREATE_NEW_FLAG) create = CREATE_NEW; else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG) create = OPEN_EXISTING; else create = OPEN_ALWAYS; file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); if (file != INVALID_HANDLE_VALUE) { HCERTSTORE memStore = NULL; DWORD size = GetFileSize(file, NULL), type = 0; /* If the file isn't empty, try to get the type from the file itself */ if (size) { DWORD contentType; BOOL ret; /* Close the file so CryptQueryObject can succeed.. */ CloseHandle(file); ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName, CERT_QUERY_CONTENT_FLAG_CERT | CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE | CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED, CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL, &memStore, NULL, NULL); if (ret) { if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED) type = CERT_STORE_SAVE_AS_PKCS7; else type = CERT_STORE_SAVE_AS_STORE; /* and reopen the file. */ file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create, FILE_ATTRIBUTE_NORMAL, NULL); } } else { static const WCHAR spc[] = { 's','p','c',0 }; static const WCHAR p7c[] = { 'p','7','c',0 }; LPCWSTR ext = strrchrW(fileName, '.'); if (ext) { ext++; if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c)) type = CERT_STORE_SAVE_AS_PKCS7; } if (!type) type = CERT_STORE_SAVE_AS_STORE; memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, NULL); } if (memStore) { store = CRYPT_CreateFileStore(dwFlags, memStore, file, type); /* File store doesn't need crypto provider, so close it */ if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG)) CryptReleaseContext(hCryptProv, 0); } } return (PWINECRYPT_CERTSTORE)store; }
PCCERT_CONTEXT SslSocketCpServer::CreateOurCertificate() { // CertCreateSelfSignCertificate(0,&SubjectName,0,0,0,0,0,0); HRESULT hr = 0; HCRYPTPROV hProv = NULL; PCCERT_CONTEXT p = 0; HCRYPTKEY hKey = 0; CERT_NAME_BLOB sib = { 0 }; BOOL AX = 0; // Step by step to create our own certificate try { // Create the subject char cb[1000] = { 0 }; sib.pbData = (BYTE*)cb; sib.cbData = 1000; wchar_t* szSubject = L"CN=Certificate"; if (!CertStrToName(CRYPT_ASN_ENCODING, szSubject, 0, 0, sib.pbData, &sib.cbData, NULL)) throw; // Acquire Context wchar_t* pszKeyContainerName = L"Container"; if (!CryptAcquireContext(&hProv, pszKeyContainerName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) { hr = GetLastError(); if (GetLastError() == NTE_EXISTS) { if (!CryptAcquireContext(&hProv, pszKeyContainerName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) { throw; } } else throw; } // Generate KeyPair if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) throw; // Generate the certificate CRYPT_KEY_PROV_INFO kpi = { 0 }; kpi.pwszContainerName = pszKeyContainerName; kpi.pwszProvName = MS_DEF_PROV; kpi.dwProvType = PROV_RSA_FULL; kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; kpi.dwKeySpec = AT_KEYEXCHANGE; SYSTEMTIME et; GetSystemTime(&et); et.wYear += 1; CERT_EXTENSIONS exts = { 0 }; p = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, &et, &exts); AX = CryptFindCertificateKeyProvInfo(p, CRYPT_FIND_MACHINE_KEYSET_FLAG, NULL); hCS = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, CERT_STORE_CREATE_NEW_FLAG, 0); /*AX = CertAddCertificateContextToStore(hCS,p,CERT_STORE_ADD_NEW,0); AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL);*/ } catch (...) { } if (hKey) CryptDestroyKey(hKey); hKey = 0; if (hProv) CryptReleaseContext(hProv, 0); hProv = 0; return p; }
int VerifyDataSignWithHashAlg(const char * userData, const char * hashAlg, const char * certDataB64, const char * signatureDataB64) { int rv = -1; int ulHashAlg = 0; HCRYPTHASH hHash = NULL; char * pbCert = NULL; char * pbSignature = NULL; unsigned int ulCert = 0; unsigned int ulSignature = 0; PCCERT_CONTEXT pCertContext = NULL; HCRYPTPROV hProv = NULL; HCRYPTKEY hPubKey = NULL; { ulCert = modp_b64_decode_len(strlen(certDataB64)); ulSignature = modp_b64_decode_len(strlen(signatureDataB64)); pbCert = (char *)malloc(ulCert); pbSignature = (char *) malloc(ulSignature); if (NULL == pbCert || NULL == pbSignature) { sprintf(m_errMsg, "%s","memroy less.\n" ); goto err; } ulCert = modp_b64_decode(pbCert, certDataB64,strlen(certDataB64)); ulSignature = modp_b64_decode(pbSignature, signatureDataB64,strlen(signatureDataB64)); } if (0 == strcmp(hashAlg, "MD5")) { ulHashAlg = CALG_MD5; } else if (0 == strcmp(hashAlg, "SHA")) { ulHashAlg = CALG_SHA; } else if (0 == strcmp(hashAlg, "SHA1")) { ulHashAlg = CALG_SHA1; } else if (0 == strcmp(hashAlg, "SHA_256")) { ulHashAlg = CALG_SHA_256; } else if (0 == strcmp(hashAlg, "SHA_384")) { ulHashAlg = CALG_SHA_384; } pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE *)pbCert,ulCert); if (!pCertContext) { sprintf(m_errMsg, "%s","Select Certificate UI failed.\n" ); goto err; } //Ò»¡¢»ñµÃÒ»¸öCSP¾ä±ú if(!CryptAcquireContext( &hProv, NULL, //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷ NULL, //CSP_NAME PROV_RSA_FULL, 0 )) { if(!CryptAcquireContext( &hProv, NULL, //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷ NULL, //CSP_NAME PROV_RSA_FULL, CRYPT_NEWKEYSET //´´½¨ÃÜÔ¿ÈÝÆ÷ )) { sprintf(m_errMsg, "%s","CryptAcquireContext fail.\n"); goto err; } } if(CryptImportPublicKeyInfo( hProv, X509_ASN_ENCODING, &(pCertContext->pCertInfo->SubjectPublicKeyInfo), &hPubKey )) { sprintf(m_errMsg,"CryptImportPublicKeyInfo OK. \n"); } else { sprintf(m_errMsg,"Error CryptImportPublicKeyInfo.\n"); goto err; } //if(CryptImportKey(hProv,pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, NULL, 0, &hPubKey)) //{ // sprintf(m_errMsg,"CryptImportKey OK. \n"); //} //else //{ // sprintf(m_errMsg,"Error CryptImportKey.\n"); // goto err; //} if(CryptCreateHash( hProv, ulHashAlg, 0, 0, &hHash)) { sprintf(m_errMsg, "%s","An empty hash object has been created. \n"); } else { sprintf(m_errMsg, "%s","Error during CryptBeginHash!\n"); goto err; } //-------------------------------------------------------------------- // This code assumes that the handle of a cryptographic context // has been acquired and that a hash object has been created // and its handle (hHash) is available. if(CryptHashData( hHash, (unsigned char *)userData, strlen(userData), 0)) { sprintf(m_errMsg, "%s","The data buffer has been added to the hash.\n"); } else { sprintf(m_errMsg, "%s","Error during CryptHashData.\n"); goto err; } if(CryptVerifySignature(hHash, (const BYTE *)pbSignature, ulSignature,hPubKey,NULL,0)) { sprintf(m_errMsg,"verify OK.\n"); } else { sprintf(m_errMsg,"Error during CryptVerifySignature.\n"); goto err; } rv = 0; err: if(hHash) { CryptDestroyHash(hHash); } if (pbSignature) { free(pbSignature); } if (pbCert) { free(pbCert); } if (pCertContext) { CertFreeCertificateContext(pCertContext); } if(hProv) { CryptReleaseContext(hProv,0); } return rv; }
void _tmain(int argc, TCHAR *argv[]) { BOOL fResult = FALSE; HCRYPTPROV hProv = NULL; HCRYPTHASH hHash = NULL; HCRYPTKEY hSessionKey = NULL; HANDLE hInFile = INVALID_HANDLE_VALUE; HANDLE hOutFile = INVALID_HANDLE_VALUE; BOOL fEncrypt = FALSE; BOOL finished = FALSE; BYTE pbBuffer[OUT_BUFFER_SIZE]; DWORD dwByteCount = 0; DWORD dwBytesWritten = 0; if (argc != 5) { PrintUsage(); return; } __try { /* Check whether the action to be performed is encrypt or decrypt */ if (_tcsicmp(argv[2], _T("/e")) == 0) { fEncrypt = TRUE; } else if (_tcsicmp(argv[2], _T("/d")) == 0) { fEncrypt = FALSE; } else { PrintUsage(); return; } // Open the input file to be encrypted or decrypted hInFile = CreateFile(argv[3], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hInFile == INVALID_HANDLE_VALUE) { _tprintf(_T("CreateFile failed with %d\n"), GetLastError()); __leave; } // Open the output file to write the encrypted or decrypted data hOutFile = CreateFile(argv[4], GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hOutFile == INVALID_HANDLE_VALUE) { _tprintf(_T("CreateFile failed with %d\n"), GetLastError()); __leave; } // Acquire a handle to MS_DEF_PROV using CRYPT_VERIFYCONTEXT for dwFlags // parameter as we are going to do only session key encryption or decryption fResult = CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!fResult) { _tprintf(_T("CryptAcquireContext failed with %X\n"), GetLastError()); __leave; } fResult = CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash); if (!fResult) { _tprintf(_T("CryptCreateHash failed with %X\n"), GetLastError()); __leave; } // Hash the supplied secret password fResult = CryptHashData(hHash, (LPBYTE)argv[1], (DWORD)_tcslen(argv[1]), 0); if (!fResult) { _tprintf(_T("CryptHashData failed with %X\n"), GetLastError()); __leave; } // Derive a symmetric session key from password hash fResult = CryptDeriveKey(hProv, CALG_RC4, hHash, 0, &hSessionKey); if (!fResult) { _tprintf(_T("CryptDeriveKey failed with %X\n"), GetLastError()); __leave; } do { dwByteCount = 0; // Now read data from the input file 64K bytes at a time. fResult = ReadFile(hInFile, pbBuffer, IN_BUFFER_SIZE, &dwByteCount, NULL); // If the file size is exact multiple of 64K, dwByteCount will be zero after // all the data has been read from the input file. In this case, simply break // from the while loop. The check to do this is below if (dwByteCount == 0) break; if (!fResult) { _tprintf(_T("ReadFile failed with %d\n"), GetLastError()); __leave; } finished = (dwByteCount < IN_BUFFER_SIZE); // Encrypt/Decrypt depending on the required action. if (fEncrypt) { fResult = CryptEncrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount, OUT_BUFFER_SIZE); if (!fResult) { _tprintf(_T("CryptEncrypt failed with %X\n"), GetLastError()); __leave; } } else { fResult = CryptDecrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount); if (!fResult) { _tprintf(_T("CryptDecrypt failed with %X\n"), GetLastError()); __leave; } } // Write the encrypted/decrypted data to the output file. fResult = WriteFile(hOutFile, pbBuffer, dwByteCount, &dwBytesWritten, NULL); if (!fResult) { _tprintf(_T("WriteFile failed with %d\n"), GetLastError()); __leave; } } while (!finished); if (fEncrypt) _tprintf(_T("File %s is encrypted successfully!\n"), argv[3]); else _tprintf(_T("File %s is decrypted successfully!\n"), argv[3]); } __finally { /* Cleanup */ if (hInFile != INVALID_HANDLE_VALUE) CloseHandle(hInFile); if (hOutFile != INVALID_HANDLE_VALUE) CloseHandle(hOutFile); if (hSessionKey != NULL) CryptDestroyKey(hSessionKey); if (hHash != NULL) CryptDestroyHash(hHash); if (hProv != NULL) CryptReleaseContext(hProv, 0); } }
string md5file(wchar_t* file){ DWORD dwStatus = 0; BOOL bResult = FALSE; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; HANDLE hFile = NULL; BYTE rgbFile[BUFSIZE]; DWORD cbRead = 0; BYTE rgbHash[MD5LEN]; DWORD cbHash = 0; CHAR rgbDigits[] = "0123456789abcdef"; // Logic to check usage goes here. hFile = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == hFile) { dwStatus = GetLastError(); return ""; } // Get handle to the crypto provider if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { dwStatus = GetLastError(); (hFile); CloseHandle(file); return ""; } if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { dwStatus = GetLastError(); CloseHandle(hFile); CryptReleaseContext(hProv, 0); return ""; } while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, &cbRead, NULL)) { if (0 == cbRead) { break; } if (!CryptHashData(hHash, rgbFile, cbRead, 0)) { dwStatus = GetLastError(); printf("CryptHashData failed: %d\n", dwStatus); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return ""; } } if (!bResult) { dwStatus = GetLastError(); printf("ReadFile failed: %d\n", dwStatus); CryptReleaseContext(hProv, 0); CryptDestroyHash(hHash); CloseHandle(hFile); return ""; } cbHash = MD5LEN; char* rc = ""; if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { size_t size; rc = base64_encode((const unsigned char*)rgbHash, cbHash, &size); } CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); CloseHandle(hFile); string s = string(rc); delete rc; return s; }
void CHasher::Shutdown(){ #if _WIN32 CryptReleaseContext(m_cryptProv, 0); CryptDestroyHash(m_cryptHash); #endif }
void CWE328_Reversible_One_Way_Hash__w32_MD2_15_bad() { switch(6) { case 6: { HCRYPTPROV hCryptProv; HCRYPTHASH hHash; FILE *pFile = NULL; char password[PASSWORD_INPUT_SIZE]; UCHAR savedHash[MD2_SUM_SIZE], calcHash[MD2_SUM_SIZE]; DWORD hashSize; char *replace; size_t i; pFile = fopen("password.txt", "r"); if (pFile == NULL) { exit(1); } for (i = 0; i < MD2_SUM_SIZE; i++) { ULONG val; if (fscanf(pFile, "%02x", &val) != 1) { fclose(pFile); exit(1); } if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */ { fclose(pFile); exit(1); } savedHash[i] = (UCHAR)val; } if (pFile) { fclose(pFile); } if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL) { exit(1); } replace = strchr(password, '\r'); if (replace) { *replace = '\0'; } replace = strchr(password, '\n'); if (replace) { *replace = '\0'; } if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0)) { exit(1); } /* FLAW: Use a reversible hash (MD2) */ if (!CryptCreateHash(hCryptProv, CALG_MD2, 0, 0, &hHash)) { CryptReleaseContext(hCryptProv, 0); exit(1); } /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags, * the password hash was not securely transmitted (via one form or another), * that may raise flags */ if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } hashSize = MD2_SUM_SIZE; if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0)) { CryptDestroyHash(hHash); CryptReleaseContext(hCryptProv, 0); exit(1); } if (memcmp(savedHash, calcHash, MD2_SUM_SIZE * sizeof(UCHAR)) == 0) { printLine("Access granted"); } else { printLine("Access denied"); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } break; default: /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); break; } }
/* * Requires "ent" be locked. */ static void destroyfilesource(isc_entropyfilesource_t *source) { CryptReleaseContext(source->handle, 0); }
/* * Do not use Windows tmpfile() function. * It will make a temporary file under the root directory * and it'll cause permission error if a user who is * non-Administrator creates temporary files. * Also Windows version of mktemp family including _mktemp_s * are not secure. */ int __archive_mktemp(const char *tmpdir) { static const wchar_t *prefix = L"libarchive_"; static const wchar_t *suffix = L"XXXXXXXXXX"; static const wchar_t num[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7', L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F', L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N', L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V', L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd', L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l', L'm', L'n', L'o', L'p', L'q', L'r', L's', L't', L'u', L'v', L'w', L'x', L'y', L'z' }; HCRYPTPROV hProv; struct archive_wstring temp_name; wchar_t *ws; DWORD attr; wchar_t *xp, *ep; int fd; hProv = (HCRYPTPROV)NULL; fd = -1; ws = NULL; archive_string_init(&temp_name); /* Get a temporary directory. */ if (tmpdir == NULL) { size_t l; wchar_t *tmp; l = GetTempPathW(0, NULL); if (l == 0) { la_dosmaperr(GetLastError()); goto exit_tmpfile; } tmp = malloc(l*sizeof(wchar_t)); if (tmp == NULL) { errno = ENOMEM; goto exit_tmpfile; } GetTempPathW((DWORD)l, tmp); archive_wstrcpy(&temp_name, tmp); free(tmp); } else { if (archive_wstring_append_from_mbs(&temp_name, tmpdir, strlen(tmpdir)) < 0) goto exit_tmpfile; if (temp_name.s[temp_name.length-1] != L'/') archive_wstrappend_wchar(&temp_name, L'/'); } /* Check if temp_name is a directory. */ attr = GetFileAttributesW(temp_name.s); if (attr == (DWORD)-1) { if (GetLastError() != ERROR_FILE_NOT_FOUND) { la_dosmaperr(GetLastError()); goto exit_tmpfile; } ws = __la_win_permissive_name_w(temp_name.s); if (ws == NULL) { errno = EINVAL; goto exit_tmpfile; } attr = GetFileAttributesW(ws); if (attr == (DWORD)-1) { la_dosmaperr(GetLastError()); goto exit_tmpfile; } } if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) { errno = ENOTDIR; goto exit_tmpfile; } /* * Create a temporary file. */ archive_wstrcat(&temp_name, prefix); archive_wstrcat(&temp_name, suffix); ep = temp_name.s + archive_strlen(&temp_name); xp = ep - wcslen(suffix); if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { la_dosmaperr(GetLastError()); goto exit_tmpfile; } for (;;) { wchar_t *p; HANDLE h; /* Generate a random file name through CryptGenRandom(). */ p = xp; if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t), (BYTE*)p)) { la_dosmaperr(GetLastError()); goto exit_tmpfile; } for (; p < ep; p++) *p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))]; free(ws); ws = __la_win_permissive_name_w(temp_name.s); if (ws == NULL) { errno = EINVAL; goto exit_tmpfile; } /* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to * delete this temporary file immediately when this * file closed. */ h = CreateFileW(ws, GENERIC_READ | GENERIC_WRITE | DELETE, 0,/* Not share */ NULL, CREATE_NEW,/* Create a new file only */ FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL); if (h == INVALID_HANDLE_VALUE) { /* The same file already exists. retry with * a new filename. */ if (GetLastError() == ERROR_FILE_EXISTS) continue; /* Otherwise, fail creation temporary file. */ la_dosmaperr(GetLastError()); goto exit_tmpfile; } fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR); if (fd == -1) { CloseHandle(h); goto exit_tmpfile; } else break;/* success! */ } exit_tmpfile: if (hProv != (HCRYPTPROV)NULL) CryptReleaseContext(hProv, 0); free(ws); archive_wstring_free(&temp_name); return (fd); }
int RAND_poll(void) { MEMORYSTATUS m; HCRYPTPROV hProvider = 0; DWORD w; int good = 0; /* Determine the OS version we are on so we can turn off things * that do not work properly. */ OSVERSIONINFO osverinfo ; osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ; GetVersionEx( &osverinfo ) ; #if defined(OPENSSL_SYS_WINCE) # if defined(_WIN32_WCE) && _WIN32_WCE>=300 /* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available * in commonly available implementations prior 300... */ { BYTE buf[64]; /* poll the CryptoAPI PRNG */ /* The CryptoAPI returns sizeof(buf) bytes of randomness */ if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (CryptGenRandom(hProvider, sizeof(buf), buf)) RAND_add(buf, sizeof(buf), sizeof(buf)); CryptReleaseContext(hProvider, 0); } } # endif #else /* OPENSSL_SYS_WINCE */ /* * None of below libraries are present on Windows CE, which is * why we #ifndef the whole section. This also excuses us from * handling the GetProcAddress issue. The trouble is that in * real Win32 API GetProcAddress is available in ANSI flavor * only. In WinCE on the other hand GetProcAddress is a macro * most commonly defined as GetProcAddressW, which accepts * Unicode argument. If we were to call GetProcAddress under * WinCE, I'd recommend to either redefine GetProcAddress as * GetProcAddressA (there seem to be one in common CE spec) or * implement own shim routine, which would accept ANSI argument * and expand it to Unicode. */ { /* load functions dynamically - not available on all systems */ HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL")); HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL")); HMODULE user = NULL; HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL")); CRYPTACQUIRECONTEXTW acquire = NULL; CRYPTGENRANDOM gen = NULL; CRYPTRELEASECONTEXT release = NULL; NETSTATGET netstatget = NULL; NETFREE netfree = NULL; BYTE buf[64]; if (netapi) { netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet"); netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree"); } if (netstatget && netfree) { LPBYTE outbuf; /* NetStatisticsGet() is a Unicode only function * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0 * contains 17 fields. We treat each field as a source of * one byte of entropy. */ if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) { RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45); netfree(outbuf); } if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) { RAND_add(outbuf, sizeof(STAT_SERVER_0), 17); netfree(outbuf); } } if (netapi) FreeLibrary(netapi); /* It appears like this can cause an exception deep within ADVAPI32.DLL * at random times on Windows 2000. Reported by Jeffrey Altman. * Only use it on NT. */ /* Wolfgang Marczy <*****@*****.**> reports that * the RegQueryValueEx call below can hang on NT4.0 (SP6). * So we don't use this at all for now. */ #if 0 if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && osverinfo.dwMajorVersion < 5) { /* Read Performance Statistics from NT/2000 registry * The size of the performance data can vary from call * to call so we must guess the size of the buffer to use * and increase its size if we get an ERROR_MORE_DATA * return instead of ERROR_SUCCESS. */ LONG rc=ERROR_MORE_DATA; char * buf=NULL; DWORD bufsz=0; DWORD length; while (rc == ERROR_MORE_DATA) { buf = realloc(buf,bufsz+8192); if (!buf) break; bufsz += 8192; length = bufsz; rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"), NULL, NULL, buf, &length); } if (rc == ERROR_SUCCESS) { /* For entropy count assume only least significant * byte of each DWORD is random. */ RAND_add(&length, sizeof(length), 0); RAND_add(buf, length, length / 4.0); /* Close the Registry Key to allow Windows to cleanup/close * the open handle * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened * when the RegQueryValueEx above is done. However, if * it is not explicitly closed, it can cause disk * partition manipulation problems. */ RegCloseKey(HKEY_PERFORMANCE_DATA); } if (buf) free(buf); } #endif if (advapi) { /* * If it's available, then it's available in both ANSI * and UNICODE flavors even in Win9x, documentation says. * We favor Unicode... */ acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi, "CryptAcquireContextW"); gen = (CRYPTGENRANDOM) GetProcAddress(advapi, "CryptGenRandom"); release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi, "CryptReleaseContext"); } if (acquire && gen && release) { /* poll the CryptoAPI PRNG */ /* The CryptoAPI returns sizeof(buf) bytes of randomness */ if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { if (gen(hProvider, sizeof(buf), buf) != 0) { RAND_add(buf, sizeof(buf), 0); good = 1; #if 0 printf("randomness from PROV_RSA_FULL\n"); #endif } release(hProvider, 0); } /* poll the Pentium PRG with CryptoAPI */ if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0)) { if (gen(hProvider, sizeof(buf), buf) != 0) { RAND_add(buf, sizeof(buf), sizeof(buf)); good = 1; #if 0 printf("randomness from PROV_INTEL_SEC\n"); #endif } release(hProvider, 0); } } if (advapi) FreeLibrary(advapi); if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT || !OPENSSL_isservice()) && (user = LoadLibrary(TEXT("USER32.DLL")))) { GETCURSORINFO cursor; GETFOREGROUNDWINDOW win; GETQUEUESTATUS queue; win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow"); cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo"); queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus"); if (win) { /* window handle */ HWND h = win(); RAND_add(&h, sizeof(h), 0); } if (cursor) { /* unfortunately, its not safe to call GetCursorInfo() * on NT4 even though it exists in SP3 (or SP6) and * higher. */ if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT && osverinfo.dwMajorVersion < 5) cursor = 0; } if (cursor) { /* cursor position */ /* assume 2 bytes of entropy */ CURSORINFO ci; ci.cbSize = sizeof(CURSORINFO); if (cursor(&ci)) RAND_add(&ci, ci.cbSize, 2); } if (queue) { /* message queue status */ /* assume 1 byte of entropy */ w = queue(QS_ALLEVENTS); RAND_add(&w, sizeof(w), 1); } FreeLibrary(user); } /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm * (Win 9x and 2000 only, not available on NT) * * This seeding method was proposed in Peter Gutmann, Software * Generation of Practically Strong Random Numbers, * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html * revised version at http://www.cryptoengines.com/~peter/06_random.pdf * (The assignment of entropy estimates below is arbitrary, but based * on Peter's analysis the full poll appears to be safe. Additional * interactive seeding is encouraged.) */ if (kernel) { CREATETOOLHELP32SNAPSHOT snap; CLOSETOOLHELP32SNAPSHOT close_snap; HANDLE handle; HEAP32FIRST heap_first; HEAP32NEXT heap_next; HEAP32LIST heaplist_first, heaplist_next; PROCESS32 process_first, process_next; THREAD32 thread_first, thread_next; MODULE32 module_first, module_next; HEAPLIST32 hlist; HEAPENTRY32 hentry; PROCESSENTRY32 p; THREADENTRY32 t; MODULEENTRY32 m; DWORD starttime = 0; snap = (CREATETOOLHELP32SNAPSHOT) GetProcAddress(kernel, "CreateToolhelp32Snapshot"); close_snap = (CLOSETOOLHELP32SNAPSHOT) GetProcAddress(kernel, "CloseToolhelp32Snapshot"); heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); process_first = (PROCESS32) GetProcAddress(kernel, "Process32First"); process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next"); thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); if (snap && heap_first && heap_next && heaplist_first && heaplist_next && process_first && process_next && thread_first && thread_next && module_first && module_next && (handle = snap(TH32CS_SNAPALL,0)) != INVALID_HANDLE_VALUE) { /* heap list and heap walking */ /* HEAPLIST32 contains 3 fields that will change with * each entry. Consider each field a source of 1 byte * of entropy. * HEAPENTRY32 contains 5 fields that will change with * each entry. Consider each field a source of 1 byte * of entropy. */ ZeroMemory(&hlist, sizeof(HEAPLIST32)); hlist.dwSize = sizeof(HEAPLIST32); if (good) starttime = GetTickCount(); #ifdef _MSC_VER if (heaplist_first(handle, &hlist)) { /* following discussion on dev ML, exception on WinCE (or other Win platform) is theoretically of unknown origin; prevent infinite loop here when this theoretical case occurs; otherwise cope with the expected (MSDN documented) exception-throwing behaviour of Heap32Next() on WinCE. based on patch in original message by Tanguy Fautré (2009/03/02) Subject: RAND_poll() and CreateToolhelp32Snapshot() stability */ int ex_cnt_limit = 42; do { RAND_add(&hlist, hlist.dwSize, 3); __try { ZeroMemory(&hentry, sizeof(HEAPENTRY32)); hentry.dwSize = sizeof(HEAPENTRY32); if (heap_first(&hentry, hlist.th32ProcessID, hlist.th32HeapID)) { int entrycnt = 80; do RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) && (!good || (GetTickCount()-starttime)<MAXDELAY) && --entrycnt > 0); } } __except (EXCEPTION_EXECUTE_HANDLER) { /* ignore access violations when walking the heap list */ ex_cnt_limit--; } } while (heaplist_next(handle, &hlist) && (!good || (GetTickCount()-starttime)<MAXDELAY) && ex_cnt_limit > 0); } #else if (heaplist_first(handle, &hlist)) { do { RAND_add(&hlist, hlist.dwSize, 3); hentry.dwSize = sizeof(HEAPENTRY32); if (heap_first(&hentry, hlist.th32ProcessID, hlist.th32HeapID)) { int entrycnt = 80; do RAND_add(&hentry, hentry.dwSize, 5); while (heap_next(&hentry) && --entrycnt > 0); } } while (heaplist_next(handle, &hlist) && (!good || (GetTickCount()-starttime)<MAXDELAY)); } #endif /* process walking */ /* PROCESSENTRY32 contains 9 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ p.dwSize = sizeof(PROCESSENTRY32); if (good) starttime = GetTickCount(); if (process_first(handle, &p)) do RAND_add(&p, p.dwSize, 9); while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY)); /* thread walking */ /* THREADENTRY32 contains 6 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ t.dwSize = sizeof(THREADENTRY32); if (good) starttime = GetTickCount(); if (thread_first(handle, &t)) do RAND_add(&t, t.dwSize, 6); while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY)); /* module walking */ /* MODULEENTRY32 contains 9 fields that will change * with each entry. Consider each field a source of * 1 byte of entropy. */ m.dwSize = sizeof(MODULEENTRY32); if (good) starttime = GetTickCount(); if (module_first(handle, &m)) do RAND_add(&m, m.dwSize, 9); while (module_next(handle, &m) && (!good || (GetTickCount()-starttime)<MAXDELAY)); if (close_snap) close_snap(handle); else CloseHandle(handle); } FreeLibrary(kernel); }