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);
            }
        }
    }
}
Пример #2
1
void
rust_win32_rand_release(HCRYPTPROV hProv) {
    win32_require
        (_T("CryptReleaseContext"), CryptReleaseContext(hProv, 0));
}
/* goodB2G1() - use badsource and goodsink by changing the second STATIC_CONST_TRUE to STATIC_CONST_FALSE */
static void goodB2G1()
{
    char * data;
    char dataBuffer[100] = "";
    data = dataBuffer;
    if(STATIC_CONST_TRUE)
    {
        {
            FILE *pFile;
            pFile = fopen("passwords.txt", "r");
            if (pFile != NULL)
            {
                /* POTENTIAL FLAW: Read the password from a file */
                if (fgets(data, 100, pFile) == NULL)
                {
                    data[0] = '\0';
                }
                fclose(pFile);
            }
            else
            {
                data[0] = '\0';
            }
        }
    }
    if(STATIC_CONST_FALSE)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            HANDLE pHandle;
            char * username = "******";
            char * domain = "Domain";
            char hashData[100] = HASH_INPUT;
            HCRYPTPROV hCryptProv = 0;
            HCRYPTHASH hHash = 0;
            HCRYPTKEY hKey = 0;
            do
            {
                BYTE payload[(100 - 1) * sizeof(char)]; /* same size as data except for NUL terminator */
                DWORD payloadBytes;
                /* Hex-decode the input string into raw bytes */
                payloadBytes = decodeHexChars(payload, sizeof(payload), data);
                /* Wipe the hex string, to prevent it from being given to LogonUserA if
                 * any of the crypto calls fail. */
                SecureZeroMemory(data, 100 * sizeof(char));
                /* Aquire a Context */
                if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0))
                {
                    break;
                }
                /* Create hash handle */
                if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash))
                {
                    break;
                }
                /* Hash the input string */
                if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0))
                {
                    break;
                }
                /* Derive an AES key from the hash */
                if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey))
                {
                    break;
                }
                if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes))
                {
                    break;
                }
                /* Copy back into data and NUL-terminate */
                memcpy(data, payload, payloadBytes);
                data[payloadBytes / sizeof(char)] = '\0';
            }
            while (0);
            if (hKey)
            {
                CryptDestroyKey(hKey);
            }
            if (hHash)
            {
                CryptDestroyHash(hHash);
            }
            if (hCryptProv)
            {
                CryptReleaseContext(hCryptProv, 0);
            }
            /* FIX: Decrypt the password before using it for authentication  */
            if (LogonUserA(
                        username,
                        domain,
                        data,
                        LOGON32_LOGON_NETWORK,
                        LOGON32_PROVIDER_DEFAULT,
                        &pHandle) != 0)
            {
                printLine("User logged in successfully.");
                CloseHandle(pHandle);
            }
            else
            {
                printLine("Unable to login.");
            }
        }
    }
}
void 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);
        }
    }
}
Пример #5
0
int KSI_PKITruststore_verifyRawSignature(KSI_CTX *ctx, const unsigned char *data, unsigned data_len, const char *algoOid, const unsigned char *signature, unsigned signature_len, const KSI_PKICertificate *certificate) {
	int res = KSI_UNKNOWN_ERROR;
	ALG_ID algorithm=0;
	HCRYPTPROV hCryptProv = 0;
    PCCERT_CONTEXT subjectCert = NULL;
	HCRYPTKEY publicKey = 0;
	DWORD i=0;
	BYTE *little_endian_pkcs1= NULL;
	DWORD pkcs1_len = 0;
	HCRYPTHASH hash = 0;
	char buf[1024];

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || data == NULL || signature == NULL ||
		signature_len >= UINT_MAX || algoOid == NULL || certificate == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}


	algorithm = algIdFromOID(algoOid);
	if (algorithm == 0) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL);
		goto cleanup;
	}

	// Get the CSP context
	if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to get cryptographic provider.");
		goto cleanup;
	}

	// Get the public key from the issuer certificate
	subjectCert = certificate->x509;
	if (!CryptImportPublicKeyInfo(hCryptProv, X509_ASN_ENCODING,&subjectCert->pCertInfo->SubjectPublicKeyInfo,&publicKey)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Failed to read PKI public key.");
		goto cleanup;
	}

	/*Convert big-endian to little-endian PKCS#1 signature*/
	pkcs1_len = signature_len;
	little_endian_pkcs1 = (BYTE*)KSI_malloc(pkcs1_len);

	if (little_endian_pkcs1 == NULL){
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	for (i=0; i<pkcs1_len; i++){
		little_endian_pkcs1[pkcs1_len-1-i] = signature[i];
	}

	// Create the hash object and hash input data.
	if (!CryptCreateHash(hCryptProv, algorithm, 0, 0, &hash)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to create hasher.");
		goto cleanup;
	}

	if (!CryptHashData(hash, (BYTE*)data, data_len,0)){
		KSI_LOG_debug(ctx, "%s", getMSError(GetLastError(), buf, sizeof(buf)));
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, "Unable to hash data.");
		goto cleanup;
	}

	/*Verify the signature. The format MUST be PKCS#1*/
	if (!CryptVerifySignature(hash, (BYTE*)little_endian_pkcs1, pkcs1_len, publicKey, NULL, 0)){
		DWORD error = GetLastError();
		const char *errmsg = getMSError(GetLastError(), buf, sizeof(buf));
		KSI_LOG_debug(ctx, "%s", errmsg);

		if (error == NTE_BAD_SIGNATURE)
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, "Invalid PKI signature.");
		else if (error == NTE_NO_MEMORY)
			KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, "Unable to verify PKI signature. CSP out of memory.");
		else
			KSI_pushError(ctx, res = KSI_PKI_CERTIFICATE_NOT_TRUSTED, errmsg);

		goto cleanup;
	}

	KSI_LOG_debug(certificate->ctx, "CryptoAPI: PKI signature verified successfully.");

	res = KSI_OK;

cleanup:

	KSI_free(little_endian_pkcs1);
	if (hCryptProv) CryptReleaseContext(hCryptProv, 0);
	if (hash) CryptDestroyHash(hash);

	return res;
}
Пример #6
0
HRESULT
modmd5(LPSTR *hexhash)
{
    HRESULT hRes;
    HANDLE hFile = NULL;
    DEBUG_MODULE_PARAMETERS ModParams;
    HCRYPTPROV hCryptProv = NULL;
    HCRYPTHASH hHash = NULL;
    BYTE *pbHashData = NULL;
    BYTE buffer[BUFSIZE];
    DWORD cbHash;
    DWORD cbRead = 0;
    BOOL bResult = FALSE;

   /*
    msdn: returns parameters for modules in the target.
    */
    hRes=g_ExtSymbols->GetModuleParameters(1, &g_Base, 0, &ModParams);
    if(FAILED(hRes))
    {
        dprintf("[sync] modcheck: failed get module parameters\n");
        return E_FAIL;
    }

    dprintf("[sync] modcheck:\n"
            "       File: %s\n"
            "       Size: 0x%x\n"
            "       TimeDateStamp: 0x%x\n", g_NameBuffer, ModParams.Size, ModParams.TimeDateStamp);

    hRes=E_FAIL;

    hFile = CreateFile(g_NameBuffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        dprintf("[sync] failed at opening file: %d\n", GetLastError());
        return hRes;
    }

    if (!(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)))
    {
        dprintf("[sync] CryptAcquireContext failed\n");
        goto Exit;
    }

    if (!(CryptCreateHash(hCryptProv, CALG_MD5, NULL, NULL, &hHash)))
    {
        dprintf("[sync] CryptCreateHash failed\n");
        goto Exit;
    }

    while (bResult = ReadFile(hFile, buffer, BUFSIZE, &cbRead, NULL))
    {
        if (cbRead == 0)
            break;

        if (!(CryptHashData(hHash, buffer, cbRead, NULL)))
        {
            dprintf("[sync] CryptHashData failed\n");
            goto Exit;
        }
    }

    if (!bResult)
    {
        dprintf("[sync] ReadFile failed\n");
        goto Exit;
    }

    if (!(CryptGetHashParam(hHash, HP_HASHVAL, NULL, &cbHash, 0)))
    {
        dprintf("[sync] CryptGetHashParam failed\n");
        goto Exit;
    }

    pbHashData = (BYTE *) malloc(cbHash);
    if (pbHashData==NULL){
        dprintf("[sync] failed at allocate buffer: %d\n", GetLastError());
        goto Exit;
    }

    if (!(CryptGetHashParam(hHash, HP_HASHVAL, pbHashData, &cbHash, 0)))
    {
        dprintf("[sync] CryptGetHashParam failed\n");
        goto Exit;
    }

    hRes = ToHexString((const byte *)pbHashData, (unsigned int)cbHash, hexhash);

Exit:
    if (hFile)
        CloseHandle(hFile);
    if (pbHashData)
        free(pbHashData);
    if (hHash)
       CryptDestroyHash(hHash);
    if (hCryptProv)
       CryptReleaseContext(hCryptProv,0);

    return hRes;
}
Пример #7
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;
}
/* 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);
        }
    }
}
Пример #9
0
int KSI_DataHasher_open(KSI_CTX *ctx, KSI_HashAlgorithm algo_id, KSI_DataHasher **hasher) {
	int res = KSI_UNKNOWN_ERROR;
	KSI_DataHasher *tmp_hasher = NULL;
	CRYPTO_HASH_CTX *tmp_cryptoCTX = NULL;
	HCRYPTPROV tmp_CSP = 0;

	KSI_ERR_clearErrors(ctx);
	if (ctx == NULL || hasher == NULL){
		res = KSI_INVALID_ARGUMENT;
		goto cleanup;
	}

	/*Test if hash algorithm is valid*/
	if (!KSI_isHashAlgorithmSupported(algo_id)) {
		KSI_pushError(ctx, res = KSI_UNAVAILABLE_HASH_ALGORITHM, NULL);
		goto cleanup;
	}

	/*Create new abstract data hasher object*/
	tmp_hasher = KSI_new(KSI_DataHasher);
	if (tmp_hasher == NULL) {
		KSI_pushError(ctx, res = KSI_OUT_OF_MEMORY, NULL);
		goto cleanup;
	}

	tmp_hasher->hashContext = NULL;
	tmp_hasher->ctx = ctx;
	tmp_hasher->algorithm = algo_id;
	tmp_hasher->closeExisting = closeExisting;

	/*Create new helper context for crypto api*/
	res = CRYPTO_HASH_CTX_new(&tmp_cryptoCTX);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	/*Create new crypto service provider (CSP)*/
	if (!CryptAcquireContext(&tmp_CSP, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
		char errm[1024];
		KSI_snprintf(errm, sizeof(errm), "Wincrypt Error (%d)", GetLastError());
		KSI_pushError(ctx, res = KSI_CRYPTO_FAILURE, errm);
		goto cleanup;
		}

	/*Set CSP in helper struct*/
	tmp_cryptoCTX->pt_CSP = tmp_CSP;
	/*Set helper struct in abstract struct*/
	tmp_hasher->hashContext = tmp_cryptoCTX;

	res = KSI_DataHasher_reset(tmp_hasher);
	if (res != KSI_OK) {
		KSI_pushError(ctx, res, NULL);
		goto cleanup;
	}

	*hasher = tmp_hasher;
	tmp_hasher = NULL;
	tmp_cryptoCTX = NULL;
	tmp_CSP = 0;

	res = KSI_OK;

cleanup:

	KSI_DataHasher_free(tmp_hasher);
	if (tmp_CSP) CryptReleaseContext(tmp_CSP, 0);
	CRYPTO_HASH_CTX_free(tmp_cryptoCTX);

	return res;
}
Пример #10
0
uint8_t ntru_rand_wincrypt_release(NtruRandContext *rand_ctx) {
    HCRYPTPROV *hCryptProv = (HCRYPTPROV*)rand_ctx->state;
    uint8_t result = CryptReleaseContext(*hCryptProv, 0);
    free(hCryptProv);
    return result;
}
Пример #11
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;
}
Пример #12
0
BOOL CreateSignatureHMACSHA1(wstring src, wstring secretKey, wstring& signature)
{
	signature = L"";

	string hashSrc = "";
	string hashKey = "";
	WtoUTF8(src, hashSrc);
	WtoUTF8(secretKey, hashKey);

	HCRYPTPROV cryptProv = NULL;
	HCRYPTHASH cryptHash = NULL;
	BYTE key[65];
	DWORD keySize = 0;
	BYTE ipad[65];
	BYTE opad[65];
	ZeroMemory(key, 65);
	ZeroMemory(ipad, 65);
	ZeroMemory(opad, 65);

	BYTE* firstHash = NULL;
	DWORD firstHashSize = 0;
	BYTE* secondHash = NULL;
	DWORD secondHashSize = 0;

	WCHAR* base64 = NULL;
	DWORD base64Size = 0;

	if ( CryptAcquireContext(&cryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE ){
		goto Err_End;
	}

	if( hashKey.size() > 64 ){
		if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){
			goto Err_End;
		}
		if( CryptHashData(cryptHash, (BYTE*)hashKey.c_str(), (DWORD)hashKey.length(), 0) == FALSE ){
			goto Err_End;
		}
		if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &keySize, 0 ) == FALSE ){
			goto Err_End;
		}
		if( CryptGetHashParam(cryptHash, HP_HASHVAL, key, &keySize, 0 ) == FALSE ){
			goto Err_End;
		}
		CryptDestroyHash(cryptHash);
		cryptHash = NULL;
	}else{
		keySize = (DWORD)hashKey.size();
		memcpy(key, hashKey.c_str(), keySize);
	}
	memcpy(ipad, key, keySize);
	memcpy(opad, key, keySize);
	for( int i=0; i<64; i++ ){
		ipad[i] ^= 0x36;
		opad[i] ^= 0x5c;
	}

	if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){
		goto Err_End;
	}
	if( CryptHashData(cryptHash, ipad, 64, 0) == FALSE ){
		goto Err_End;
	}
	if( CryptHashData(cryptHash, (BYTE*)hashSrc.c_str(), (DWORD)hashSrc.size(), 0) == FALSE ){
		goto Err_End;
	}
	if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &firstHashSize, 0 ) == FALSE ){
		goto Err_End;
	}
	firstHash = new BYTE[firstHashSize];
	if( CryptGetHashParam(cryptHash, HP_HASHVAL, firstHash, &firstHashSize, 0 ) == FALSE ){
		goto Err_End;
	}
	CryptDestroyHash(cryptHash);
	cryptHash = NULL;

	if ( CryptCreateHash(cryptProv, CALG_SHA1, 0, 0, &cryptHash) == FALSE ){
		goto Err_End;
	}
	if( CryptHashData(cryptHash, opad, 64, 0) == FALSE ){
		goto Err_End;
	}
	if( CryptHashData(cryptHash, firstHash, firstHashSize, 0) == FALSE ){
		goto Err_End;
	}
	if( CryptGetHashParam(cryptHash, HP_HASHVAL, NULL, &secondHashSize, 0 ) == FALSE ){
		goto Err_End;
	}
	secondHash = new BYTE[secondHashSize];
	if( CryptGetHashParam(cryptHash, HP_HASHVAL, secondHash, &secondHashSize, 0 ) == FALSE ){
		goto Err_End;
	}
	CryptDestroyHash(cryptHash);
	cryptHash = NULL;

	//Base64
	if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, NULL, &base64Size ) == FALSE){
		goto Err_End;
	}
   base64 = new WCHAR[ base64Size + 1 ];
   if( CryptBinaryToString( secondHash, secondHashSize, CRYPT_STRING_BASE64, base64, &base64Size ) == FALSE ){
		goto Err_End;
   }
   signature = base64;
   //最後に\r\n入ってしまうみたいなので除去
   Replace(signature, L"\r\n", L"");

Err_End:
	SAFE_DELETE_ARRAY(base64);
	SAFE_DELETE_ARRAY(secondHash);
	SAFE_DELETE_ARRAY(firstHash);

	if( cryptHash !=NULL ){
		CryptDestroyHash(cryptHash);
	}
	if( cryptProv != NULL ){
		CryptReleaseContext(cryptProv, 0);
	}

	if( signature.size() > 0 ){
		return TRUE;
	}else{
		return FALSE;
	}
}
Пример #13
0
//-----------------------------------------------------------------------------
// swCryptTerm()
//-----------------------------------------------------------------------------
// Libération du CSP 
//-----------------------------------------------------------------------------
void swCryptTerm()
{
	TRACE((TRACE_ENTER,_F_,""));
	if (ghProv!=NULL) { CryptReleaseContext(ghProv,0); ghProv=NULL; }
	TRACE((TRACE_LEAVE,_F_,""));
}
Пример #14
0
char *
mit_krb5_pkinit_cert_hash_str(const mit_krb5_data *cert)
{
#ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H

    CC_SHA1_CTX ctx;
    char *outstr, *cpOut;
    unsigned char digest[CC_SHA1_DIGEST_LENGTH];
    unsigned i;
    
    LOG_ENTRY();

    CC_SHA1_Init(&ctx);
    CC_SHA1_Update(&ctx, cert->data, cert->length);
    CC_SHA1_Final(digest, &ctx);
    
    cpOut = outstr = (char *)malloc((2 * CC_SHA1_DIGEST_LENGTH) + 1);
    if(outstr == NULL)
	return NULL;

    for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++, cpOut += 2)
	sprintf(cpOut, "%02X", (unsigned)digest[i]);
    *cpOut = '\0';
    return outstr;

#elif defined(_WIN32)

    HCRYPTPROV  hProv = 0;
    HCRYPTHASH  hHash = 0;
    char        *outstr = NULL;
    char        *outpos;
    size_t      cch_left;
    BYTE        *hash = NULL;
    DWORD       hashSize = 0;
    DWORD       len, i;

    LOG_ENTRY();

    if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_SIG, CRYPT_VERIFYCONTEXT)) {
        LOG_LASTERROR("CryptAcquireContext failed");
        goto done;
    }

    if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) {
        LOG_LASTERROR("CryptCreateHash failed");
        goto done;
    }

    if (!CryptHashData(hHash, (BYTE *) cert->data, cert->length, 0)) {
        LOG_LASTERROR("CryptHashData failed");
        goto done;
    }

    len = sizeof(hashSize);
    if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) &hashSize, &len, 0)) {
        LOG_LASTERROR("CryptGetHashParam failed while getting hash size");
        goto done;
    }

    hash = malloc(hashSize);
    if (hash == NULL) {
        goto done;
    }

    len = hashSize;
    if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, &len, 0)) {
        LOG_LASTERROR("CryptGetHashParam failed while getting hash");
        goto done;
    }

    outstr = malloc(hashSize * 2 + 1);
    if (outstr == NULL) {
        goto done;
    }

    outpos = outstr;
    cch_left = hashSize * 2 + 1;
    for (i = 0; i < hashSize; i++) {
        StringCchPrintfExA(outpos, cch_left, &outpos, &cch_left, STRSAFE_FILL_ON_FAILURE,
                           "%02X", (unsigned) hash[i]);
    }

    *outpos = '\0';

done:

    if (hHash != 0)
        CryptDestroyHash(hHash);

    if (hProv != 0)
        CryptReleaseContext(hProv, 0);

    if (hash != NULL)
        free(hash);

    return outstr;

#endif
}
Пример #15
0
isc_result_t
isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {
	isc_result_t ret;
	isc_entropysource_t *source;
	HCRYPTPROV hcryptprov;
	DWORD errval;
	BOOL err;

	REQUIRE(VALID_ENTROPY(ent));
	REQUIRE(fname != NULL);

	LOCK(&ent->lock);

	source = NULL;

	/*
	 * The first time we just try to acquire the context
	 */
	err = CryptAcquireContext(&hcryptprov, NULL, NULL, PROV_RSA_FULL,
				  CRYPT_VERIFYCONTEXT);
	if (!err){
		errval = GetLastError();
		ret = ISC_R_IOERROR;
		goto errout;
	}

	source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
	if (source == NULL) {
		ret = ISC_R_NOMEMORY;
		goto closecontext;
	}

	/*
	 * From here down, no failures can occur.
	 */
	source->magic = SOURCE_MAGIC;
	source->type = ENTROPY_SOURCETYPE_FILE;
	source->ent = ent;
	source->total = 0;
	source->bad = ISC_FALSE;
	memset(source->name, 0, sizeof(source->name));
	ISC_LINK_INIT(source, link);
	source->sources.file.handle = hcryptprov;

	/*
	 * Hook it into the entropy system.
	 */
	ISC_LIST_APPEND(ent->sources, source, link);
	ent->nsources++;

	UNLOCK(&ent->lock);
	return (ISC_R_SUCCESS);

 closecontext:
	CryptReleaseContext(hcryptprov, 0);

 errout:
	if (source != NULL)
		isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));

	UNLOCK(&ent->lock);

	return (ret);
}
/* 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.");
            }
        }
    }
}
Пример #17
0
int_t main(void)
{
   error_t error;
   size_t length;
   int_t ret;
   WSADATA wsaData;
   HOSTENT *host;
   SOCKADDR_IN addr;
   HCRYPTPROV hProvider;
   YarrowContext yarrowContext;
   char_t buffer[512];
   uint8_t seed[32];

   //Socket descriptor
   SOCKET sock = SOCKET_ERROR;

   //SSL/TLS context
   TlsContext *tlsContext = NULL;

   //Credentials
   char_t *clientCert = NULL;
   size_t clientCertLength = 0;
   char_t *clientPrivateKey = NULL;
   size_t clientPrivateKeyLength = 0;
   char_t *trustedCaList = NULL;
   size_t trustedCaListLength = 0;

   //Start-up message
   TRACE_INFO("******************************\r\n");
   TRACE_INFO("*** CycloneSSL Client Demo ***\r\n");
   TRACE_INFO("******************************\r\n");
   TRACE_INFO("\r\n");

   //Acquire cryptographic context
   ret = CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT);
   //Any error to report?
   if(!ret)
   {
      //Debug message
      TRACE_ERROR("Error: Cannot acquire cryptographic context (%d)\r\n", GetLastError());
      //Exit immediately
      return ERROR_FAILURE;
   }

   //Generate a random seed
   ret = CryptGenRandom(hProvider, sizeof(seed), seed);
   //Any error to report?
   if(!ret)
   {
      //Debug message
      TRACE_ERROR("Error: Failed to generate random data (%d)\r\n", GetLastError());
      //Exit immediately
      return ERROR_FAILURE;
   }

   //Release cryptographic context
   CryptReleaseContext(hProvider, 0);

   //PRNG initialization
   error = yarrowInit(&yarrowContext);
   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Error: PRNG initialization failed (%d)\r\n", error);
      //Exit immediately
      return ERROR_FAILURE;
   }

   //Properly seed the PRNG
   error = yarrowSeed(&yarrowContext, seed, sizeof(seed));
   //Any error to report?
   if(error)
   {
      //Debug message
      TRACE_ERROR("Error: Failed to seed PRNG (%d)\r\n", error);
      //Exit immediately
      return error;
   }

   //Winsock initialization
   ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
   //Any error to report?
   if(ret)
   {
      //Debug message
      TRACE_ERROR("Error: Winsock initialization failed (%d)\r\n", ret);
      //Exit immediately
      return ERROR_FAILURE;
   }

   //Start of exception handling block
   do
   {
      //Debug message
      TRACE_INFO("Loading credentials...\r\n");

      //Load trusted CA certificates
      error = readPemFile(APP_CA_CERT_BUNDLE, &trustedCaList, &trustedCaListLength);
      //Any error to report?
      if(error) break;

      //Load client's certificate
      error = readPemFile(APP_CLIENT_CERT, &clientCert, &clientCertLength);
      //Any error to report?
      if(error) break;

      //Load client's private key
      error = readPemFile(APP_CLIENT_PRIVATE_KEY, &clientPrivateKey, &clientPrivateKeyLength);
      //Any error to report?
      if(error) break;

      //Debug message
      TRACE_INFO("Trying to resolve %s...\r\n", APP_SERVER_NAME);

      //Resolve server name
      host = gethostbyname(APP_SERVER_NAME);
      //Failed to resolve server name?
      if(!host)
      {
         //Debug message
         TRACE_ERROR("Error: Cannot resolve server name (%d)\r\n", WSAGetLastError());
         //Report an error
         error = ERROR_FAILURE;
         //Exit immediately
         break;
      }

      //Open a socket
      sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      //Failed to open socket?
      if(sock < 0)
      {
         //Debug message
         TRACE_ERROR("Error: Cannot open socket (%d)\r\n", WSAGetLastError());
         //Report an error
         error = ERROR_FAILURE;
         //Exit immediately
         break;
      }

      //Destination address
      addr.sin_family = host->h_addrtype;
      memcpy(&addr.sin_addr, host->h_addr, host->h_length);
      addr.sin_port = htons(APP_SERVER_PORT);

      //Connect to the SSL server
      ret = connect(sock, (PSOCKADDR) &addr, sizeof(addr));
      //Connection with server failed?
      if(ret < 0)
      {
         //Debug message
         TRACE_ERROR("Error: Failed to connect (%d)\r\n", WSAGetLastError());
         //Report an error
         error = ERROR_FAILURE;
         //Exit immediately
         break;
      }

      //Initialize SSL/TLS context
      tlsContext = tlsInit();
      //Initialization failed?
      if(!tlsContext)
      {
         //Report an error
         error = ERROR_OUT_OF_MEMORY;
         //Exit immediately
         break;
      }

      //Bind TLS to the relevant socket
      error = tlsSetSocket(tlsContext, sock);
      //Any error to report?
      if(error) break;

      //Select client operation mode
      error = tlsSetConnectionEnd(tlsContext, TLS_CONNECTION_END_CLIENT);
      //Any error to report?
      if(error) break;

      //Set the PRNG algorithm to be used
      error = tlsSetPrng(tlsContext, YARROW_PRNG_ALGO, &yarrowContext);
      //Any error to report?
      if(error) break;

#if (APP_SET_CIPHER_SUITES == ENABLED)
      //Preferred cipher suite list
      error = tlsSetCipherSuites(tlsContext, cipherSuites, arraysize(cipherSuites));
      //Any error to report?
      if(error) break;
#endif

#if (APP_SET_SERVER_NAME == ENABLED)
      //Set the fully qualified domain name of the server
      error = tlsSetServerName(tlsContext, APP_SERVER_NAME);
      //Any error to report?
      if(error) break;
#endif

#if (APP_SET_TRUSTED_CA_LIST == ENABLED)
      //Import the list of trusted CA certificates
      error = tlsSetTrustedCaList(tlsContext, trustedCaList, trustedCaListLength);
      //Any error to report?
      if(error) break;
#endif

#if (APP_SET_CLIENT_CERT == ENABLED)
      //Import the client's certificate
      error = tlsAddCertificate(tlsContext, clientCert,
         clientCertLength, clientPrivateKey, clientPrivateKeyLength);
      //Any error to report?
      if(error) break;
#endif

      //Establish a secure session
      error = tlsConnect(tlsContext);
      //TLS handshake failure?
      if(error) break;

      //Format HTTP request
      sprintf(buffer, "GET %s HTTP/1.0\r\nHost: %s:%u\r\n\r\n",
         APP_REQUEST_URI, APP_SERVER_NAME, APP_SERVER_PORT);

      //Debug message
      TRACE_INFO("\r\n");
      TRACE_INFO("HTTP request:\r\n%s", buffer);

      //Send the request
      error = tlsWrite(tlsContext, buffer, strlen(buffer), 0);
      //Any error to report?
      if(error) break;

      //Debug message
      TRACE_INFO("HTTP response:\r\n");

      //Read the whole response
      while(1)
      {
         //Read data
         error = tlsRead(tlsContext, buffer, sizeof(buffer) - 1, &length, 0);
         //End of stream?
         if(error) break;

         //Properly terminate the string with a NULL character
         buffer[length] = '\0';
         //Debug message
         TRACE_INFO("%s", buffer);
      }

      //Successfull processing
      error = NO_ERROR;

   //End of exception handling block
   } while(0);

   //Terminate TLS session
   tlsFree(tlsContext);

   //Close socket if necessary
   if(sock >= 0)
      closesocket(sock);

   //Free previously allocated resources
   free(trustedCaList);
   free(clientCert);
   free(clientPrivateKey);

   //Release PRNG context
   yarrowRelease(&yarrowContext);

   //Winsock related cleanup
   WSACleanup();
   //Dumps all the memory blocks in the heap when a memory leak has occurred
   _CrtDumpMemoryLeaks();

   //Wait for the user to press a key
   system("pause");

   //Return status code
   return error;
}
/* 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.");
            }
        }
    }
}
Пример #19
0
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;
}
/* good2() reverses the bodies in the if statement */
static void good2()
{
    if(staticTrue)
    {
        {
            HCRYPTPROV hCryptProv;
            HCRYPTHASH hHash;
            FILE *pFile = NULL;
            char password[PASSWORD_INPUT_SIZE];
            UCHAR savedHash[SHA512_SUM_SIZE], calcHash[SHA512_SUM_SIZE];
            DWORD hashSize;
            char *replace;
            size_t i;
            pFile = fopen("password.txt", "r");
            if (pFile == NULL)
            {
                exit(1);
            }
            for (i = 0; i < SHA512_SUM_SIZE; i++)
            {
                ULONG val;
                if (fscanf(pFile, "%02x", &val) != 1)
                {
                    fclose(pFile);
                    exit(1);
                }
                if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */
                {
                    fclose(pFile);
                    exit(1);
                }
                savedHash[i] = (UCHAR)val;
            }
            fclose(pFile);
            if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL)
            {
                exit(1);
            }
            replace = strchr(password, '\r');
            if (replace)
            {
                *replace = '\0';
            }
            replace = strchr(password, '\n');
            if (replace)
            {
                *replace = '\0';
            }
            if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0))
            {
                exit(1);
            }
            /* FIX: use a non-reversible hash (SHA-512) */
            if (!CryptCreateHash(hCryptProv, CALG_SHA_512, 0, 0, &hHash))
            {
                CryptReleaseContext(hCryptProv, 0);
                exit(1);
            }
            /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags,
             * the password hash was not securely transmitted (via one form or another),
             * that may raise flags
             */
            if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0))
            {
                CryptDestroyHash(hHash);
                CryptReleaseContext(hCryptProv, 0);
                exit(1);
            }
            hashSize = SHA512_SUM_SIZE;
            if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0))
            {
                CryptDestroyHash(hHash);
                CryptReleaseContext(hCryptProv, 0);
                exit(1);
            }
            if (memcmp(savedHash, calcHash, SHA512_SUM_SIZE * sizeof(UCHAR)) == 0)
            {
                printLine("Access granted");
            }
            else
            {
                printLine("Access denied");
            }
            if (hHash)
            {
                CryptDestroyHash(hHash);
            }
            if (hCryptProv)
            {
                CryptReleaseContext(hCryptProv, 0);
            }
        }
    }
}
Пример #21
0
PWINECRYPT_CERTSTORE CRYPT_FileNameOpenStoreW(HCRYPTPROV hCryptProv,
 DWORD dwFlags, const void *pvPara)
{
    HCERTSTORE store = 0;
    LPCWSTR fileName = (LPCWSTR)pvPara;
    DWORD access, create;
    HANDLE file;

    TRACE("(%ld, %08x, %s)\n", hCryptProv, dwFlags, debugstr_w(fileName));

    if (!fileName)
    {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return NULL;
    }
    if ((dwFlags & CERT_STORE_READONLY_FLAG) &&
     (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG))
    {
        SetLastError(E_INVALIDARG);
        return NULL;
    }

    access = GENERIC_READ;
    if (dwFlags & CERT_FILE_STORE_COMMIT_ENABLE_FLAG)
        access |= GENERIC_WRITE;
    if (dwFlags & CERT_STORE_CREATE_NEW_FLAG)
        create = CREATE_NEW;
    else if (dwFlags & CERT_STORE_OPEN_EXISTING_FLAG)
        create = OPEN_EXISTING;
    else
        create = OPEN_ALWAYS;
    file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL, create,
     FILE_ATTRIBUTE_NORMAL, NULL);
    if (file != INVALID_HANDLE_VALUE)
    {
        HCERTSTORE memStore = NULL;
        DWORD size = GetFileSize(file, NULL), type = 0;

        /* If the file isn't empty, try to get the type from the file itself */
        if (size)
        {
            DWORD contentType;
            BOOL ret;

            /* Close the file so CryptQueryObject can succeed.. */
            CloseHandle(file);
            ret = CryptQueryObject(CERT_QUERY_OBJECT_FILE, fileName,
             CERT_QUERY_CONTENT_FLAG_CERT |
             CERT_QUERY_CONTENT_FLAG_SERIALIZED_STORE |
             CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED,
             CERT_QUERY_FORMAT_FLAG_BINARY, 0, NULL, &contentType, NULL,
             &memStore, NULL, NULL);
            if (ret)
            {
                if (contentType == CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED)
                    type = CERT_STORE_SAVE_AS_PKCS7;
                else
                    type = CERT_STORE_SAVE_AS_STORE;
                /* and reopen the file. */
                file = CreateFileW(fileName, access, FILE_SHARE_READ, NULL,
                 create, FILE_ATTRIBUTE_NORMAL, NULL);
            }
        }
        else
        {
            static const WCHAR spc[] = { 's','p','c',0 };
            static const WCHAR p7c[] = { 'p','7','c',0 };
            LPCWSTR ext = strrchrW(fileName, '.');

            if (ext)
            {
                ext++;
                if (!lstrcmpiW(ext, spc) || !lstrcmpiW(ext, p7c))
                    type = CERT_STORE_SAVE_AS_PKCS7;
            }
            if (!type)
                type = CERT_STORE_SAVE_AS_STORE;
            memStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
             CERT_STORE_CREATE_NEW_FLAG, NULL);
        }
        if (memStore)
        {
            store = CRYPT_CreateFileStore(dwFlags, memStore, file, type);
            /* File store doesn't need crypto provider, so close it */
            if (hCryptProv && !(dwFlags & CERT_STORE_NO_CRYPT_RELEASE_FLAG))
                CryptReleaseContext(hCryptProv, 0);
        }
    }
    return (PWINECRYPT_CERTSTORE)store;
}
Пример #22
0
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;
}
Пример #23
0
int VerifyDataSignWithHashAlg(const char * userData,  const char * hashAlg, const char * certDataB64, const char * signatureDataB64)
{
	int rv = -1;
	int ulHashAlg = 0;
	HCRYPTHASH hHash = NULL;
	char * pbCert = NULL;
	char * pbSignature = NULL;
	unsigned int ulCert = 0;
	unsigned int ulSignature = 0;
	PCCERT_CONTEXT pCertContext = NULL;  
	HCRYPTPROV hProv = NULL;  
	HCRYPTKEY hPubKey = NULL;  

	{
		ulCert = modp_b64_decode_len(strlen(certDataB64));
		ulSignature = modp_b64_decode_len(strlen(signatureDataB64));

		pbCert = (char *)malloc(ulCert);
		pbSignature =  (char *) malloc(ulSignature);

		if (NULL == pbCert || NULL == pbSignature)
		{
			sprintf(m_errMsg, "%s","memroy less.\n" );
			goto err;
		}

		ulCert = modp_b64_decode(pbCert, certDataB64,strlen(certDataB64));
		ulSignature = modp_b64_decode(pbSignature, signatureDataB64,strlen(signatureDataB64));
	}

	if (0 == strcmp(hashAlg, "MD5"))
	{
		ulHashAlg = CALG_MD5;
	}
	else if (0 == strcmp(hashAlg, "SHA"))
	{
		ulHashAlg = CALG_SHA;
	}
	else if (0 == strcmp(hashAlg, "SHA1"))
	{
		ulHashAlg = CALG_SHA1;
	}
	else if (0 == strcmp(hashAlg, "SHA_256"))
	{
		ulHashAlg = CALG_SHA_256;
	}
	else if (0 == strcmp(hashAlg, "SHA_384"))
	{
		ulHashAlg = CALG_SHA_384;
	}

	pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, (BYTE *)pbCert,ulCert);
	if (!pCertContext)
	{
		sprintf(m_errMsg, "%s","Select Certificate UI failed.\n" );
		goto err;
	}


	//Ò»¡¢»ñµÃÒ»¸öCSP¾ä±ú  
	if(!CryptAcquireContext(  
		&hProv,  
		NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
		NULL,           //CSP_NAME  
		PROV_RSA_FULL,  
		0  
		)) 
	{  
		if(!CryptAcquireContext(  
			&hProv,  
			NULL,           //ÃÜÔ¿ÈÝÆ÷Ãû£¬NULL±íʾʹÓÃĬÈÏÈÝÆ÷  
			NULL,           //CSP_NAME  
			PROV_RSA_FULL,  
			CRYPT_NEWKEYSET //´´½¨ÃÜÔ¿ÈÝÆ÷  
			))
		{
			sprintf(m_errMsg, "%s","CryptAcquireContext fail.\n");
			goto err;
		}
	}  


	if(CryptImportPublicKeyInfo(
		hProv,
		X509_ASN_ENCODING,
		&(pCertContext->pCertInfo->SubjectPublicKeyInfo),
		&hPubKey
		))
	{
		sprintf(m_errMsg,"CryptImportPublicKeyInfo OK. \n");
	}
	else
	{
		sprintf(m_errMsg,"Error CryptImportPublicKeyInfo.\n");
		goto err;
	}

	//if(CryptImportKey(hProv,pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData, pCertContext->pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData, NULL, 0, &hPubKey))
	//{
	//	sprintf(m_errMsg,"CryptImportKey OK. \n");
	//}
	//else
	//{
	//	sprintf(m_errMsg,"Error CryptImportKey.\n");
	//	goto err;
	//}

	if(CryptCreateHash(
		hProv, 
		ulHashAlg, 
		0, 
		0, 
		&hHash)) 
	{
		sprintf(m_errMsg, "%s","An empty hash object has been created. \n");
	}
	else
	{
		sprintf(m_errMsg, "%s","Error during CryptBeginHash!\n");
		goto err;
	}


	//--------------------------------------------------------------------
	//  This code assumes that the handle of a cryptographic context 
	//  has been acquired and that a hash object has been created 
	//  and its handle (hHash) is available.
	if(CryptHashData(
		hHash, 
		(unsigned char *)userData, 
		strlen(userData), 
		0)) 
	{
		sprintf(m_errMsg, "%s","The data buffer has been added to the hash.\n");
	}
	else
	{
		sprintf(m_errMsg, "%s","Error during CryptHashData.\n");
		goto err;
	}

	if(CryptVerifySignature(hHash, (const BYTE *)pbSignature, ulSignature,hPubKey,NULL,0))
	{
		sprintf(m_errMsg,"verify OK.\n");
	}
	else
	{
		sprintf(m_errMsg,"Error during CryptVerifySignature.\n");
		goto err;
	}

	rv = 0;

err:
	if(hHash) 
	{
		CryptDestroyHash(hHash);
	}

	if (pbSignature)
	{
		free(pbSignature);
	}

	if (pbCert)
	{
		free(pbCert);
	}

	if (pCertContext)
	{
		CertFreeCertificateContext(pCertContext);
	}

	if(hProv)  
	{
		CryptReleaseContext(hProv,0);  
	}


	return rv;
}
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);
   }
}
Пример #25
0
string md5file(wchar_t* file){
	DWORD dwStatus = 0;
    BOOL bResult = FALSE;
    HCRYPTPROV hProv = 0;
    HCRYPTHASH hHash = 0;
    HANDLE hFile = NULL;
    BYTE rgbFile[BUFSIZE];
    DWORD cbRead = 0;
    BYTE rgbHash[MD5LEN];
    DWORD cbHash = 0;
    CHAR rgbDigits[] = "0123456789abcdef";
    // Logic to check usage goes here.

    hFile = CreateFile(file,
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_SEQUENTIAL_SCAN,
        NULL);

    if (INVALID_HANDLE_VALUE == hFile)
    {
        dwStatus = GetLastError();
		return "";
    }

    // Get handle to the crypto provider
    if (!CryptAcquireContext(&hProv,
        NULL,
        NULL,
        PROV_RSA_FULL,
        CRYPT_VERIFYCONTEXT))
    {
        dwStatus = GetLastError();
        (hFile);
		CloseHandle(file);
        return "";
    }

    if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash))
    {
        dwStatus = GetLastError();
        CloseHandle(hFile);
        CryptReleaseContext(hProv, 0);
        return "";
    }

    while (bResult = ReadFile(hFile, rgbFile, BUFSIZE, 
        &cbRead, NULL))
    {
        if (0 == cbRead)
        {
            break;
        }

        if (!CryptHashData(hHash, rgbFile, cbRead, 0))
        {
            dwStatus = GetLastError();
            printf("CryptHashData failed: %d\n", dwStatus); 
            CryptReleaseContext(hProv, 0);
            CryptDestroyHash(hHash);
            CloseHandle(hFile);
            return "";
        }
    }

    if (!bResult)
    {
        dwStatus = GetLastError();
        printf("ReadFile failed: %d\n", dwStatus); 
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CloseHandle(hFile);
        return "";
    }

    cbHash = MD5LEN;
	char* rc = "";
    if (CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0))
    {
     	size_t size;
		rc = base64_encode((const unsigned char*)rgbHash, cbHash, &size);
	}

    CryptDestroyHash(hHash);
    CryptReleaseContext(hProv, 0);
    CloseHandle(hFile);
	string s = string(rc);
	delete rc;
	return s;

}
Пример #26
0
void CHasher::Shutdown(){
#if _WIN32
	CryptReleaseContext(m_cryptProv, 0);
	CryptDestroyHash(m_cryptHash);
#endif
}
void CWE328_Reversible_One_Way_Hash__w32_MD2_15_bad()
{
    switch(6)
    {
    case 6:
    {
        HCRYPTPROV hCryptProv;
        HCRYPTHASH hHash;
        FILE *pFile = NULL;
        char password[PASSWORD_INPUT_SIZE];
        UCHAR savedHash[MD2_SUM_SIZE], calcHash[MD2_SUM_SIZE];
        DWORD hashSize;
        char *replace;
        size_t i;
        pFile = fopen("password.txt", "r");
        if (pFile == NULL)
        {
            exit(1);
        }
        for (i = 0; i < MD2_SUM_SIZE; i++)
        {
            ULONG val;
            if (fscanf(pFile, "%02x", &val) != 1)
            {
                fclose(pFile);
                exit(1);
            }
            if (val > 0xff) /* EXPECTED INCIDENTAL: Reliance on data memory layout, we assume char is at least 8 bits */
            {
                fclose(pFile);
                exit(1);
            }
            savedHash[i] = (UCHAR)val;
        }
        if (pFile)
        {
            fclose(pFile);
        }
        if (fgets(password, PASSWORD_INPUT_SIZE, stdin) == NULL)
        {
            exit(1);
        }
        replace = strchr(password, '\r');
        if (replace)
        {
            *replace = '\0';
        }
        replace = strchr(password, '\n');
        if (replace)
        {
            *replace = '\0';
        }
        if (!CryptAcquireContextW(&hCryptProv, 0, 0, PROV_RSA_FULL, 0))
        {
            exit(1);
        }
        /* FLAW: Use a reversible hash (MD2) */
        if (!CryptCreateHash(hCryptProv, CALG_MD2, 0, 0, &hHash))
        {
            CryptReleaseContext(hCryptProv, 0);
            exit(1);
        }
        /* EXPECTED INCIDENTAL: We did not salt the password, that may raise flags,
         * the password hash was not securely transmitted (via one form or another),
         * that may raise flags
         */
        if (!CryptHashData(hHash, (BYTE*)password, strlen(password), 0))
        {
            CryptDestroyHash(hHash);
            CryptReleaseContext(hCryptProv, 0);
            exit(1);
        }
        hashSize = MD2_SUM_SIZE;
        if (!CryptGetHashParam(hHash, HP_HASHVAL, (BYTE*)calcHash, &hashSize, 0))
        {
            CryptDestroyHash(hHash);
            CryptReleaseContext(hCryptProv, 0);
            exit(1);
        }
        if (memcmp(savedHash, calcHash, MD2_SUM_SIZE * sizeof(UCHAR)) == 0)
        {
            printLine("Access granted");
        }
        else
        {
            printLine("Access denied");
        }
        if (hHash)
        {
            CryptDestroyHash(hHash);
        }
        if (hCryptProv)
        {
            CryptReleaseContext(hCryptProv, 0);
        }
    }
    break;
    default:
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
        break;
    }
}
Пример #28
0
/*
 * Requires "ent" be locked.
 */
static void
destroyfilesource(isc_entropyfilesource_t *source) {
	CryptReleaseContext(source->handle, 0);
}
Пример #29
0
/*
 * Do not use Windows tmpfile() function.
 * It will make a temporary file under the root directory
 * and it'll cause permission error if a user who is
 * non-Administrator creates temporary files.
 * Also Windows version of mktemp family including _mktemp_s
 * are not secure.
 */
int
__archive_mktemp(const char *tmpdir)
{
	static const wchar_t *prefix = L"libarchive_";
	static const wchar_t *suffix = L"XXXXXXXXXX";
	static const wchar_t num[] = {
		L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
		L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
		L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
		L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
		L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
		L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
		L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
		L'u', L'v', L'w', L'x', L'y', L'z'
	};
	HCRYPTPROV hProv;
	struct archive_wstring temp_name;
	wchar_t *ws;
	DWORD attr;
	wchar_t *xp, *ep;
	int fd;

	hProv = (HCRYPTPROV)NULL;
	fd = -1;
	ws = NULL;
	archive_string_init(&temp_name);

	/* Get a temporary directory. */
	if (tmpdir == NULL) {
		size_t l;
		wchar_t *tmp;

		l = GetTempPathW(0, NULL);
		if (l == 0) {
			la_dosmaperr(GetLastError());
			goto exit_tmpfile;
		}
		tmp = malloc(l*sizeof(wchar_t));
		if (tmp == NULL) {
			errno = ENOMEM;
			goto exit_tmpfile;
		}
		GetTempPathW((DWORD)l, tmp);
		archive_wstrcpy(&temp_name, tmp);
		free(tmp);
	} else {
		if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
		    strlen(tmpdir)) < 0)
			goto exit_tmpfile;
		if (temp_name.s[temp_name.length-1] != L'/')
			archive_wstrappend_wchar(&temp_name, L'/');
	}

	/* Check if temp_name is a directory. */
	attr = GetFileAttributesW(temp_name.s);
	if (attr == (DWORD)-1) {
		if (GetLastError() != ERROR_FILE_NOT_FOUND) {
			la_dosmaperr(GetLastError());
			goto exit_tmpfile;
		}
		ws = __la_win_permissive_name_w(temp_name.s);
		if (ws == NULL) {
			errno = EINVAL;
			goto exit_tmpfile;
		}
		attr = GetFileAttributesW(ws);
		if (attr == (DWORD)-1) {
			la_dosmaperr(GetLastError());
			goto exit_tmpfile;
		}
	}
	if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
		errno = ENOTDIR;
		goto exit_tmpfile;
	}

	/*
	 * Create a temporary file.
	 */
	archive_wstrcat(&temp_name, prefix);
	archive_wstrcat(&temp_name, suffix);
	ep = temp_name.s + archive_strlen(&temp_name);
	xp = ep - wcslen(suffix);

	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
		CRYPT_VERIFYCONTEXT)) {
		la_dosmaperr(GetLastError());
		goto exit_tmpfile;
	}

	for (;;) {
		wchar_t *p;
		HANDLE h;

		/* Generate a random file name through CryptGenRandom(). */
		p = xp;
		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
		    (BYTE*)p)) {
			la_dosmaperr(GetLastError());
			goto exit_tmpfile;
		}
		for (; p < ep; p++)
			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];

		free(ws);
		ws = __la_win_permissive_name_w(temp_name.s);
		if (ws == NULL) {
			errno = EINVAL;
			goto exit_tmpfile;
		}
		/* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
		 * delete this temporary file immediately when this
		 * file closed. */
		h = CreateFileW(ws,
		    GENERIC_READ | GENERIC_WRITE | DELETE,
		    0,/* Not share */
		    NULL,
		    CREATE_NEW,/* Create a new file only */
		    FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
		    NULL);
		if (h == INVALID_HANDLE_VALUE) {
			/* The same file already exists. retry with
			 * a new filename. */
			if (GetLastError() == ERROR_FILE_EXISTS)
				continue;
			/* Otherwise, fail creation temporary file. */
			la_dosmaperr(GetLastError());
			goto exit_tmpfile;
		}
		fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
		if (fd == -1) {
			CloseHandle(h);
			goto exit_tmpfile;
		} else
			break;/* success! */
	}
exit_tmpfile:
	if (hProv != (HCRYPTPROV)NULL)
		CryptReleaseContext(hProv, 0);
	free(ws);
	archive_wstring_free(&temp_name);
	return (fd);
}
Пример #30
0
int RAND_poll(void)
{
	MEMORYSTATUS m;
	HCRYPTPROV hProvider = 0;
	DWORD w;
	int good = 0;

	/* Determine the OS version we are on so we can turn off things 
	 * that do not work properly.
	 */
        OSVERSIONINFO osverinfo ;
        osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
        GetVersionEx( &osverinfo ) ;

#if defined(OPENSSL_SYS_WINCE)
# if defined(_WIN32_WCE) && _WIN32_WCE>=300
/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
 * in commonly available implementations prior 300... */
	{
	BYTE buf[64];
	/* poll the CryptoAPI PRNG */
	/* The CryptoAPI returns sizeof(buf) bytes of randomness */
	if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
				CRYPT_VERIFYCONTEXT))
		{
		if (CryptGenRandom(hProvider, sizeof(buf), buf))
			RAND_add(buf, sizeof(buf), sizeof(buf));
		CryptReleaseContext(hProvider, 0); 
		}
	}
# endif
#else	/* OPENSSL_SYS_WINCE */
	/*
	 * None of below libraries are present on Windows CE, which is
	 * why we #ifndef the whole section. This also excuses us from
	 * handling the GetProcAddress issue. The trouble is that in
	 * real Win32 API GetProcAddress is available in ANSI flavor
	 * only. In WinCE on the other hand GetProcAddress is a macro
	 * most commonly defined as GetProcAddressW, which accepts
	 * Unicode argument. If we were to call GetProcAddress under
	 * WinCE, I'd recommend to either redefine GetProcAddress as
	 * GetProcAddressA (there seem to be one in common CE spec) or
	 * implement own shim routine, which would accept ANSI argument
	 * and expand it to Unicode.
	 */
	{
	/* load functions dynamically - not available on all systems */
	HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
	HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
	HMODULE user = NULL;
	HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
	CRYPTACQUIRECONTEXTW acquire = NULL;
	CRYPTGENRANDOM gen = NULL;
	CRYPTRELEASECONTEXT release = NULL;
	NETSTATGET netstatget = NULL;
	NETFREE netfree = NULL;
	BYTE buf[64];

	if (netapi)
		{
		netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet");
		netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree");
		}

	if (netstatget && netfree)
		{
		LPBYTE outbuf;
		/* NetStatisticsGet() is a Unicode only function
 		 * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
		 * contains 17 fields.  We treat each field as a source of
		 * one byte of entropy.
                 */

		if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0)
			{
			RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
			netfree(outbuf);
			}
		if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
			{
			RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
			netfree(outbuf);
			}
		}

	if (netapi)
		FreeLibrary(netapi);

        /* It appears like this can cause an exception deep within ADVAPI32.DLL
         * at random times on Windows 2000.  Reported by Jeffrey Altman.  
         * Only use it on NT.
	 */
	/* Wolfgang Marczy <*****@*****.**> reports that
	 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
	 * So we don't use this at all for now. */
#if 0
        if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
		osverinfo.dwMajorVersion < 5)
		{
		/* Read Performance Statistics from NT/2000 registry
		 * The size of the performance data can vary from call
		 * to call so we must guess the size of the buffer to use
		 * and increase its size if we get an ERROR_MORE_DATA
		 * return instead of ERROR_SUCCESS.
		 */
		LONG   rc=ERROR_MORE_DATA;
		char * buf=NULL;
		DWORD bufsz=0;
		DWORD length;

		while (rc == ERROR_MORE_DATA)
			{
			buf = realloc(buf,bufsz+8192);
			if (!buf)
				break;
			bufsz += 8192;

			length = bufsz;
			rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"),
				NULL, NULL, buf, &length);
			}
		if (rc == ERROR_SUCCESS)
			{
                        /* For entropy count assume only least significant
			 * byte of each DWORD is random.
			 */
			RAND_add(&length, sizeof(length), 0);
			RAND_add(buf, length, length / 4.0);

			/* Close the Registry Key to allow Windows to cleanup/close
			 * the open handle
			 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
			 *       when the RegQueryValueEx above is done.  However, if
			 *       it is not explicitly closed, it can cause disk
			 *       partition manipulation problems.
			 */
			RegCloseKey(HKEY_PERFORMANCE_DATA);
			}
		if (buf)
			free(buf);
		}
#endif

	if (advapi)
		{
		/*
		 * If it's available, then it's available in both ANSI
		 * and UNICODE flavors even in Win9x, documentation says.
		 * We favor Unicode...
		 */
		acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
			"CryptAcquireContextW");
		gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
			"CryptGenRandom");
		release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
			"CryptReleaseContext");
		}

	if (acquire && gen && release)
		{
		/* poll the CryptoAPI PRNG */
                /* The CryptoAPI returns sizeof(buf) bytes of randomness */
		if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
			CRYPT_VERIFYCONTEXT))
			{
			if (gen(hProvider, sizeof(buf), buf) != 0)
				{
				RAND_add(buf, sizeof(buf), 0);
				good = 1;
#if 0
				printf("randomness from PROV_RSA_FULL\n");
#endif
				}
			release(hProvider, 0); 
			}
		
		/* poll the Pentium PRG with CryptoAPI */
		if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
			{
			if (gen(hProvider, sizeof(buf), buf) != 0)
				{
				RAND_add(buf, sizeof(buf), sizeof(buf));
				good = 1;
#if 0
				printf("randomness from PROV_INTEL_SEC\n");
#endif
				}
			release(hProvider, 0);
			}
		}

        if (advapi)
		FreeLibrary(advapi);

	if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
	     !OPENSSL_isservice()) &&
	    (user = LoadLibrary(TEXT("USER32.DLL"))))
		{
		GETCURSORINFO cursor;
		GETFOREGROUNDWINDOW win;
		GETQUEUESTATUS queue;

		win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
		cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
		queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");

		if (win)
			{
			/* window handle */
			HWND h = win();
			RAND_add(&h, sizeof(h), 0);
			}
		if (cursor)
			{
			/* unfortunately, its not safe to call GetCursorInfo()
			 * on NT4 even though it exists in SP3 (or SP6) and
			 * higher.
			 */
			if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
				osverinfo.dwMajorVersion < 5)
				cursor = 0;
			}
		if (cursor)
			{
			/* cursor position */
                        /* assume 2 bytes of entropy */
			CURSORINFO ci;
			ci.cbSize = sizeof(CURSORINFO);
			if (cursor(&ci))
				RAND_add(&ci, ci.cbSize, 2);
			}

		if (queue)
			{
			/* message queue status */
                        /* assume 1 byte of entropy */
			w = queue(QS_ALLEVENTS);
			RAND_add(&w, sizeof(w), 1);
			}

		FreeLibrary(user);
		}

	/* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
	 * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
	 * (Win 9x and 2000 only, not available on NT)
	 *
	 * This seeding method was proposed in Peter Gutmann, Software
	 * Generation of Practically Strong Random Numbers,
	 * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
	 * revised version at http://www.cryptoengines.com/~peter/06_random.pdf
	 * (The assignment of entropy estimates below is arbitrary, but based
	 * on Peter's analysis the full poll appears to be safe. Additional
	 * interactive seeding is encouraged.)
	 */

	if (kernel)
		{
		CREATETOOLHELP32SNAPSHOT snap;
		CLOSETOOLHELP32SNAPSHOT close_snap;
		HANDLE handle;

		HEAP32FIRST heap_first;
		HEAP32NEXT heap_next;
		HEAP32LIST heaplist_first, heaplist_next;
		PROCESS32 process_first, process_next;
		THREAD32 thread_first, thread_next;
		MODULE32 module_first, module_next;

		HEAPLIST32 hlist;
		HEAPENTRY32 hentry;
		PROCESSENTRY32 p;
		THREADENTRY32 t;
		MODULEENTRY32 m;
		DWORD starttime = 0;

		snap = (CREATETOOLHELP32SNAPSHOT)
			GetProcAddress(kernel, "CreateToolhelp32Snapshot");
		close_snap = (CLOSETOOLHELP32SNAPSHOT)
			GetProcAddress(kernel, "CloseToolhelp32Snapshot");
		heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
		heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
		heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
		heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
		process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
		process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
		thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
		thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
		module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
		module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");

		if (snap && heap_first && heap_next && heaplist_first &&
			heaplist_next && process_first && process_next &&
			thread_first && thread_next && module_first &&
			module_next && (handle = snap(TH32CS_SNAPALL,0))
			!= INVALID_HANDLE_VALUE)
			{
			/* heap list and heap walking */
                        /* HEAPLIST32 contains 3 fields that will change with
                         * each entry.  Consider each field a source of 1 byte
                         * of entropy.
                         * HEAPENTRY32 contains 5 fields that will change with 
                         * each entry.  Consider each field a source of 1 byte
                         * of entropy.
                         */
			ZeroMemory(&hlist, sizeof(HEAPLIST32));
			hlist.dwSize = sizeof(HEAPLIST32);		
			if (good) starttime = GetTickCount();
#ifdef _MSC_VER
			if (heaplist_first(handle, &hlist))
				{
				/*
				   following discussion on dev ML, exception on WinCE (or other Win
				   platform) is theoretically of unknown origin; prevent infinite
				   loop here when this theoretical case occurs; otherwise cope with
				   the expected (MSDN documented) exception-throwing behaviour of
				   Heap32Next() on WinCE.

				   based on patch in original message by Tanguy Fautré (2009/03/02)
			           Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
			     */
				int ex_cnt_limit = 42; 
				do
					{
					RAND_add(&hlist, hlist.dwSize, 3);
					__try
						{
						ZeroMemory(&hentry, sizeof(HEAPENTRY32));
					hentry.dwSize = sizeof(HEAPENTRY32);
					if (heap_first(&hentry,
						hlist.th32ProcessID,
						hlist.th32HeapID))
						{
						int entrycnt = 80;
						do
							RAND_add(&hentry,
								hentry.dwSize, 5);
						while (heap_next(&hentry)
						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
							&& --entrycnt > 0);
						}
						}
					__except (EXCEPTION_EXECUTE_HANDLER)
						{
							/* ignore access violations when walking the heap list */
							ex_cnt_limit--;
						}
					} while (heaplist_next(handle, &hlist) 
						&& (!good || (GetTickCount()-starttime)<MAXDELAY)
						&& ex_cnt_limit > 0);
				}

#else
			if (heaplist_first(handle, &hlist))
				{
				do
					{
					RAND_add(&hlist, hlist.dwSize, 3);
					hentry.dwSize = sizeof(HEAPENTRY32);
					if (heap_first(&hentry,
						hlist.th32ProcessID,
						hlist.th32HeapID))
						{
						int entrycnt = 80;
						do
							RAND_add(&hentry,
								hentry.dwSize, 5);
						while (heap_next(&hentry)
							&& --entrycnt > 0);
						}
					} while (heaplist_next(handle, &hlist) 
						&& (!good || (GetTickCount()-starttime)<MAXDELAY));
				}
#endif

			/* process walking */
                        /* PROCESSENTRY32 contains 9 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			p.dwSize = sizeof(PROCESSENTRY32);
		
			if (good) starttime = GetTickCount();
			if (process_first(handle, &p))
				do
					RAND_add(&p, p.dwSize, 9);
				while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));

			/* thread walking */
                        /* THREADENTRY32 contains 6 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			t.dwSize = sizeof(THREADENTRY32);
			if (good) starttime = GetTickCount();
			if (thread_first(handle, &t))
				do
					RAND_add(&t, t.dwSize, 6);
				while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));

			/* module walking */
                        /* MODULEENTRY32 contains 9 fields that will change
                         * with each entry.  Consider each field a source of
                         * 1 byte of entropy.
                         */
			m.dwSize = sizeof(MODULEENTRY32);
			if (good) starttime = GetTickCount();
			if (module_first(handle, &m))
				do
					RAND_add(&m, m.dwSize, 9);
				while (module_next(handle, &m)
					       	&& (!good || (GetTickCount()-starttime)<MAXDELAY));
			if (close_snap)
				close_snap(handle);
			else
				CloseHandle(handle);

			}

		FreeLibrary(kernel);
		}