text: /* TEMPLATE GENERATED TESTCASE FILE
  Filename: CWE319_Cleartext_Tx_Sensitive_Info__w32_char_listen_socket_62a.cpp
  Label Definition File: CWE319_Cleartext_Tx_Sensitive_Info__w32.label.xml
  Template File: sources-sinks-62a.tmpl.cpp
  */
  /*
   * @description
   * CWE: 319 Cleartext Transmission of Sensitive Information
   * BadSource: listen_socket Read the password using a listen socket (server side)
   * GoodSource: Use a hardcoded password (one that was not sent over the network)
   * Sinks:
   *    GoodSink: Decrypt the password before using it in an authentication API call to show that it was transferred as ciphertext
   *    BadSink : Use the password directly from the source in an authentication API call to show that it was transferred as plaintext
   * Flow Variant: 62 Data flow: data flows using a C++ reference from one function to another in different source files
   *
   * */
  
  #include "std_testcase.h"
  
  #include <windows.h>
  #pragma comment(lib, "advapi32.lib")
  
  #define HASH_INPUT "ABCDEFG123456" /* INCIDENTAL: Hardcoded crypto */
  
  namespace CWE319_Cleartext_Tx_Sensitive_Info__w32_char_listen_socket_62
  {
  
  #ifndef OMITBAD
  
  /* bad function declaration */
  void badSource(char * &password);
  
  void bad()
  {
      char * password;
      char passwordBuffer[100] = "";
      password = passwordBuffer;
      badSource(password);
      {
          HANDLE pHandle;
          char * username = "User";
          char * domain = "Domain";
          /* Use the password in LogonUser() to establish that it is "sensitive" */
          /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */
          if (LogonUserA(
                      username,
                      domain,
                      password,
                      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 */
  void goodG2BSource(char * &password);
  
  static void goodG2B()
  {
      char * password;
      char passwordBuffer[100] = "";
      password = passwordBuffer;
      goodG2BSource(password);
      {
          HANDLE pHandle;
          char * username = "User";
          char * domain = "Domain";
          /* Use the password in LogonUser() to establish that it is "sensitive" */
          /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */
          if (LogonUserA(
                      username,
                      domain,
                      password,
                      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 */
  void goodB2GSource(char * &password);
  
  static void goodB2G()
  {
      char * password;
      char passwordBuffer[100] = "";
      password = passwordBuffer;
      goodB2GSource(password);
      {
          HCRYPTPROV hCryptProv = 0;
          HCRYPTHASH hHash = 0;
          HCRYPTKEY hKey = 0;
          char hashData[100] = HASH_INPUT;
          HANDLE pHandle;
          char * username = "User";
          char * domain = "Domain";
          do
          {
              BYTE payload[(100 - 1) * sizeof(char)]; /* same size as password except for NUL terminator */
              DWORD payloadBytes;
              /* Hex-decode the input string into raw bytes */
              payloadBytes = decodeHexChars(payload, sizeof(payload), password);
              /* Wipe the hex string, to prevent it from being given to LogonUserA if
               * any of the crypto calls fail. */
              SecureZeroMemory(password, 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 */
              if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes))
              {
                  break;
              }
              /* Copy back into password and NUL-terminate */
              memcpy(password, payload, payloadBytes);
              password[payloadBytes / sizeof(char)] = '\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 (LogonUserA(
                      username,
                      domain,
                      password,
                      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 CWE319_Cleartext_Tx_Sensitive_Info__w32_char_listen_socket_62; /* 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
  