// convert signature to binary
// ensure to free pbSignature after use
void sig2bin(void)
{
    DWORD slen = lstrlen(signature);
    // determine how much space we need
    CryptStringToBinary(signature, slen,
                        CRYPT_STRING_HEX_ANY, NULL, &dwSigLen, NULL, NULL);
    // allocate memory
    pbSignature = xmalloc(dwSigLen);
    // get the binary
    CryptStringToBinary(signature, slen,
                        CRYPT_STRING_HEX_ANY, pbSignature, &dwSigLen, NULL, NULL);
}
Esempio n. 2
0
HRESULT
FromBase64(LPCSTR pszString, BYTE **ppbBinary)
{
    HRESULT hRes=S_OK;
    DWORD cbBinary;
    
    hRes = CryptStringToBinary(pszString, 0, CRYPT_STRING_BASE64, NULL, &cbBinary, NULL, NULL);
    if(FAILED(hRes)){
        dprintf("[sync] failed at CryptStringToBinaryA: %d\n", GetLastError());
        return E_FAIL;
    }

    *ppbBinary = (BYTE *) malloc(cbBinary+1);

    if (ppbBinary==NULL){
        dprintf("[sync] failed at allocate buffer: %d\n", GetLastError());
        return E_FAIL;
    }

    hRes = CryptStringToBinaryA(pszString, 0, CRYPT_STRING_BASE64, *ppbBinary, &cbBinary, NULL, NULL);
    if(FAILED(hRes)){
        dprintf("[sync] failed at CryptStringToBinaryA: %d\n", GetLastError());
        return E_FAIL;
    }

    *((char *)((*ppbBinary)+cbBinary)) = 0;
    
    return hRes;
}
Esempio n. 3
0
bool CCommonUtils::VerifyFile(LPCTSTR lpFileName, LPVOID lpKeyData, DWORD dwKeySize, LPCTSTR lpBase64)
{
    LPVOID lpFileData = NULL;
    DWORD  dwFileSize = 0;
    bool bRet = false;
    HCRYPTPROV hProv = NULL;
    HCRYPTKEY  hKey = NULL;
    HCRYPTHASH hHash = NULL;
    LPVOID lpSignature = NULL;
    DWORD  dwSigSize = 0;

    try
    {
        lpFileData = ReadFileData(lpFileName, dwFileSize);
        if(!lpFileData)
        {
            throw _com_error(E_FAIL);
        }

        if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptImportKey(hProv, (LPBYTE)lpKeyData, dwKeySize, NULL, 0, &hKey))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptHashData(hHash, (LPBYTE)lpFileData, dwFileSize, 0)) 
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptStringToBinary(lpBase64, 0, CRYPT_STRING_BASE64, NULL, &dwSigSize, NULL, NULL))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        lpSignature = malloc(dwSigSize);
        if(!CryptStringToBinary(lpBase64, 0, CRYPT_STRING_BASE64, (LPBYTE)lpSignature, &dwSigSize, NULL, NULL))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        if(!CryptVerifySignature(hHash, (LPBYTE)lpSignature, dwSigSize, hKey, NULL, 0))
        {
            throw _com_error(HRESULT_FROM_WIN32(GetLastError()));
        }

        bRet = true;
    }
    catch(_com_error& err)
    {
        DEBUG_PRINTF(L"Error in verifying file 0x%08X\n", err.Error());
    }

    if(hHash)
    {
        CryptDestroyHash(hHash);
    }

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

    if(lpSignature)
    {
        free(lpSignature);
    }

    if(lpFileData)
    {
        free(lpFileData);
    }

    if(lpKeyData)
    {
        free(lpKeyData);
    }

    return bRet;
}
Esempio n. 4
0
void CEstEIDIEPluginBHO::signWithCNG(BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;
#ifdef WIN_XP
	EstEID_log("WARNING: CNG is not supported for windows XP");
#else
	int methodResult = true;


	#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)
	SECURITY_STATUS secStatus = ERROR_SUCCESS;
	NCRYPT_KEY_HANDLE hKey = NULL;
	DWORD cbSignature = 0;
	NTSTATUS status = ((NTSTATUS)0xC0000001L);
	PBYTE pbSignature = NULL;
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store;
	BOOL must_release_provider;		
		
	int hashHexLength = _bstr_t(hash).length()/2;

	BCRYPT_PKCS1_PADDING_INFO padInfo;
	padInfo.pszAlgId = 0;
	switch(hashHexLength) {
		case BINARY_SHA1_LENGTH:
			padInfo.pszAlgId = NCRYPT_SHA1_ALGORITHM;break; 
		case BINARY_SHA224_LENGTH:
			padInfo.pszAlgId = L"SHA224"; break;
		case BINARY_SHA256_LENGTH :
			padInfo.pszAlgId = NCRYPT_SHA256_ALGORITHM; break;
		case BINARY_SHA512_LENGTH:
			padInfo.pszAlgId = NCRYPT_SHA512_ALGORITHM; break;
		default:
			break; 
	}
	
	try {
		if(!id || !strlen(CW2A(id))) {
			throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
		}
		EstEID_log("signing started, selected certificate id = %s", CW2A(id));	

		if(padInfo.pszAlgId == 0) {
			throw CryptoException(ESTEID_INVALID_HASH_ERROR);
		}


		cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
		if(!cert_store) throw CryptoException();

		while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
			if(certificateMatchesId(certContext, id)) {
				if (!CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, &hKey,
					NULL, &must_release_provider)) {
					throw CryptoException(ESTEID_CRYPTO_API_ERROR);
				}

				BYTE hashBytes[65];
				CryptStringToBinary(hash, hashHexLength*2, CRYPT_STRING_HEX, hashBytes, (DWORD*)&hashHexLength, 0, 0);
				EstEID_log("Number of bytes stored in hashBytes buffer = %u", hashHexLength);
		
				EstEID_log("signing with %s", CW2A(padInfo.pszAlgId));
				if(FAILED(secStatus = NCryptSignHash(hKey, &padInfo, (PBYTE)hashBytes, hashHexLength, NULL, 0, &cbSignature, 0))) {
					throw CryptoException(secStatus);
				}

				pbSignature = (PBYTE)HeapAlloc (GetProcessHeap (), 0, cbSignature);
				if(NULL == pbSignature){
					throw CryptoException(ESTEID_CRYPTO_API_ERROR);
				}
				
				if(FAILED(secStatus = NCryptSignHash(hKey, &padInfo, (PBYTE)hashBytes, hashHexLength, pbSignature, cbSignature, &cbSignature, BCRYPT_PAD_PKCS1))) {
					throw CryptoException(secStatus);
				}

				std::stringstream ss;
				for (DWORD i = 0; i < cbSignature; i++) {
					ss << std::hex << std::setfill('0') << std::setw(2) << (short)pbSignature[i];
				}
				*signature = _bstr_t(ss.str().c_str()).Detach();
			}
		}
	}
	catch(CryptoException e) {
		*signature = _bstr_t("").Detach();
		if(pbSignature) HeapFree(GetProcessHeap(), 0, pbSignature);
		if(hKey) NCryptFreeObject(hKey);
		if(certContext) CertFreeCertificateContext(certContext);
		if(must_release_provider && cert_store) CertCloseStore(cert_store, 0);

		throw CryptoException(e.windowsErrorCode);
	}
	CertFreeCertificateContext(certContext);
	if(must_release_provider) CertCloseStore(cert_store, 0);
#endif

}
Esempio n. 5
0
void CEstEIDIEPluginBHO::signWithCSP(BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;

	HCRYPTPROV cryptoProvider = NULL;
	HCRYPTHASH _hash = NULL ;
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store;
	BOOL must_release_provider;		

	try{
		if(!id || !strlen(CW2A(id))) {
			throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
		}
		EstEID_log("signing started, selected certificate id = %s", CW2A(id));	

#define VALID_HASH_LENGTH 40
		if (_bstr_t(hash).length() != VALID_HASH_LENGTH) {
			throw CryptoException("invalid hash");
		}

		cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
		if(!cert_store) throw CryptoException();
		
		while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
			if(certificateMatchesId(certContext, id)) {
				DWORD key_type = 0;
				if (CryptAcquireCertificatePrivateKey(certContext, CRYPT_ACQUIRE_CACHE_FLAG, 
					NULL, &cryptoProvider, &key_type, &must_release_provider)) {
						BYTE hashBytes[21];
						DWORD hashBytesLength = 20;
						
						CryptStringToBinary(hash, VALID_HASH_LENGTH, CRYPT_STRING_HEX, hashBytes, &hashBytesLength, 0, 0);
						hashBytes[hashBytesLength] = '\0';
						EstEID_log("Number of bytes stored in hashBytes buffer = %u", hashBytesLength);

						CryptoErrorHandler(CryptCreateHash(cryptoProvider, CALG_SHA1, 0, 0, &_hash));
						EstEID_log("CryptCreateHash() set hash object pointer to %p", _hash);  

						CryptoErrorHandler(CryptSetHashParam(_hash, HP_HASHVAL, hashBytes, 0));

						#define SIGNATURE_LENGTH 1024 
						BYTE _signature[SIGNATURE_LENGTH];
						DWORD signatureLength = SIGNATURE_LENGTH;
						INT retCode = CryptSignHash(_hash, AT_SIGNATURE, NULL, 0, _signature, &signatureLength);
						DWORD lastError = GetLastError();
						EstEID_log("CryptSignHash() return code: %u (%s) %x", retCode, retCode ? "SUCCESS" : "FAILURE", lastError);
						if(!retCode) throw CryptoException(lastError);

						CryptDestroyHash(_hash);
						CryptReleaseContext(cryptoProvider, 0);	
						CertFreeCertificateContext(certContext);
						if(must_release_provider) CertCloseStore(cert_store, 0);

						std::stringstream ss;
						for (DWORD i = 0; i < signatureLength; i++) {
							ss << std::hex << std::setfill('0') << std::setw(2) << (short)_signature[signatureLength - i - 1];
						}

						*signature = _bstr_t(ss.str().c_str()).Detach();
				}
				else {
					INT lastError = GetLastError();
					EstEID_log("ERROR: CryptAcquireCertificatePrivateKey() failed, error code = %lXh", GetLastError());
					switch(lastError) {
					case NTE_BAD_PUBLIC_KEY:
						EstEID_log("       error code %lXh: NTE_BAD_PUBLIC_KEY", lastError);
						break;
					case NTE_SILENT_CONTEXT:
						EstEID_log("       error code %lXh: NTE_SILENT_CONTEXT", lastError);
					}
				}				
				break;
			}
		}	
	}
	catch(CryptoException e) {
		*signature = _bstr_t("").Detach();
		if(_hash) CryptDestroyHash(_hash);
		if(cryptoProvider) CryptReleaseContext(cryptoProvider, 0);
		if(certContext) CertFreeCertificateContext(certContext);
		if(must_release_provider && cert_store) CertCloseStore(cert_store, 0);

		throw(CryptoException(e.windowsErrorCode));
	}
}
HRESULT Hex2BstrByte(
				LPWSTR pwszHex,
				BSTR *pbstrByte)
{

	HRESULT hr = S_OK;

	BSTR bstrByte = NULL;

	BYTE *pbData = NULL;
	DWORD cbData = 0;

	if(!pwszHex || !*pwszHex)
	{
		hr = E_INVALIDARG;
		goto error;
	}

	//Get buffer size first.
	if(!CryptStringToBinary(
					pwszHex,
					0,
					CRYPT_STRING_HEX,
					NULL,
					&cbData,
					NULL,
					NULL))
	{
		hr = E_FAIL;
		goto error;
	}

	pbData = (BYTE*)malloc(cbData);
	if(!pbData)
	{
		hr = E_OUTOFMEMORY;
		goto error;
	}

	//pbData points to the memory blob in which
	//the converted hex values are stored.
	if(!CryptStringToBinary(
					pwszHex,
					0,
					CRYPT_STRING_HEX,
					pbData,
					&cbData,
					NULL,
					NULL))
	{
		hr = E_FAIL;
		goto error;
	}
	
	bstrByte = SysAllocStringByteLen((LPCSTR)pbData, cbData);
	if(!bstrByte)
	{
		hr = E_OUTOFMEMORY;
		goto error;
	}

	*pbstrByte = bstrByte;

error:

	free(pbData);

	return hr;
}
Esempio n. 7
0
int	Base64Decode(const char *File)
{
#ifdef WIN32
	FILE *fp = fopen(File, "rb");
	long FileSize;
	DWORD OutFileSize = 0;
	char *FileContent;
	char *ResultContent;

	if( fp == NULL )
	{
		return -1;
	}

	if( fseek(fp, 0L, SEEK_END) != 0 )
	{
		fclose(fp);
		return -2;
	}

	FileSize = ftell(fp);

	if( FileSize < 0 )
	{
		fclose(fp);
		return -3;
	}

	if( fseek(fp, 0L, SEEK_SET) != 0 )
	{
		fclose(fp);
		return -4;
	}

	FileContent = SafeMalloc(FileSize);
	if( FileContent == NULL )
	{
		fclose(fp);
		return -5;
	}

	if( fread(FileContent, 1, FileSize, fp) != FileSize )
	{
		SafeFree(FileContent);
		fclose(fp);
		return -6;
	}

	fclose(fp);

	fp = fopen(File, "wb");
	if( fp == NULL )
	{
		SafeFree(FileContent);
		return -7;
	}

	if( CryptStringToBinary((const BYTE *)FileContent, FileSize, 0x00000001, NULL, &OutFileSize, NULL, NULL) != TRUE )
	{
		SafeFree(FileContent);
		fclose(fp);
		return -8;
	}

	ResultContent = SafeMalloc(OutFileSize);
	if( ResultContent == NULL )
	{
		SafeFree(FileContent);
		fclose(fp);
		return -9;
	}


	if( CryptStringToBinary((const BYTE *)FileContent, FileSize, 0x00000001, ResultContent, &OutFileSize, NULL, NULL) != TRUE )
	{
		SafeFree(ResultContent);
		SafeFree(FileContent);
		fclose(fp);
		return -9;
	}

	fwrite(ResultContent, 1, OutFileSize, fp);

	SafeFree(ResultContent);
	SafeFree(FileContent);
	fclose(fp);
	return 0;

#else /* WIN32 */
	BIO *ub64, *bmem;

	FILE *fp = fopen(File, "rb");
	long FileSize;
	int	OutputSize = 0;
	char *FileContent;
	char *ResultContent;

	if( fp == NULL )
	{
		return -1;
	}

	if( fseek(fp, 0L, SEEK_END) != 0 )
	{
		fclose(fp);
		return -2;
	}

	FileSize = ftell(fp);

	if( FileSize < 0 )
	{
		fclose(fp);
		return -3;
	}

	if( fseek(fp, 0L, SEEK_SET) != 0 )
	{
		fclose(fp);
		return -4;
	}

	FileContent = SafeMalloc(FileSize);
	if( FileContent == NULL )
	{
		fclose(fp);
		return -5;
	}

	if( fread(FileContent, 1, FileSize, fp) != FileSize )
	{
		SafeFree(FileContent);
		fclose(fp);
		return -6;
	}

	fclose(fp);

	ub64 = BIO_new(BIO_f_base64());
	if( ub64 == NULL )
	{
		SafeFree(FileContent);
		return -7;
	}

	bmem = BIO_new_mem_buf(FileContent, FileSize);
	if( ub64 == NULL )
	{
		SafeFree(FileContent);
		return -8;
	}

	fp = fopen(File, "wb");
	if( fp == NULL )
	{
		BIO_free_all(bmem);
		SafeFree(FileContent);
		return -9;
	}

	bmem = BIO_push(ub64, bmem);
	if( bmem== NULL )
	{
		SafeFree(FileContent);
		fclose(fp);
		return -10;
	}

	ResultContent = SafeMalloc(FileSize);
	if( ResultContent == NULL )
	{
		BIO_free_all(bmem);
		SafeFree(FileContent);
		fclose(fp);
		return -11;
	}

	OutputSize = BIO_read(bmem, ResultContent, FileSize);
	if( OutputSize < 1 )
	{
		BIO_free_all(bmem);
		SafeFree(ResultContent);
		SafeFree(FileContent);
		fclose(fp);
		return -12;
	}

	fwrite(ResultContent, 1, OutputSize, fp);

	BIO_free_all(bmem);
	SafeFree(ResultContent);
	SafeFree(FileContent);
	fclose(fp);
	return 0;

#endif /* WIN32 */
}