Example #1
0
Blob
PrivateKey::decrypt(const Blob& cipher) const
{
    if (!key)
        throw CryptoException("Can't decrypt data without private key !");

    unsigned key_len = 0;
    int err = gnutls_privkey_get_pk_algorithm(key, &key_len);
    if (err < 0)
        throw CryptoException("Can't read public key length !");
    if (err != GNUTLS_PK_RSA)
        throw CryptoException("Must be an RSA key");

    unsigned cypher_block_sz = key_len / 8;
    if (cipher.size() % cypher_block_sz)
        throw CryptoException("Unexpected cipher length");

    Blob ret;
    for (auto cb = cipher.cbegin(), ce = cipher.cend(); cb < ce; cb += cypher_block_sz) {
        const gnutls_datum_t dat {(uint8_t*)(&(*cb)), cypher_block_sz};
        gnutls_datum_t out;
        int err = gnutls_privkey_decrypt_data(key, 0, &dat, &out);
        if (err != GNUTLS_E_SUCCESS)
            throw DhtException(std::string("Can't decrypt data: ") + gnutls_strerror(err));
        ret.insert(ret.end(), out.data, out.data+out.size);
        gnutls_free(out.data);
    }
    return ret;
}
void CryptoManager::generateCertificate() throw(CryptoException) {
#ifdef _WIN32
	// Generate certificate using OpenSSL
	if(SETTING(TLS_PRIVATE_KEY_FILE).empty()) {
		throw CryptoException("No private key file chosen");
	}
	if(SETTING(TLS_CERTIFICATE_FILE).empty()) {
		throw CryptoException("No certificate file chosen");
	}
	wstring cmd = L"openssl.exe genrsa -out \"" + Text::utf8ToWide(SETTING(TLS_PRIVATE_KEY_FILE)) + L"\" 2048";
	PROCESS_INFORMATION pi = { 0 };
	STARTUPINFO si = { 0 };
	si.cb = sizeof(si);

	if(!CreateProcess(0, const_cast<wchar_t*>(cmd.c_str()), 0, 0, FALSE, 0, 0, 0, &si, &pi)) {
		throw CryptoException(Util::translateError(::GetLastError()));
	}
	WaitForSingleObject(pi.hProcess, INFINITE);
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);

	cmd = L"openssl.exe req -x509 -new -batch -days 3650 -key \"" + Text::utf8ToWide(SETTING(TLS_PRIVATE_KEY_FILE)) +
		L"\" -out \"" + Text::utf8ToWide(SETTING(TLS_CERTIFICATE_FILE)) + L"\" -subj \"/CN=" +
		Text::utf8ToWide(ClientManager::getInstance()->getMyCID().toBase32()) + L"\"";

	if(!CreateProcess(0, const_cast<wchar_t*>(cmd.c_str()), 0, 0, FALSE, 0, 0, 0, &si, &pi)) {
		throw CryptoException(Util::translateError(::GetLastError()));
	}

	WaitForSingleObject(pi.hProcess, INFINITE);
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
#endif
}
Example #3
0
PrivateKey::PrivateKey(gnutls_x509_privkey_t k) : x509_key(k)
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
    gnutls_privkey_init(&key);
    if (gnutls_privkey_import_x509(key, k, GNUTLS_PRIVKEY_IMPORT_COPY) != GNUTLS_E_SUCCESS) {
        key = nullptr;
        throw CryptoException("Can't load generic private key !");
    }
}
Example #4
0
Blob
PrivateKey::sign(const Blob& data) const
{
    if (!key)
        throw CryptoException("Can't sign data: no private key set !");
    gnutls_datum_t sig;
    const gnutls_datum_t dat {(unsigned char*)data.data(), (unsigned)data.size()};
    if (gnutls_privkey_sign_data(key, GNUTLS_DIG_SHA512, 0, &dat, &sig) != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't sign data !");
    Blob ret(sig.data, sig.data+sig.size);
    gnutls_free(sig.data);
    return ret;
}
Example #5
0
PrivateKey
PrivateKey::generate(unsigned key_length)
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
    gnutls_x509_privkey_t key;
    if (gnutls_x509_privkey_init(&key) != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize private key.");
    int err = gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, key_length, 0);
    if (err != GNUTLS_E_SUCCESS) {
        gnutls_x509_privkey_deinit(key);
        throw CryptoException(std::string("Can't generate RSA key pair: ") + gnutls_strerror(err));
    }
    return PrivateKey{key};
}
void CEstEIDCertificate::readFromCertContext() {
	LOG_LOCATION;
	PCCERT_CONTEXT pCertContext = NULL;
	HCERTSTORE hCertStore = NULL;
	CRYPTUI_SELECTCERTIFICATE_STRUCT sel = {sizeof(sel)};
	int counter = 0;

	hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_READONLY_FLAG, L"MY");
	if(!hCertStore){
		throw CryptoException();
	}
	sel.pvCallbackData = &counter;
	sel.pFilterCallback = filter_proc;
	sel.rghDisplayStores = &hCertStore;
	sel.cDisplayStores = 1;
	
#ifdef _SEB_BUILD	
	EstEID_log("SEB build");
	PCCERT_CONTEXT pCertContextForEnumeration = NULL;
	int certificatesCount = 0;
	while(pCertContextForEnumeration = CertEnumCertificatesInStore(hCertStore, pCertContextForEnumeration)) {
		if(isValidForSigning(pCertContextForEnumeration)) {
			certificatesCount++;	
			pCertContext = pCertContextForEnumeration;
		}
	}

	EstEID_log("Certificates count %i", certificatesCount);

	if(certificatesCount != 1) {
		pCertContext = CryptUIDlgSelectCertificate(&sel);
	}
#else
	pCertContext = CryptUIDlgSelectCertificate(&sel);
#endif
	if(!pCertContext) {
		EstEID_log("User didn't select sertificate");
		throw CryptoException(ESTEID_USER_CANCEL);
	}

	loadCertContexts(pCertContext);
	if(pCertContext){
		CertFreeCertificateContext(pCertContext);
	}
	if(hCertStore) {
		CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
	}
}
void CEstEIDIEPluginBHO::CryptoErrorHandler(BOOL result) {
	EstEID_log("");
	if (!result) {		
		EstEID_log("Throwing CryptoException");
		throw CryptoException();
	}
}
Example #8
0
void
Certificate::unpack(Blob::const_iterator& begin, Blob::const_iterator& end)
{
    if (cert) {
        gnutls_x509_crt_deinit(cert);
        cert = nullptr;
    }
    gnutls_x509_crt_t* cert_list;
    unsigned cert_num;
    const gnutls_datum_t crt_dt {(uint8_t*)&(*begin), (unsigned)(end-begin)};
    int err = gnutls_x509_crt_list_import2(&cert_list, &cert_num, &crt_dt, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
    if (err != GNUTLS_E_SUCCESS)
        err = gnutls_x509_crt_list_import2(&cert_list, &cert_num, &crt_dt, GNUTLS_X509_FMT_DER, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED);
    if (err != GNUTLS_E_SUCCESS || cert_num == 0) {
        cert = nullptr;
        throw CryptoException(std::string("Could not read certificate - ") + gnutls_strerror(err));
    }

    cert = cert_list[0];
    Certificate* crt = this;
    size_t i = 1;
    while (crt and i < cert_num) {
        crt->issuer = std::make_shared<Certificate>(cert_list[i++]);
        crt = crt->issuer.get();
    }
    gnutls_free(cert_list);
}
Example #9
0
void AES::SetIV(ref<ByteArray> iv)
{
	if (iv->Count() == 16)
		m_iv = iv;
	else
		cdec_throw(CryptoException(EC_CRYPT_InvalidIVSize));
}
Example #10
0
void AES::SetKey(ref<ByteArray> key)
{
	int len = key->Count();
	if (len == 16 || len == 24 || len == 32)
		m_key = key;
	else
		cdec_throw(CryptoException(EC_CRYPT_InvalidKeySize));
}
void CEstEIDIEPluginBHO::signWithPKCS11(HINSTANCE hInst, BSTR id, BSTR hash, BSTR *signature) {
	LOG_LOCATION;
	char *_signature = NULL;
	EstEID_errorCode = 0;

	CK_SLOT_ID slotId;	
	if(id == NULL) {
		throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
	}
	if(EstEID_getSlotId(CW2A(id), &slotId)){
		if(EstEID_isPinPad(slotId)) {
#ifdef WIN_XP
			_signature = EstEID_sign(strdup(CW2A(id)), strdup(CW2A(hash)), pinPromptData);
			if(pinPadDlg != NULL) {
				pinPadDlg->EndDialog(ESTEID_NO_ERROR);
			}
#endif
		}
		else {
			CEstEidPin2Dlg *pin2Dlg = new CEstEidPin2Dlg();
			pin2Dlg->SetCertId(id);
			pin2Dlg->SetHash(hash);
			INT result = pin2Dlg->DoModal();
			if(!result) {
				throw CryptoException(ESTEID_USER_CANCEL);
			}
			_signature = pin2Dlg->GetSignature();
		}
		if(_signature == NULL) {
			throw CryptoException(EstEID_errorCode == 0 ? ESTEID_PKCS11_ERROR : EstEID_errorCode);
		}
	}
	else {
		throw CryptoException(ESTEID_CERT_NOT_FOUND_ERROR);
	}
	if (_signature) {
		*signature = _bstr_t(_signature).Detach();
		free(_signature);
	}
	else {
		//TODO:error handling
		//EstEID_log("EstEID_error=%s", EstEID_error);
		throw CryptoException(ESTEID_UNKNOWN_ERROR);
	}
}
Example #12
0
InfoHash
Certificate::getId() const
{
    if (not cert)
        return {};
    InfoHash id;
    size_t sz = id.size();
    if (gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
        throw CryptoException("Can't get certificate public key ID.");
    return id;
}
Example #13
0
void
PublicKey::pack(Blob& b) const
{
    std::vector<uint8_t> tmp(2048);
    size_t sz = tmp.size();
    int err = gnutls_pubkey_export(pk, GNUTLS_X509_FMT_DER, tmp.data(), &sz);
    if (err != GNUTLS_E_SUCCESS)
        throw CryptoException(std::string("Could not export public key: ") + gnutls_strerror(err));
    tmp.resize(sz);
    serialize<Blob>(tmp, b);
}
void CEstEIDCertificate::readFromCertContext() {
	PCCERT_CONTEXT certContext = NULL;
	HCERTSTORE cert_store = NULL;

	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();
	}

	if(!CertFindCertificateInStore(cert_store, X509_ASN_ENCODING  | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, NULL)) {
		CertCloseStore(cert_store, CERT_CLOSE_STORE_FORCE_FLAG);
		throw CryptoException();
	}
	
	while(certContext = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING  | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext)) {
		BYTE keyUsage;
		CertGetIntendedKeyUsage(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, certContext->pCertInfo, &keyUsage, 1);
		if (keyUsage & CERT_NON_REPUDIATION_KEY_USAGE) {
			this->certificates.push_back(CertDuplicateCertificateContext(certContext));
		}	
	}
	
	//PCCERT_CONTEXT ct = CryptUIDlgSelectCertificateFromStore(cert_store, NULL, L"TIITEL", L"Vali cert:", NULL, 0, 0);
	//loadCertContexts(ct);
	CCertificateSelectionDlg *dlg = new CCertificateSelectionDlg();
	dlg->setCertificate(this->certificates);
	INT_PTR selectedItem = dlg->DoModal();
	EstEID_log("selected item index = %i", selectedItem);
	
	if(selectedItem == -1) {
		throw CryptoException(ESTEID_USER_CANCEL);
	}
	loadCertContexts(this->certificates[selectedItem]);

	if(certContext){
		CertFreeCertificateContext(certContext);
	}
	if(cert_store) {
		CertCloseStore(cert_store, CERT_CLOSE_STORE_FORCE_FLAG);
	}
}
Example #15
0
void AES::SetMode(CipherMode mode)
{
	switch (mode)
	{
	case Cipher_ECB:
	case Cipher_CBC:
		m_mode = mode;
		break;
	default:
		cdec_throw(CryptoException(EC_CRYPT_InvalidCipherMode));
	}
}
void CryptoManager::decodeBZ2(const u_int8_t* is, size_t sz, string& os) throw (CryptoException) {
	bz_stream bs = { 0 };

	if(BZ2_bzDecompressInit(&bs, 0, 0) != BZ_OK)
		throw(CryptoException(STRING(DECOMPRESSION_ERROR)));

	// We assume that the files aren't compressed more than 2:1...if they are it'll work anyway,
	// but we'll have to do multiple passes...
	size_t bufsize = 2*sz;
	AutoArray<char> buf(bufsize);
	
	bs.avail_in = sz;
	bs.avail_out = bufsize;
	bs.next_in = (char*)(const_cast<u_int8_t*>(is));
	bs.next_out = buf;

	int err;

	os.clear();
	
	while((err = BZ2_bzDecompress(&bs)) == BZ_OK) { 
		if (bs.avail_in == 0 && bs.avail_out > 0) { // error: BZ_UNEXPECTED_EOF 
			BZ2_bzDecompressEnd(&bs); 
			throw CryptoException(STRING(DECOMPRESSION_ERROR)); 
		} 
		os.append(buf, bufsize-bs.avail_out); 
		bs.avail_out = bufsize; 
		bs.next_out = buf; 
	} 

	if(err == BZ_STREAM_END)
		os.append(buf, bufsize-bs.avail_out);
	
	BZ2_bzDecompressEnd(&bs);

	if(err < 0) {
		// This was a real error
		throw CryptoException(STRING(DECOMPRESSION_ERROR));	
	}
}
Example #17
0
PrivateKey::PrivateKey(const Blob& import)
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
    int err = gnutls_x509_privkey_init(&x509_key);
    if (err != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize private key !");

    const gnutls_datum_t dt {(uint8_t*)import.data(), static_cast<unsigned>(import.size())};
    err = gnutls_x509_privkey_import2(x509_key, &dt, GNUTLS_X509_FMT_PEM, nullptr, GNUTLS_PKCS_PLAIN);
    if (err != GNUTLS_E_SUCCESS)
        err = gnutls_x509_privkey_import2(x509_key, &dt, GNUTLS_X509_FMT_DER, nullptr, GNUTLS_PKCS_PLAIN);
    if (err != GNUTLS_E_SUCCESS) {
        gnutls_x509_privkey_deinit(x509_key);
        throw CryptoException("Can't load private key !");
    }

    gnutls_privkey_init(&key);
    if (gnutls_privkey_import_x509(key, x509_key, GNUTLS_PRIVKEY_IMPORT_COPY) != GNUTLS_E_SUCCESS) {
        throw CryptoException("Can't load generic private key !");
    }
}
Example #18
0
void
PublicKey::unpack(Blob::const_iterator& begin, Blob::const_iterator& end)
{
    Blob tmp = deserialize<Blob>(begin, end);
    if (pk)
        gnutls_pubkey_deinit(pk);
    gnutls_pubkey_init(&pk);
    const gnutls_datum_t dat {(uint8_t*)tmp.data(), (unsigned)tmp.size()};
    int err = gnutls_pubkey_import(pk, &dat, GNUTLS_X509_FMT_PEM);
    if (err != GNUTLS_E_SUCCESS)
        err = gnutls_pubkey_import(pk, &dat, GNUTLS_X509_FMT_DER);
    if (err != GNUTLS_E_SUCCESS)
        throw CryptoException(std::string("Could not read public key: ") + gnutls_strerror(err));
}
Example #19
0
Blob
PublicKey::encrypt(const Blob& data) const
{
    if (!pk)
        throw CryptoException("Can't read public key !");

    unsigned key_len = 0;
    int err = gnutls_pubkey_get_pk_algorithm(pk, &key_len);
    if (err < 0)
        throw CryptoException("Can't read public key length !");
    if (err != GNUTLS_PK_RSA)
        throw CryptoException("Must be an RSA key");

    unsigned max_block_sz = key_len / 8 - 11;
    unsigned cypher_block_sz = key_len / 8;
    unsigned block_num = data.empty() ? 1 : 1 + (data.size() - 1) / max_block_sz;

    Blob ret;
    auto eb = data.cbegin();
    auto ee = data.cend();
    for (unsigned i=0; i<block_num; i++) {
        auto blk_sz = std::min<unsigned>(ee - eb, max_block_sz);
        const gnutls_datum_t dat {(uint8_t*)&(*eb), blk_sz};
        gnutls_datum_t encrypted;
        err = gnutls_pubkey_encrypt_data(pk, 0, &dat, &encrypted);
        if (err != GNUTLS_E_SUCCESS)
            throw CryptoException(std::string("Can't encrypt data: ") + gnutls_strerror(err));
        if (encrypted.size != cypher_block_sz)
            throw CryptoException("Unexpected cypherblock size");
        ret.insert(ret.end(), encrypted.data, encrypted.data+encrypted.size);
        eb += blk_sz;
        gnutls_free(encrypted.data);
    }

    return ret;
}
Example #20
0
AesTransform::AesTransform(CAesAlg* alg, CipherMode mode, ref<ByteArray> iv, bool fEncoder)
{
	m_alg = alg;
	m_mode = mode;

	if (mode != Cipher_ECB)
	{
		if (iv == NULL)
			cdec_throw(CryptoException(EC_CRYPT_InvalidIVSize));
		memcpy(m_iv, iv->GetBuffer().ptr(), 16);
	}

	if (mode == Cipher_ECB)
		m_e = fEncoder ? &AesTransform::f_EncodeECB : &AesTransform::f_DecodeECB;
	else if (mode == Cipher_CBC)
		m_e = fEncoder ? &AesTransform::f_EncodeCBC : &AesTransform::f_DecodeCBC;
}
Example #21
0
void Sec256DsaEx::ParsePubKey(RCSpan cbuf) {
	if (!secp256k1_ec_pubkey_parse(g_sec256Ctx, &m_pubkey, cbuf.data(), cbuf.size()))
		throw CryptoException(make_error_code(ExtErr::Crypto), "Invalid PubKey");
}
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

}
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));
	}
}
void CryptoManager::decodeHuffman(const u_int8_t* is, string& os, const size_t len) throw(CryptoException) {
//	BitInputStream bis;
	int pos = 0;

	if(len < 11 || is[pos] != 'H' || is[pos+1] != 'E' || !((is[pos+2] == '3') || (is[pos+2] == '0'))) {
		throw CryptoException(STRING(DECOMPRESSION_ERROR));
	}
	pos+=5;

	int size;
	size = *(int*)&is[pos];

	pos+=4;

	dcdebug("Size: %d\n", size);
	
	unsigned short treeSize;
	treeSize = *(unsigned short*)&is[pos];

	pos+=2;

	if(len < (size_t)(11 + treeSize * 2)) 
		throw CryptoException(STRING(DECOMPRESSION_ERROR));
	Leaf** leaves = new Leaf*[treeSize];

	int i;
	for(i=0; i<treeSize; i++) {
		int chr =  is[pos++];
		int bits = is[pos++];
		leaves[i] = new Leaf(chr, bits);
	}

	BitInputStream bis(is, pos, len);

	DecNode* root = new DecNode();

	for(i=0; i<treeSize; i++) {
		DecNode* node = root;
		for(int j=0; j<leaves[i]->len; j++) {
			try {
				if(bis.get()) {
					if(node->right == NULL)
						node->right = new DecNode();

					node = node->right;
				} else {
					if(node->left == NULL)
						node->left = new DecNode();

					node = node->left;
				}
			} catch(const BitStreamException&) {
				throw CryptoException(STRING(DECOMPRESSION_ERROR));
			}
		}
		node->chr = leaves[i]->chr;
	}
	
	bis.skipToByte();
	
	// We know the size, so no need to use strange STL stuff...
	AutoArray<char> buf(size+1);

	pos = 0;
	for(i=0; i<size; i++) {
		DecNode* node = root;
		while(node->chr == -1) {
			try {
				if(bis.get()) {
					node = node->right;
				} else {
					node = node->left;
				}
			} catch(const BitStreamException&) {
				throw CryptoException(STRING(DECOMPRESSION_ERROR));
			}

			if(node == NULL) {
				for(i=0; i<treeSize; i++) {
					delete leaves[i];
				}
				
				delete[] leaves;
				delete root;

				dcdebug("Bad node found!!!\n");
				throw CryptoException(STRING(DECOMPRESSION_ERROR));
			}
		}
		buf[pos++] = (u_int8_t)node->chr;
	}
	buf[pos] = 0;
	os.assign(buf, size);

	for(i=0; i<treeSize; i++) {
		delete leaves[i];
	}
	
	delete[] leaves;
	delete root;
}
Example #25
0
void Sec256Signature::Parse(RCSpan cbuf) {
	if (!secp256k1_ecdsa_sig_parse(&m_r, &m_s, cbuf.data(), cbuf.size()))
		throw CryptoException(make_error_code(ExtErr::Crypto), "Invalid Signature");
}
Example #26
0
PrivateKey::PrivateKey()
{
    if (gnutls_global_init() != GNUTLS_E_SUCCESS)
        throw CryptoException("Can't initialize GnuTLS.");
}
Example #27
0
void Sec256SignatureEx::Parse(RCSpan cbuf) {
	if (!ecdsa_signature_parse_der_lax(g_sec256Ctx, &m_sig, cbuf.data(), cbuf.size()))
		throw CryptoException(make_error_code(ExtErr::Crypto), "Invalid Signature");
	secp256k1_ecdsa_signature_normalize(g_sec256Ctx, &m_sig, &m_sig);
}
void CEstEIDCertificate::CryptoErrorHandler(BOOL result) {
	if (!result) {
		throw CryptoException();
	}
}