text: /* TEMPLATE GENERATED TESTCASE FILE
  Filename: CWE321_Hard_Coded_Cryptographic_Key__w32_wchar_t_63b.c
  Label Definition File: CWE321_Hard_Coded_Cryptographic_Key__w32.label.xml
  Template File: sources-sink-63b.tmpl.c
  */
  /*
   * @description
   * CWE: 321 Use of Hard-coded Cryptographic Key
   * BadSource:  Copy a hardcoded value into cryptoKey
   * GoodSource: Read cryptoKey from the console
   * Sinks:
   *    BadSink : Hash cryptoKey and use the value to encrypt a string
   * Flow Variant: 63 Data flow: pointer to data passed from one function to another in different source files
   *
   * */
  
  #include "std_testcase.h"
  
  #define CRYPTO_KEY L"Hardcoded"
  
  #include <windows.h>
  #include <wincrypt.h>
  
  /* Link with the Advapi32.lib file for Crypt* functions */
  #pragma comment (lib, "Advapi32")
  
  #ifndef OMITBAD
  
  void CWE321_Hard_Coded_Cryptographic_Key__w32_wchar_t_63b_badSink(wchar_t * * cryptoKeyPtr)
  {
      wchar_t * cryptoKey = *cryptoKeyPtr;
      {
          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);
          }
      }
  }
  
  #endif /* OMITBAD */
  
  #ifndef OMITGOOD
  
  /* goodG2B uses the GoodSource with the BadSink */
  void CWE321_Hard_Coded_Cryptographic_Key__w32_wchar_t_63b_goodG2BSink(wchar_t * * cryptoKeyPtr)
  {
      wchar_t * cryptoKey = *cryptoKeyPtr;
      {
          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);
          }
      }
  }
  
  #endif /* OMITGOOD */
  