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.");
        }
    }
}
Beispiel #3
0
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);

}
Beispiel #4
0
/*
* 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;
}
Beispiel #5
0
// 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;
}
Beispiel #7
0
/**
 * 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.");
            }
        }
    }
}
Beispiel #9
0
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;
}
Beispiel #10
0
// 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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}
Beispiel #13
0
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);
}
Beispiel #15
0
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);
    }
}
Beispiel #19
0
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);
        }
    }
}
Beispiel #21
0
/**
 * 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;
}
Beispiel #22
0
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);
   }
}
Beispiel #24
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;
}
Beispiel #26
0
//-----------------------------------------------------------------------------
// 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.");
            }
        }
    }
}
Beispiel #30
0
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;
}