text: /* TEMPLATE GENERATED TESTCASE FILE
  Filename: CWE256_Plaintext_Storage_of_Password__w32_char_33.cpp
  Label Definition File: CWE256_Plaintext_Storage_of_Password__w32.label.xml
  Template File: sources-sinks-33.tmpl.cpp
  */
  /*
   * @description
   * CWE: 256 Plaintext Storage of Password
   * BadSource:  Read the password from a file
   * GoodSource: Read the password from a file and decrypt it
   * Sinks:
   *    GoodSink: Decrypt the password then authenticate the user using LogonUserA()
   *    BadSink : Authenticate the user using LogonUserA()
   * Flow Variant: 33 Data flow: use of a C++ reference to data within the same function
   *
   * */
  
  #include "std_testcase.h"
  
  #include <wchar.h>
  #include <windows.h>
  #include <wincrypt.h>
  #pragma comment(lib, "advapi32")
  #pragma comment(lib, "crypt32.lib")
  
  #define HASH_INPUT "ABCDEFG123456" /* INCIDENTAL: Hardcoded crypto */
  
  namespace CWE256_Plaintext_Storage_of_Password__w32_char_33
  {
  
  #ifndef OMITBAD
  
  void bad()
  {
      char * data;
      char * &dataRef = data;
      char dataBuffer[100] = "";
      data = dataBuffer;
      {
          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';
          }
      }
      {
          char * data = dataRef;
          {
              HANDLE pHandle;
              char * username = "User";
              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.");
              }
          }
      }
  }
  
  #endif /* OMITBAD */
  
  #ifndef OMITGOOD
  
  /* goodG2B() uses the GoodSource with the BadSink */
  static void goodG2B()
  {
      char * data;
      char * &dataRef = data;
      char dataBuffer[100] = "";
      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 (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);
          }
      }
      {
          char * data = dataRef;
          {
              HANDLE pHandle;
              char * username = "User";
              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.");
              }
          }
      }
  }
  
  /* goodB2G() uses the BadSource with the GoodSink */
  static void goodB2G()
  {
      char * data;
      char * &dataRef = data;
      char dataBuffer[100] = "";
      data = dataBuffer;
      {
          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';
          }
      }
      {
          char * data = dataRef;
          {
              HANDLE pHandle;
              char * username = "User";
              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 good()
  {
      goodG2B();
      goodB2G();
  }
  
  #endif /* OMITGOOD */
  
  } /* close namespace */
  
  /* Below is the main(). It is only used when building this testcase on
     its own for testing or for building a binary to use in testing binary
     analysis tools. It is not used when compiling all the testcases as one
     application, which is how source code analysis tools are tested. */
  #ifdef INCLUDEMAIN
  
  using namespace CWE256_Plaintext_Storage_of_Password__w32_char_33; /* so that we can use good and bad easily */
  
  int main(int argc, char * argv[])
  {
      /* seed randomness */
      srand( (unsigned)time(NULL) );
  #ifndef OMITGOOD
      printLine("Calling good()...");
      good();
      printLine("Finished good()");
  #endif /* OMITGOOD */
  #ifndef OMITBAD
      printLine("Calling bad()...");
      bad();
      printLine("Finished bad()");
  #endif /* OMITBAD */
      return 0;
  }
  
  #endif
  