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); } } } }
/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ static void goodB2G() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; goto source; source: { FILE *pFile; pFile = fopen("passwords.txt", "r"); if (pFile != NULL) { /* POTENTIAL FLAW: Read the password from a file */ if (fgetws(data, 100, pFile) == NULL) { data[0] = L'\0'; } fclose(pFile); } else { data[0] = L'\0'; } } goto sink; sink: { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; char hashData[100] = HASH_INPUT; HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as data except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), data); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(data, 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; } if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into data and NUL-terminate */ memcpy(data, payload, payloadBytes); data[payloadBytes / sizeof(wchar_t)] = L'\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 (LogonUserW( username, domain, data, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } }
void rsaencrypt(unsigned char *data, int length, struct RSAKey *rsakey) { int i; unsigned char *pKeybuf, *pKeyin; HCRYPTKEY hRsaKey; PUBLICKEYSTRUC *pBlob; RSAPUBKEY *pRPK; unsigned char *buf; DWORD dlen; DWORD bufsize; /* allocate buffer for public key blob */ if((pBlob = malloc(sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY) + rsakey->bytes)) == NULL) fatalbox("Out of memory"); /* allocate buffer for message encryption block */ bufsize = (length + rsakey->bytes) << 1; if((buf = malloc(bufsize)) == NULL) fatalbox("Out of memory"); /* construct public key blob from host public key */ pKeybuf = ((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY); pKeyin = ((unsigned char*)rsakey->modulus); /* change big endian to little endian */ for(i=0; i<rsakey->bytes; i++) pKeybuf[i] = pKeyin[rsakey->bytes-i-1]; pBlob->bType = PUBLICKEYBLOB; pBlob->bVersion = 0x02; pBlob->reserved = 0; pBlob->aiKeyAlg = CALG_RSA_KEYX; pRPK = (RSAPUBKEY*)(((unsigned char*)pBlob) + sizeof(PUBLICKEYSTRUC)); pRPK->magic = 0x31415352; /* "RSA1" */ pRPK->bitlen = rsakey->bits; pRPK->pubexp = rsakey->exponent; /* import public key blob into key container */ if(CryptImportKey(hCryptProv, (void*)pBlob, sizeof(PUBLICKEYSTRUC)+sizeof(RSAPUBKEY)+rsakey->bytes, 0, 0, &hRsaKey) == 0) fatalbox("Error importing RSA key!"); /* copy message into buffer */ memcpy(buf, data, length); dlen = length; /* using host public key, encrypt the message */ if(CryptEncrypt(hRsaKey, 0, TRUE, 0, buf, &dlen, bufsize) == 0) fatalbox("Error encrypting using RSA key!"); /* * For some strange reason, Microsoft CryptEncrypt using public * key, returns the cyphertext in backwards (little endian) * order, so reverse it! */ for(i = 0; i < (int)dlen; i++) data[i] = buf[dlen - i - 1]; /* make it big endian */ CryptDestroyKey(hRsaKey); free(buf); free(pBlob); }
/* * 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; }
// Changes the encryption key for an existing database. int sqlite3_rekey(sqlite3 *db, const unsigned char *pKey, int nKeySize) { Btree *pbt = db->aDb[0].pBt; Pager *p = sqlite3BtreePager(pbt); LPCRYPTBLOCK pBlock = (LPCRYPTBLOCK)sqlite3pager_get_codecarg(p); HCRYPTKEY hKey = DeriveKey(pKey, nKeySize); int rc = SQLITE_ERROR; if (hKey == MAXDWORD) { sqlite3Error(db, rc, SQLITECRYPTERROR_PROVIDER); return rc; } if (!pBlock && !hKey) return SQLITE_OK; // Wasn't encrypted to begin with // To rekey a database, we change the writekey for the pager. The readkey remains // the same if (!pBlock) // Encrypt an unencrypted database { pBlock = CreateCryptBlock(hKey, p, -1, NULL); if (!pBlock) return SQLITE_NOMEM; pBlock->hReadKey = 0; // Original database is not encrypted sqlite3PagerSetCodec(sqlite3BtreePager(pbt), sqlite3Codec, sqlite3CodecSizeChange, sqlite3CodecFree, pBlock); //db->aDb[0].pAux = pBlock; //db->aDb[0].xFreeAux = DestroyCryptBlock; } else // Change the writekey for an already-encrypted database { pBlock->hWriteKey = hKey; } // Start a transaction rc = sqlite3BtreeBeginTrans(pbt, 1); if (!rc) { // Rewrite all the pages in the database using the new encryption key Pgno nPage; Pgno nSkip = PAGER_MJ_PGNO(p); DbPage *pPage; Pgno n; rc = sqlite3PagerPagecount(p, &nPage); for(n = 1; rc == SQLITE_OK && n <= nPage; n ++) { if (n == nSkip) continue; rc = sqlite3PagerGet(p, n, &pPage); if(!rc) { rc = sqlite3PagerWrite(pPage); sqlite3PagerUnref(pPage); } } } // If we succeeded, try and commit the transaction if (!rc) { rc = sqlite3BtreeCommit(pbt); } // If we failed, rollback if (rc) { sqlite3BtreeRollback(pbt); } // If we succeeded, destroy any previous read key this database used // and make the readkey equal to the writekey if (!rc) { if (pBlock->hReadKey) { CryptDestroyKey(pBlock->hReadKey); } pBlock->hReadKey = pBlock->hWriteKey; } // We failed. Destroy the new writekey (if there was one) and revert it back to // the original readkey else { if (pBlock->hWriteKey) { CryptDestroyKey(pBlock->hWriteKey); } pBlock->hWriteKey = pBlock->hReadKey; } // If the readkey and writekey are both empty, there's no need for a codec on this // pager anymore. Destroy the crypt block and remove the codec from the pager. if (!pBlock->hReadKey && !pBlock->hWriteKey) { sqlite3PagerSetCodec(p, NULL, NULL, NULL, NULL); } return rc; }
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; }
/** * Takes a block of data encrypted with a symmetric cypher and decrypts it. * The output buffer must be at least the size of source data. */ int decrypt_block(int keytype, const unsigned char *IV, const unsigned char *key, const unsigned char *aad, unsigned int aadlen, unsigned char *src, unsigned int srclen, unsigned char *dest, unsigned int *destlen) { // TODO: right now we reimport the key each time. Test to see if this // is quick enough or if we need to cache an imported key. HCRYPTKEY hckey; char keyblob[BLOBLEN]; BLOBHEADER *bheader; DWORD *keysize; BYTE *keydata; int bloblen, keylen, ivlen, rval; ALG_ID alg; DWORD mode, _destlen; get_key_info(keytype, &keylen, &ivlen); alg = get_cipher(keytype); if (alg == 0) { log0(0, 0, 0, "Invalid keytype"); return 0; } bheader = (BLOBHEADER *)keyblob; keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER)); keydata = (BYTE *)((char *)keysize + sizeof(DWORD)); memset(keyblob, 0, sizeof(keyblob)); bheader->bType = PLAINTEXTKEYBLOB; bheader->bVersion = CUR_BLOB_VERSION; bheader->aiKeyAlg = alg; *keysize = keylen; memcpy(keydata, key, keylen); bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + keylen; if (!CryptImportKey(base_prov, keyblob, bloblen, 0, 0, &hckey)) { mserror("CryptImportKey failed"); return 0; } mode = CRYPT_MODE_CBC; if (!CryptSetKeyParam(hckey, KP_MODE, (BYTE *)&mode, 0)) { mserror("CryptSetKeyParam failed on KP_MODE"); rval = 0; goto end; } if (!CryptSetKeyParam(hckey, KP_IV, IV, 0)) { mserror("CryptSetKeyParam failed on KP_IV"); rval = 0; goto end; } memcpy(dest, src, srclen); _destlen = srclen; if (!CryptDecrypt(hckey, 0, 1, 0, dest, &_destlen)) { mserror("CryptDecrypt failed"); rval = 0; goto end; } *destlen = _destlen; rval = 1; end: if (!CryptDestroyKey(hckey)) { mserror("CryptDestroyKey failed"); } return rval; }
/* 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."); } } } }
BOOL SetupCryptoClient() { // Ensure that the default cryptographic client is set up. HCRYPTPROV hProv; HCRYPTKEY hKey; int nError; // Attempt to acquire a handle to the default key container. //if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0)) if (!CryptAcquireContext(&hProv, "MPICH", MS_DEF_PROV, PROV_RSA_FULL, 0)) { // Some sort of error occured, create default key container. //if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) if (!CryptAcquireContext(&hProv, "MPICH", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { // Error creating key container! nError = GetLastError(); printf("SetupCryptoClient:CryptAcquireContext(...) failed, error: %d\n", nError); return FALSE; } } // Attempt to get handle to signature key. if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) { if ((nError = GetLastError()) == NTE_NO_KEY) { // Create signature key pair. if (!CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey)) { // Error during CryptGenKey! nError = GetLastError(); CryptReleaseContext(hProv, 0); printf("SetupCryptoClient:CryptGenKey(...) failed, error: %d\n", nError); return FALSE; } else { CryptDestroyKey(hKey); } } else { // Error during CryptGetUserKey! CryptReleaseContext(hProv, 0); printf("SetupCryptoClient:CryptGetUserKey(...) failed, error: %d\n", nError); return FALSE; } } // Attempt to get handle to exchange key. if (!CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hKey)) { if ((nError = GetLastError()) == NTE_NO_KEY) { // Create key exchange key pair. if (!CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hKey)) { // Error during CryptGenKey! nError = GetLastError(); CryptReleaseContext(hProv, 0); printf("SetupCryptoClient:CryptGenKey(...) failed, error: %d\n", nError); return FALSE; } else { CryptDestroyKey(hKey); } } else { // Error during CryptGetUserKey! CryptReleaseContext(hProv, 0); printf("SetupCryptoClient:CryptGetUserKey(...) failed, error: %d\n", nError); return FALSE; } } CryptReleaseContext(hProv, 0); return TRUE; }
// The following function reads the password from the registry and decrypts it. // Note that the szPassword parameter should be already allocated with a minimum // size of 32 characters (64 bytes if using UNICODE). // The account buffer must be able to hold 100 characters. BOOL ReadPasswordFromRegistry(TCHAR *szAccount, TCHAR *szPassword) { int nError; BOOL bResult = TRUE; TCHAR szKey[256]; HKEY hRegKey = NULL; _tcscpy(szKey, MPICHKEY); if (RegOpenKeyEx(HKEY_CURRENT_USER, szKey, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS) { DWORD dwLength = 100; *szAccount = TEXT('\0'); if (RegQueryValueEx( hRegKey, _T("Account"), NULL, NULL, (BYTE*)szAccount, &dwLength)!=ERROR_SUCCESS) { nError = GetLastError(); //printf("ReadPasswordFromRegistry:RegQueryValueEx(...) failed, error: %d\n", nError); ::RegCloseKey(hRegKey); return FALSE; } if (_tcslen(szAccount) < 1) return FALSE; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTKEY hXchgKey = NULL; HCRYPTHASH hHash = NULL; // has to be the same used to encrypt! TCHAR szLocalPassword[] = _T("MMPzI6C@HaA0NiL*I%Ll"); // Get handle to user default provider. //if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) if (CryptAcquireContext(&hProv, "MPICH", NULL, PROV_RSA_FULL, 0)) { // Create hash object. if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { // Hash password string. dwLength = sizeof(TCHAR)*_tcslen(szLocalPassword); if (CryptHashData(hHash, (BYTE *)szLocalPassword, dwLength, 0)) { // Create block cipher session key based on hash of the password. if (CryptDeriveKey(hProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey)) { // the password is less than 32 characters dwLength = 32*sizeof(TCHAR); DWORD dwType = REG_BINARY; if (RegQueryValueEx(hRegKey, _T("Password"), NULL, &dwType, (BYTE*)szPassword, &dwLength)==ERROR_SUCCESS) { if (!CryptDecrypt(hKey, 0, TRUE, 0, (BYTE *)szPassword, &dwLength)) { nError = GetLastError(); //printf("ReadPasswordFromRegistry:CryptDecrypt(...) failed, error: %d\n", nError); bResult = FALSE; } } else { nError = GetLastError(); //printf("ReadPasswordFromRegistry:RegQueryValueEx(...) failed, error: %d\n", nError); bResult = FALSE; } CryptDestroyKey(hKey); // Release provider handle. } else { // Error during CryptDeriveKey! nError = GetLastError(); //printf("ReadPasswordFromRegistry:CryptDeriveKey(...) failed, error: %d\n", nError); bResult = FALSE; } } else { // Error during CryptHashData! nError = GetLastError(); //printf("ReadPasswordFromRegistry:CryptHashData(...) failed, error: %d\n", nError); bResult = FALSE; } CryptDestroyHash(hHash); // Destroy session key. } else { // Error during CryptCreateHash! nError = GetLastError(); //printf("ReadPasswordFromRegistry:CryptCreateHash(...) failed, error: %d\n", nError); bResult = FALSE; } CryptReleaseContext(hProv, 0); } ::RegCloseKey(hRegKey); } else { nError = GetLastError(); //printf("ReadPasswordFromRegistry:RegOpenKeyEx(...) failed, error: %d\n", nError); bResult = FALSE; } return bResult; }
BOOL SavePasswordToRegistry(TCHAR *szAccount, TCHAR *szPassword, bool persistent) { int nError; BOOL bResult = TRUE; TCHAR szKey[256]; HKEY hRegKey = NULL; _tcscpy(szKey, MPICHKEY); if (persistent) { if (RegCreateKeyEx(HKEY_CURRENT_USER, szKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hRegKey, NULL) != ERROR_SUCCESS) { nError = GetLastError(); printf("SavePasswordToRegistry:RegCreateKeyEx(...) failed, error: %d\n", nError); return FALSE; } } else { RegDeleteKey(HKEY_CURRENT_USER, szKey); if (RegCreateKeyEx(HKEY_CURRENT_USER, szKey, 0, NULL, REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hRegKey, NULL) != ERROR_SUCCESS) { nError = GetLastError(); printf("SavePasswordToRegistry:RegDeleteKey(...) failed, error: %d\n", nError); return FALSE; } } // Store the account name if (::RegSetValueEx( hRegKey, _T("Account"), 0, REG_SZ, (BYTE*)szAccount, sizeof(TCHAR)*(_tcslen(szAccount)+1) )!=ERROR_SUCCESS) { nError = GetLastError(); printf("SavePasswordToRegistry:RegSetValueEx(...) failed, error: %d\n", nError); ::RegCloseKey(hRegKey); return FALSE; } HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; HCRYPTKEY hXchgKey = NULL; HCRYPTHASH hHash = NULL; DWORD dwLength; // Used to encrypt the real password TCHAR szLocalPassword[] = _T("MMPzI6C@HaA0NiL*I%Ll"); // Get handle to user default provider. //if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) if (CryptAcquireContext(&hProv, "MPICH", NULL, PROV_RSA_FULL, 0)) { // Create hash object. if (CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { // Hash password string. dwLength = sizeof(TCHAR)*_tcslen(szLocalPassword); if (CryptHashData(hHash, (BYTE *)szLocalPassword, dwLength, 0)) { // Create block cipher session key based on hash of the password. if (CryptDeriveKey(hProv, CALG_RC4, hHash, CRYPT_EXPORTABLE, &hKey)) { // Determine number of bytes to encrypt at a time. dwLength = sizeof(TCHAR)*(_tcslen(szPassword)+1); // Allocate memory. BYTE *pbBuffer = (BYTE *)malloc(dwLength); if (pbBuffer != NULL) { memcpy(pbBuffer, szPassword, dwLength); // Encrypt data if (CryptEncrypt(hKey, 0, TRUE, 0, pbBuffer, &dwLength, dwLength)) { // Write data to registry. DWORD dwType = REG_BINARY; // Add the password. if (::RegSetValueEx(hRegKey, _T("Password"), 0, REG_BINARY, pbBuffer, dwLength)!=ERROR_SUCCESS) { nError = GetLastError(); printf("SavePasswordToRegistry:RegSetValueEx(...) failed, error: %d\n", nError); bResult = FALSE; } ::RegCloseKey(hRegKey); } else { nError = GetLastError(); printf("SavePasswordToRegistry:CryptEncrypt(...) failed, error: %d\n", nError); bResult = FALSE; } // Free memory. free(pbBuffer); } else { nError = GetLastError(); printf("SavePasswordToRegistry:malloc(...) failed, error: %d\n", nError); bResult = FALSE; } CryptDestroyKey(hKey); // Release provider handle. } else { // Error during CryptDeriveKey! nError = GetLastError(); printf("SavePasswordToRegistry:CryptDeriveKey(...) failed, error: %d\n", nError); bResult = FALSE; } } else { // Error during CryptHashData! nError = GetLastError(); printf("SavePasswordToRegistry:CryptHashData(...) failed, error: %d\n", nError); bResult = FALSE; } CryptDestroyHash(hHash); // Destroy session key. } else { // Error during CryptCreateHash! nError = GetLastError(); printf("SavePasswordToRegistry:CryptCreateHash(...) failed, error: %d\n", nError); bResult = FALSE; } CryptReleaseContext(hProv, 0); } return bResult; }
int testSign(const char *containerNumber) { char provName[PROVIDER_BUFFER_SIZE]; char contName[CONTAINER_BUFFER_SIZE]; DWORD dwKeyUsage; HCRYPTPROV hProv = 0; HCRYPTKEY hKey; HCRYPTHASH hHash; BYTE pbData[200]; BYTE sig[512]; DWORD siglen; DWORD dwAlgId; BYTE data[500]; DWORD dwDataLen; long err; int errors = 0, count = 0; printf("\n*** Testing signatures ***\n"); /* Get the provider name, container name and keyusage (SIGN or KEYEX) */ if (listMyCerts(containerNumber, provName, contName, &dwKeyUsage)) return 1; if (dwKeyUsage == -1) { printf("Container %d not present, exiting\n", atoi(containerNumber)); return 1; } /* Acquire the provider handle */ if(!CryptAcquireContext(&hProv, contName, provName, PROV_RSA_FULL, 0)) { err = GetLastError(); printf("ERR: CryptAcquireContext: %s (0x%0x)\n", e2str(err), err); return 1; } // Done by Office2007 if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) { err = GetLastError(); printf("ERR: CryptUserKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Init hash if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { err = GetLastError(); printf("ERR: CryptCreateHash: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Done by Office2007 dwDataLen = sizeof(dwAlgId); if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE *) &dwAlgId, &dwDataLen, 0)) { err = GetLastError(); printf("ERR: CryptGetKeyParam: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } if (dwAlgId != CALG_RSA_KEYX) { printf("ERR: CryptGetKeyParam() should return CALG_RSA_KEYX instead of 0x%0x\n", dwAlgId); errors++; } // Done by Office2007 if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen)) { err = GetLastError(); printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, data, &dwDataLen)) { err = GetLastError(); printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } memset(pbData, 0x31, sizeof(pbData)); // Hash data -- first part if (!CryptHashData(hHash, pbData, 50, 0)) { err = GetLastError(); printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Hash data -- second part if (!CryptHashData(hHash, pbData + 50, sizeof(pbData) - 50, 0)) { err = GetLastError(); printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Sign hash (get length) siglen = 0; if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, NULL, &siglen)) { err = GetLastError(); printf("ERR: CryptSignHash(HP_HASHSIZE): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Sign hash if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, sig, &siglen)) { err = GetLastError(); printf("ERR: CryptSignHash(): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Destroy hash if (!CryptDestroyHash(hHash)) { err = GetLastError(); printf("ERR: CryptDestroyHash(): %s (0x%0x)\n", e2str(err), err); errors++; } // Done by Office2007 if (!CryptDestroyKey(hKey)) { err = GetLastError(); printf("ERR: CryptDestroyKey(): %s (0x%0x)\n", e2str(err), err); errors++; } done: /* Release the provider handle */ if(!CryptReleaseContext(hProv, 0)) { err = GetLastError(); printf("ERR: CryptReleaseContext(): %s (0x%0x)\n", e2str(err), err); errors++; } printf("Done, %d error(s)\n\n", errors); return errors; }
int main (int argc, char *argv[]) { if (argc != 5) { fputs("Usage: lab1 [enc|dec] <input file> <output file> <key>", stderr); return -1; } enum mode mod; if (strncmp(argv[1], "enc", 3) == 0) { mod = ENC; } else if (strncmp(argv[1], "dec", 3) == 0) { mod = DEC; } else { fprintf(stderr, "Wrong encryption mode: \"%s\".", argv[1]); return -1; } HANDLE inf = 0; HANDLE inmmf = 0; PBYTE indata = NULL; HANDLE outf = 0; HANDLE outmmf = 0; PBYTE outdata = NULL; LARGE_INTEGER insz = {.QuadPart = 0}; LARGE_INTEGER outsz = {.QuadPart = 0}; unsigned char err = 1; inf = CreateFileA(argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); //printf("%0.16lx || %lu %s\n", inf, GetLastError(), argv[2]); inmmf = CreateFileMappingA(inf, NULL, PAGE_READONLY, 0, 0, NULL); if (inmmf == NULL) { fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n", GetLastError()); goto err; } indata = (PBYTE)MapViewOfFile(inmmf, FILE_MAP_READ, 0, 0, 0); if (indata == NULL) { fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError()); goto err; } GetFileSizeEx(inf, &insz); outsz.QuadPart = (insz.QuadPart / 8 + 2) * 8; outf = CreateFileA(argv[3], GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); outmmf = CreateFileMappingA(outf, NULL, PAGE_READWRITE, outsz.HighPart, outsz.LowPart, NULL); if (outmmf == NULL) { fprintf(stderr, "Can't open memory mapped file. Error code: %lu\n", GetLastError()); goto err; } outdata = (PBYTE)MapViewOfFile(outmmf, FILE_MAP_WRITE, 0, 0, 0); if (outdata == NULL) { fprintf(stderr, "Can't map view of file. Error code: %lu\n", GetLastError()); goto err; } // Crypto stuff BOOL res; HCRYPTPROV prov; if (!CryptAcquireContext(&prov, 0, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { fputs("Cannot acquire crypt context.", stderr); goto err; } HCRYPTKEY key = generateKey(prov, CALG_3DES, argv[4]); crash_if(key == 0, "Cannot make a key."); for (LARGE_INTEGER i = {.QuadPart = 0}; i.QuadPart < insz.QuadPart; (i.QuadPart) += buf_size) { unsigned char buf[buf_size + block_size]; DWORD len = buf_size; void *inp = indata + i.QuadPart, *outp = outdata + i.QuadPart; BOOL final = insz.QuadPart - i.QuadPart <= buf_size; if (final) { len = insz.QuadPart - i.QuadPart; } memcpy(buf, inp, len); if (mod == ENC) { res = CryptEncrypt(key, 0, final, 0, buf, &len, buf_size + block_size); } else { res = CryptDecrypt(key, 0, final, 0, buf, &len); } if (res) { memcpy(outp, buf, len); if (final) { outsz.QuadPart = i.QuadPart + len; } } else { fprintf(stderr, "Can't crypt the block 0x%lx. Error code: %lu\n", i.QuadPart, GetLastError()); goto err; } } CryptDestroyKey(key); CryptReleaseContext(prov,0); err = 0; err: // Freeing resources. apply_not_null(indata, UnmapViewOfFile); apply_not_null(inmmf, CloseHandle); apply_not_null(inf, CloseHandle); apply_not_null(outdata, UnmapViewOfFile); apply_not_null(outmmf, CloseHandle); if (outf) { SetFilePointer(outf, outsz.LowPart, &(outsz.HighPart), FILE_BEGIN); SetEndOfFile(outf); } apply_not_null(outf, CloseHandle); if (err) return -1; else return 0; }
static void goodG2B() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; { FILE *pFile; HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; pFile = fopen("passwords.txt", "r"); if (pFile != NULL) { if (fgetws(data, 100, pFile) == NULL) { data[0] = L'\0'; } fclose(pFile); } else { data[0] = L'\0'; } do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as data except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), data); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(data, 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 before passing it to the sink */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into data and NUL-terminate */ memcpy(data, payload, payloadBytes); data[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } } CWE256_Plaintext_Storage_of_Password__w32_wchar_t_53b_goodG2BSink(data); }
NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) { HCERTSTORE hCertificateStore; PCCERT_CONTEXT pCertContext; DWORD i, j, dwSizeNeeded, keySpec; wchar_t *certName; PCRYPT_KEY_PROV_INFO pBuffer; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv; HCRYPTKEY maCle; BOOL keyToFree; PCWCHAR szSystemStore, szStore; DWORD dwSystemStore = 0; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name); dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore); kull_m_string_args_byName(argc, argv, L"store", &szStore, L"My"); kprintf(L" * System Store : \'%s\' (0x%08x)\n" L" * Store : \'%s\'\n\n", szSystemStore, dwSystemStore, szStore); if(hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, dwSystemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, szStore)) { for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++) { for(j = 0; j < ARRAYSIZE(nameSrc); j++) { dwSizeNeeded = CertGetNameString(pCertContext, nameSrc[j], 0, NULL, NULL, 0); if(dwSizeNeeded > 0) { if(certName = (wchar_t *) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t))) { if(CertGetNameString(pCertContext, nameSrc[j], 0, NULL, certName, dwSizeNeeded) == dwSizeNeeded) { kprintf(L"%2u. %s\n", i, certName); dwSizeNeeded = 0; if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded)) { if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded)) { if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded)) { kprintf( L"\tKey Container : %s\n" L"\tProvider : %s\n", (pBuffer->pwszContainerName ? pBuffer->pwszContainerName : L"(null)"), (pBuffer->pwszProvName ? pBuffer->pwszProvName : L"(null)")); if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &keyToFree)) { kprintf(L"\tType : %s (0x%08x)\n", kuhl_m_crypto_keytype_to_str(keySpec), keySpec); if(keySpec != CERT_NCRYPT_KEY_SPEC) { if(CryptGetUserKey(monProv, keySpec, &maCle)) { kuhl_m_crypto_printKeyInfos(0, maCle); CryptDestroyKey(maCle); } else PRINT_ERROR_AUTO(L"CryptGetUserKey"); if(keyToFree) CryptReleaseContext(monProv, 0); } else if(kuhl_m_crypto_hNCrypt) { kuhl_m_crypto_printKeyInfos(monProv, 0); if(keyToFree) K_NCryptFreeObject(monProv); } else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); } else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); } else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); } LocalFree(pBuffer); if(!export) kprintf(L"\n"); } if(export) kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName); } else PRINT_ERROR_AUTO(L"CertGetNameString"); LocalFree(certName); } break; } else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); }
/* 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); } } }
/* 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."); } } } }
/* good1() reverses the blocks on the goto statement */ static void good1() { goto sink; sink: { BYTE payload[200]; DWORD payloadLen = strlen(PAYLOAD); HCRYPTPROV hCryptProv = (HCRYPTPROV)NULL; HCRYPTHASH hHash = (HCRYPTHASH)NULL; HCRYPTKEY hKey = (HCRYPTKEY)NULL; do { /* Copy plaintext into payload buffer */ memcpy(payload, PAYLOAD, payloadLen); /* Try to get a context with and without a new key set */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)) { if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 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 data */ if(!CryptHashData(hHash, (BYTE *) HASH_INPUT, strlen(HASH_INPUT)*sizeof(char), 0)) { printLine("Error in hashing HASH_INPUT"); exit(1); } /* Derive an RSA key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_RSA_SIGN, hHash, 0, &hKey)) { printLine("Error in CryptDeriveKey"); exit(1); } /* FIX: Use OAEP padding */ /* Use the derived key to encrypt something */ if(!CryptEncrypt(hKey, (HCRYPTHASH)NULL, 1, CRYPT_OAEP, (BYTE *)payload, &payloadLen, sizeof(payload))) { printLine("Error in CryptEncryptData"); exit(1); } } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* use encrypted block */ printBytesLine((BYTE *) payload, payloadLen); } }
void free_RSA_key(RSA_key_t rsa) { if (!CryptDestroyKey(rsa)) { mserror("CryptDestroyKey failed"); } }
/* good1() uses if(staticFalse) instead of if(staticTrue) */ static void good1() { if(staticFalse) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { { BYTE payload[100]; DWORD payloadLen = strlen(PAYLOAD); HCRYPTPROV hCryptProv = (HCRYPTPROV)NULL; HCRYPTHASH hHash = (HCRYPTHASH)NULL; HCRYPTKEY hKey = (HCRYPTKEY)NULL; char hashData[100] = HASH_INPUT; do { /* Copy plaintext into payload buffer */ memcpy(payload, PAYLOAD, payloadLen); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* FIX: All required steps are present */ /* 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; } /* Encrypt the payload */ if(!CryptEncrypt(hKey, 0, 1, 0, payload, &payloadLen, sizeof(payload))) { break; } } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Do something with the encrypted data */ printBytesLine(payload, payloadLen); } } }
/** * Calculates the HMAC of the given message, hashtype, and hashkey. * dest must be at least the hash length. */ int create_hmac(int hashtype, const unsigned char *key, unsigned int keylen, const unsigned char *src, unsigned int srclen, unsigned char *dest, unsigned int *destlen) { // TODO: right now we reimport the hmac key each time. Test to see if this // is quick enough or if we need to cache an imported hmac key. HCRYPTKEY hmackey; HCRYPTHASH hash; char keyblob[BLOBLEN]; BLOBHEADER *bheader; DWORD *keysize; BYTE *keydata; HMAC_INFO info; ALG_ID alg; int bloblen, hashlen, rval; DWORD _destlen; hashlen = get_hash_len(hashtype); alg = get_hash(hashtype); if (alg == 0) { log0(0, 0, 0, "Invalid hashtype"); return 0; } bheader = (BLOBHEADER *)keyblob; keysize = (DWORD *)(keyblob + sizeof(BLOBHEADER)); keydata = (BYTE *)((char *)keysize + sizeof(DWORD)); memset(keyblob, 0, sizeof(keyblob)); bheader->bType = PLAINTEXTKEYBLOB; bheader->bVersion = CUR_BLOB_VERSION; bheader->aiKeyAlg = CALG_RC2; *keysize = keylen; memcpy(keydata, key, keylen); bloblen = sizeof(BLOBHEADER) + sizeof(DWORD) + hashlen; if (!CryptImportKey(base_prov, keyblob, bloblen, 0, CRYPT_IPSEC_HMAC_KEY, &hmackey)) { mserror("CryptImportKey failed"); return 0; } if (!CryptCreateHash(base_prov, CALG_HMAC, hmackey, 0, &hash)) { mserror("CryptCreateHash failed"); rval = 0; goto end1; } memset(&info, 0, sizeof(info)); info.HashAlgid = alg; if (!CryptSetHashParam(hash, HP_HMAC_INFO, (BYTE *)&info, 0)) { mserror("CryptSetHashParam failed"); rval = 0; goto end2; } if (!CryptHashData(hash, src, srclen, 0)) { mserror("CryptHashData failed"); rval = 0; goto end2; } _destlen = hashlen; if (!CryptGetHashParam(hash, HP_HASHVAL, dest, &_destlen, 0)) { mserror("CryptGetHashParam failed"); rval = 0; goto end2; } *destlen = _destlen; rval = 1; end2: if (!CryptDestroyHash(hash)) { mserror("CryptDestroyHash failed"); } end1: if (!CryptDestroyKey(hmackey)) { mserror("CryptDestroyKey failed"); } return rval; }
void CAPICertificate::setUri (const std::string& capiUri) { valid_ = false; /* Syntax: "certstore:" <cert_store> ":" <hash> ":" <hash_of_cert> */ if (!boost::iequals(capiUri.substr(0, 10), "certstore:")) { return; } /* Substring of subject: uses "storename" */ std::string capiIdentity = capiUri.substr(10); std::string newCertStoreName; size_t pos = capiIdentity.find_first_of (':'); if (pos == std::string::npos) { /* Using the default certificate store */ newCertStoreName = "MY"; certName_ = capiIdentity; } else { newCertStoreName = capiIdentity.substr(0, pos); certName_ = capiIdentity.substr(pos + 1); } if (certStoreHandle_ != NULL) { if (newCertStoreName != certStore_) { CertCloseStore(certStoreHandle_, 0); certStoreHandle_ = NULL; } } if (certStoreHandle_ == NULL) { certStoreHandle_ = CertOpenSystemStore(0, newCertStoreName.c_str()); if (!certStoreHandle_) { return; } } certStore_ = newCertStoreName; PCCERT_CONTEXT certContext = findCertificateInStore (certStoreHandle_, certName_); if (!certContext) { return; } /* Now verify that we can have access to the corresponding private key */ DWORD len; CRYPT_KEY_PROV_INFO *pinfo; HCRYPTPROV hprov; HCRYPTKEY key; if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) { CertFreeCertificateContext(certContext); return; } pinfo = static_cast<CRYPT_KEY_PROV_INFO *>(malloc(len)); if (!pinfo) { CertFreeCertificateContext(certContext); return; } if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { CertFreeCertificateContext(certContext); free(pinfo); return; } CertFreeCertificateContext(certContext); // Now verify if we have access to the private key if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) { free(pinfo); return; } char smartCardReader[1024]; DWORD bufferLength = sizeof(smartCardReader); if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartCardReader, &bufferLength, 0)) { DWORD error = GetLastError(); smartCardReaderName_ = ""; } else { smartCardReaderName_ = smartCardReader; LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); DEBUG_SCARD_STATUS("SCardEstablishContext", result); if (SCARD_S_SUCCESS == result) { // Initiate monitoring for smartcard ejection smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS); } else { ///Need to handle an error here } } if (!CryptGetUserKey(hprov, pinfo->dwKeySpec, &key)) { CryptReleaseContext(hprov, 0); free(pinfo); return; } CryptDestroyKey(key); CryptReleaseContext(hprov, 0); free(pinfo); if (smartCardTimer_) { smartCardTimer_->onTick.connect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); smartCardTimer_->start(); } valid_ = true; }
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); } }
//----------------------------------------------------------------------------- // swPBKDF2() : implémentation de PBKDF2 RFC 2898 (http://www.ietf.org/rfc/rfc2898.txt) // Limitée à 2 blocs de 160 bits en sortie, dont seuls les 256 premiers sont // fournis à l'appelant. Ce résultat est utilisé pour : // 1) Alimenter la fonction de dérivation de clé AES-256 (CryptDeriveKey) // 2) Stocker le mot de passe maître //----------------------------------------------------------------------------- // Avec 2 blocs, l'algo proposé par la RFC donne : // DK = T_1 || T_2 // T_1 = F (P, S, c, 1) // T_2 = F (P, S, c, 2) // où : // P = password, an octet string // S = salt, an octet string // c = iteration count, a positive integer // F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c // U_1 = PRF (P, S || INT (i)) // U_2 = PRF (P, U_1) // ... // U_c = PRF (P, U_{c-1}) //----------------------------------------------------------------------------- // MERCI A GUILLAUME POUR SA PROPOSITION D'IMPLEMENTATION ! //----------------------------------------------------------------------------- // [out]bufResult = pointeur vers un buffer de bytes (alloué par l'appelant) // [in] bufResultLen = taille de clé souhaitée (max HASH_LENx2) // [in] szPwd = mot de passe maitre a deriver // [in] bufSalt = buffer contenant le sel // [in] bufSaltLen = taille du buffer de sel (PBKDF2_SALT_LEN) // [in] iNbIterations = nombre d'itérations //----------------------------------------------------------------------------- int swPBKDF2(BYTE *bufResult,int bufResultLen,const char *szPwd,const BYTE *bufSalt,int bufSaltLen,int iNbIterations) { TRACE((TRACE_ENTER,_F_,"bufResultLen=%d iNbIterations=%d",bufResultLen,iNbIterations)); //TRACE((TRACE_PWD,_F_,"szPwd=%s",szPwd)); TRACE_BUFFER((TRACE_DEBUG,_F_,(BYTE*)bufSalt,bufSaltLen,"sel")); int brc; int c; // itérations int rc=-1; HCRYPTKEY hKey=NULL; HCRYPTHASH hHMAC=NULL; HMAC_INFO hmacinfo; KEYBLOB *pKey=NULL; int iKeySize; DWORD dwLenHash; BYTE bufU_c[HASH_LEN]; // stocke successivement U_1, U_2, ..., U_c BYTE bufT[HASH_LEN*2]; // stocke le résultat final : T_1 à l'index 0 et T_2 à l'index HASH_LEN BYTE bufSaltWithBlocIndex[PBKDF2_SALT_LEN+4]; int iBloc; if (bufResultLen>HASH_LEN*2) { TRACE((TRACE_ERROR,_F_,"bufResultLen=%d > valeur autorisée HASH_LEN*2=%d",bufResultLen,HASH_LEN*2)); goto end; } if (bufSaltLen!=PBKDF2_SALT_LEN) { TRACE((TRACE_ERROR,_F_,"bufSaltLen=%d != valeur imposée PBKDF2_SALT_LEN=%d",bufSaltLen,PBKDF2_SALT_LEN)); goto end; } // Création de la clé HMAC en mode PLAINTEXTKEYBLOB, à partir du mot de passe iKeySize=sizeof(KEYBLOB)+strlen(szPwd); pKey=(KEYBLOB*)malloc(iKeySize); if (pKey==NULL) { TRACE((TRACE_ERROR,_F_,"malloc(%d)",iKeySize)); goto end; } ZeroMemory(pKey,iKeySize); // Création de la clé symétrique pour le HMAC // cf. doc de CryptImportKey() -> http://msdn.microsoft.com/en-us/library/aa380207(v=vs.85).aspx : // "When importing a Hash-Based Message Authentication Code (HMAC) key, the caller must identify // the imported key as a PLAINTEXTKEYBLOB type" // "The HMAC algorithms do not have their own algorithm identifiers; use CALG_RC2 instead. // CRYPT_IPSEC_HMAC_KEY allows the import of RC2 keys longer than 16 bytes." // cf. tests vectors de la RFC 2202 HMAC-SHA1 pKey->header.bType=PLAINTEXTKEYBLOB; pKey->header.bVersion=CUR_BLOB_VERSION; pKey->header.reserved=0; pKey->header.aiKeyAlg=CALG_RC2; pKey->dwKeySize=strlen(szPwd); memcpy(pKey->KeyData,szPwd,pKey->dwKeySize); // test case 1 RFC 2202 HMAC-SHA1 /*pKey->dwKeySize=20; memset(pKey->KeyData,0x0b,pKey->dwKeySize);*/ // fin test case 1 RFC 2202 HMAC-SHA1 // test case 7 RFC 2202 HMAC-SHA1 /*pKey->dwKeySize=80; memset(pKey->KeyData,0xaa,pKey->dwKeySize);*/ // fin test case 7 RFC 2202 HMAC-SHA1 //TRACE_BUFFER((TRACE_PWD,_F_,(BYTE*)pKey,iKeySize,"pKey (iKeySize=%d)",iKeySize)); brc= CryptImportKey(ghProv,(LPBYTE)pKey,iKeySize,NULL,CRYPT_IPSEC_HMAC_KEY,&hKey); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptImportKey()=0x%08lx",GetLastError())); goto end; } // Initialisation du buffer resultat a zero ZeroMemory(bufT,HASH_LEN*2); // Itération pour sortir 2 blocs de 160 bits chacun (T_1 et T_2) for (iBloc=1;iBloc<=2;iBloc++) { // concaténation de l'index de bloc au sel memcpy(bufSaltWithBlocIndex,bufSalt,PBKDF2_SALT_LEN); bufSaltWithBlocIndex[bufSaltLen]=0x00; bufSaltWithBlocIndex[bufSaltLen+1]=0x00; bufSaltWithBlocIndex[bufSaltLen+2]=0x00; bufSaltWithBlocIndex[bufSaltLen+3]=(BYTE)iBloc; TRACE_BUFFER((TRACE_DEBUG,_F_,bufSaltWithBlocIndex,bufSaltLen+4,"bufSaltWithBlocIndex")); // Création du HMAC // cf. http://msdn.microsoft.com/en-us/library/aa382379(VS.85).aspx brc=CryptCreateHash(ghProv,CALG_HMAC,hKey,0,&hHMAC); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; } // Initialisation des paramètres du HMAC ZeroMemory(&hmacinfo,sizeof(hmacinfo)); hmacinfo.HashAlgid=CALG_SHA1; brc=CryptSetHashParam(hHMAC,HP_HMAC_INFO, (BYTE*)&hmacinfo,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptSetHashParam()=0x%08lx",GetLastError())); goto end; } // test case 1 RFC 2202 HMAC-SHA1 /*brc=CryptHashData(hHMAC,(const BYTE*)"Hi There",8, 0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; } brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam()=0x%08lx",GetLastError())); goto end; } TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"Test case 1 RFC 2202 HMAC-SHA1")); if (brc) goto end;*/ // fin test case 1 RFC 2202 HMAC-SHA1 // test case 7 RFC 2202 HMAC-SHA1 /*brc=CryptHashData(hHMAC,(const BYTE*)"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",73, 0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; } brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam()=0x%08lx",GetLastError())); goto end; } TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"Test case 1 RFC 2202 HMAC-SHA1")); if (brc) goto end;*/ // fin test case 7 RFC 2202 HMAC-SHA1 // HMAC du sel enrichi de l'id de bloc brc=CryptHashData(hHMAC,bufSaltWithBlocIndex,bufSaltLen+4, 0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData(bufSaltWithBlocIndex)=0x%08lx",GetLastError())); goto end; } // Récupération du hash dwLenHash=sizeof(bufU_c); brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(bufU_1)=0x%08lx",GetLastError())); goto end; } TRACE_BUFFER((TRACE_DEBUG,_F_,bufU_c,HASH_LEN,"bufU_1")); // Destruction du HMAC brc=CryptDestroyHash(hHMAC); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptDestroyHash()=0x%08lx",GetLastError())); goto end; } hHMAC=NULL; // XOR dans le buffer résultat swXORBuff(bufT+(iBloc-1)*HASH_LEN,bufU_c,HASH_LEN); // Iterations for (c=2;c<=iNbIterations;c++) // on démarre à 1, la 1ère itération étant faite précédemment hors de la boucle { // Création du HMAC brc=CryptCreateHash(ghProv,CALG_HMAC,hKey,0,&hHMAC); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptCreateHash()=0x%08lx",GetLastError())); goto end; } // Initialisation des paramètres du HMAC ZeroMemory(&hmacinfo,sizeof(hmacinfo)); hmacinfo.HashAlgid=CALG_SHA1; brc=CryptSetHashParam(hHMAC,HP_HMAC_INFO,(BYTE*)&hmacinfo,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptSetHashParam()=0x%08lx",GetLastError())); goto end; } // HMAC du résultat de l'itération précédente brc=CryptHashData(hHMAC,bufU_c,HASH_LEN,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptHashData(bufU_%d)=0x%08lx",c,GetLastError())); goto end; } // Recup du hash brc=CryptGetHashParam(hHMAC,HP_HASHVAL,bufU_c,&dwLenHash,0); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptGetHashParam(bufU_%d)=0x%08lx",c,GetLastError())); goto end; } // Détruire le HMAC brc=CryptDestroyHash(hHMAC); if (!brc) { TRACE((TRACE_ERROR,_F_,"CryptDestroyHash()=0x%08lx",GetLastError())); goto end; } hHMAC=NULL; // XOR dans le resultat swXORBuff(bufT+(iBloc-1)*HASH_LEN,bufU_c,HASH_LEN); } TRACE_BUFFER((TRACE_DEBUG,_F_,bufT+(iBloc-1)*HASH_LEN,HASH_LEN,"bufT_%d",iBloc)); } // Les 2 blocs sont alimentés, on extrait les bufResultLen pour alimenter bufResult memcpy(bufResult,bufT,bufResultLen); TRACE_BUFFER((TRACE_DEBUG,_F_,bufResult,bufResultLen,"bufResult")); rc=0; end: if (hHMAC!=NULL) CryptDestroyHash(hHMAC); if (hKey!=NULL) CryptDestroyKey(hKey); if (pKey!=NULL) free(pKey); TRACE((TRACE_LEAVE,_F_,"rc=%d",rc)); return rc; }
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; }
//----------------------------------------------------------------------------- // swCryptDestroyKey() //----------------------------------------------------------------------------- // Libération d'une clé //----------------------------------------------------------------------------- void swCryptDestroyKey(HCRYPTKEY hKey) { TRACE((TRACE_ENTER,_F_,"")); if (hKey!=NULL) CryptDestroyKey(hKey); TRACE((TRACE_LEAVE,_F_,"")); }
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); } } }
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; }
/* goodG2B1() - use goodsource and badsink by changing the first STATIC_CONST_TRUE to STATIC_CONST_FALSE */ static void goodG2B1() { char * data; char dataBuffer[100] = ""; data = dataBuffer; if(STATIC_CONST_FALSE) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { { FILE *pFile; HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; pFile = fopen("passwords.txt", "r"); if (pFile != NULL) { if (fgets(data, 100, pFile) == NULL) { data[0] = '\0'; } fclose(pFile); } else { data[0] = '\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; } /* FIX: Decrypt the password before passing it to the sink */ 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); } } } if(STATIC_CONST_TRUE) { { HANDLE pHandle; char * username = "******"; char * domain = "Domain"; /* POTENTIAL FLAW: Attempt to login user with password from the source */ 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."); } } } }
DWORD ShowCertsDlg(LPCTSTR szProviderName, LPCTSTR szReaderName /* Can be NULL */ ) { HCRYPTPROV HMainCryptProv = NULL; BOOL bStatus = FALSE; LPTSTR szMainContainerName = NULL; CHAR szContainerName[1024]; DWORD dwContainerNameLen = sizeof(szContainerName); DWORD dwErr = 0; DWORD dwFlags = CRYPT_FIRST; PCCERT_CONTEXT pContextArray[128]; DWORD dwContextArrayLen = 0; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; LPBYTE pbCert = NULL; DWORD dwCertLen = 0; PCCERT_CONTEXT pCertContext = NULL; DWORD pKeySpecs[2] = { AT_KEYEXCHANGE, AT_SIGNATURE}; if (szReaderName) { size_t ulNameLen = _tcslen(szReaderName); szMainContainerName = (LPTSTR) LocalAlloc(0, (ulNameLen + 6) * sizeof(TCHAR)); if (!szMainContainerName) { return GetLastError(); } _stprintf(szMainContainerName, _T("\\\\.\\%s\\"), szReaderName); } bStatus = CryptAcquireContext(&HMainCryptProv,szMainContainerName,szProviderName,PROV_RSA_FULL,0); if (!bStatus) { dwErr = GetLastError(); goto end; } /* Enumerate all the containers */ while (CryptGetProvParam(HMainCryptProv,PP_ENUMCONTAINERS,(LPBYTE) szContainerName,&dwContainerNameLen,dwFlags) &&(dwContextArrayLen < 128)) { #ifndef _UNICODE if (CryptAcquireContext(&hProv, szContainerName, szProviderName, PROV_RSA_FULL, 0)) #else // convert the container name to unicode int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0); LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0, wLen * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen); // Acquire a context on the current container if (CryptAcquireContext(&hProv,szWideContainerName,szProviderName,PROV_RSA_FULL,0)) #endif { // Loop over all the key specs for (int i = 0; i < 2; i++) { if (CryptGetUserKey(hProv,pKeySpecs[i],&hKey) ) { if (CryptGetKeyParam(hKey,KP_CERTIFICATE,NULL,&dwCertLen,0)) { pbCert = (LPBYTE) LocalAlloc(0, dwCertLen); if (!pbCert) { dwErr = GetLastError(); goto end; } if (CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCert,&dwCertLen,0)) { pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, pbCert,dwCertLen); if (pCertContext) { pContextArray[dwContextArrayLen++] = pCertContext; CRYPT_KEY_PROV_INFO ProvInfo; ProvInfo.pwszContainerName = szWideContainerName; ProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; ProvInfo.dwProvType = PROV_RSA_FULL; ProvInfo.dwFlags = 0; ProvInfo.dwKeySpec = AT_SIGNATURE; ProvInfo.cProvParam = 0; ProvInfo.rgProvParam = NULL; CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, &ProvInfo); HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,L"My"); if(CertAddCertificateContextToStore(dest, pCertContext,CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { //char certName[1024]; //LPWSTR certName = (LPWSTR)new wchar_t[1024]; LPTSTR certName; int cbSize = CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,NULL,0); certName = (LPTSTR)malloc(cbSize * sizeof(TCHAR)); if (CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,certName,sizeof(certName))) { } printf("Installed certificate."); } else printf("Error while adding certificate to store"); } } LocalFree(pbCert); } CryptDestroyKey(hKey); hKey = NULL; } } CryptReleaseContext(hProv, 0); hProv = NULL; } #ifdef _UNICODE LocalFree(szWideContainerName); #endif // prepare parameters for the next loop dwContainerNameLen = sizeof(szContainerName); dwFlags = 0; } if (dwContextArrayLen == 0) printf("No certificate contexts found on card\n"); end: while (dwContextArrayLen--) { CertFreeCertificateContext(pContextArray[dwContextArrayLen]); } if (hKey) CryptDestroyKey(hKey); if (hProv) CryptReleaseContext(hProv, 0); if (szMainContainerName) LocalFree(szMainContainerName); if (HMainCryptProv) CryptReleaseContext(HMainCryptProv, 0); return dwErr; }