bool OSSLEVPHashAlgorithm::hashFinal(ByteString& hashedData)
{
	if (!HashAlgorithm::hashFinal(hashedData))
	{
		return false;
	}

	hashedData.resize(EVP_MD_size(getEVPHash()));
	unsigned int outLen = hashedData.size();

	if (!EVP_DigestFinal_ex(curCTX, &hashedData[0], &outLen))
	{
		ERROR_MSG("EVP_DigestFinal failed");

		EVP_MD_CTX_free(curCTX);
		curCTX = NULL;

		return false;
	}

	hashedData.resize(outLen);

	EVP_MD_CTX_free(curCTX);
	curCTX = NULL;

	return true;
}
bool OSSLEVPMacAlgorithm::signFinal(ByteString& signature)
{
	if (!MacAlgorithm::signFinal(signature))
	{
		return false;
	}

	signature.resize(EVP_MD_size(getEVPHash()));
	unsigned int outLen = signature.size();

	if (!HMAC_Final(&curCTX, &signature[0], &outLen))
	{
		ERROR_MSG("HMAC_Final failed");

		HMAC_CTX_cleanup(&curCTX);

		return false;
	}

	signature.resize(outLen);

	HMAC_CTX_cleanup(&curCTX);

	return true;
}
bool BotanSymmetricAlgorithm::decryptUpdate(const ByteString& encryptedData, ByteString& data)
{
	if (!SymmetricAlgorithm::decryptUpdate(encryptedData, data))
	{
		delete cryption;
		cryption = NULL;

		return false;
	}

	// Write data
	try
	{
		if (encryptedData.size() > 0)
			cryption->write(encryptedData.const_byte_str(), encryptedData.size());
	}
	catch (...)
	{
		ERROR_MSG("Failed to write to the decryption token");

		ByteString dummy;
		SymmetricAlgorithm::decryptFinal(dummy);

		delete cryption;
		cryption = NULL;

		return false;
	}

	// Read data
	int bytesRead = 0;
	try
	{
		size_t outLen = cryption->remaining();
		data.resize(outLen);
		if (outLen > 0)
			bytesRead = cryption->read(&data[0], outLen);
	}
	catch (...)
	{
		ERROR_MSG("Failed to decrypt the data");

		ByteString dummy;
		SymmetricAlgorithm::decryptFinal(dummy);

		delete cryption;
		cryption = NULL;

		return false;
	}

	// Resize the output block
	data.resize(bytesRead);
	currentBufferSize -= bytesRead;

	return true;
}
示例#4
0
// Decryption functions
bool OSSLRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
		      ByteString& data, const AsymMech::Type padding)
{
	// Check if the private key is the right type
	if (!privateKey->isOfType(OSSLRSAPrivateKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	// Retrieve the OpenSSL key object
	RSA* rsa = ((OSSLRSAPrivateKey*) privateKey)->getOSSLKey();

	// Check the input size
	if (encryptedData.size() != (size_t) RSA_size(rsa))
	{
		ERROR_MSG("Invalid amount of input data supplied for RSA decryption");

		return false;
	}

	// Determine the OpenSSL padding algorithm
	int osslPadding = 0;

	switch (padding)
	{
		case AsymMech::RSA_PKCS:
			osslPadding = RSA_PKCS1_PADDING;
			break;
		case AsymMech::RSA_PKCS_OAEP:
			osslPadding = RSA_PKCS1_OAEP_PADDING;
			break;
		case AsymMech::RSA:
			osslPadding = RSA_NO_PADDING;
			break;
		default:
			ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);
			return false;
	}

	// Perform the RSA operation
	data.resize(RSA_size(rsa));

	int decSize = RSA_private_decrypt(encryptedData.size(), (unsigned char*) encryptedData.const_byte_str(), &data[0], rsa, osslPadding);

	if (decSize == -1)
	{
		ERROR_MSG("RSA private key decryption failed (0x%08X)", ERR_get_error());

		return false;
	}

	data.resize(decSize);

	return true;
}
示例#5
0
// Set from Botan representation
void BotanEDPublicKey::setFromBotan(const Botan::Public_Key* inEDKEY)
{
	Botan::OID oid;
	std::vector<uint8_t> pub;

	for (;;)
	{
		const Botan::Curve25519_PublicKey* x25519 = dynamic_cast<const Botan::Curve25519_PublicKey*>(inEDKEY);
		if (x25519) {
			oid = x25519_oid;
			pub = x25519->public_value();
			break;
		}
		const Botan::Ed25519_PublicKey* ed25519 = dynamic_cast<const Botan::Ed25519_PublicKey*>(inEDKEY);
		if (ed25519) {
			oid = ed25519_oid;
			pub = ed25519->get_public_key();
			break;
		}
		return;
	}
	ByteString inEC = BotanUtil::oid2ByteString(oid);
	setEC(inEC);
	ByteString inA;
	inA.resize(pub.size());
	memcpy(&inA[0], &pub[0], pub.size());
	setA(DERUTIL::raw2Octet(inA));
}
示例#6
0
// Encode into PKCS#8 DER
ByteString OSSLECPrivateKey::PKCS8Encode()
{
	ByteString der;
	if (eckey == NULL) return der;
	EVP_PKEY* pkey = EVP_PKEY_new();
	if (pkey == NULL) return der;
	if (!EVP_PKEY_set1_EC_KEY(pkey, eckey))
	{
		EVP_PKEY_free(pkey);
		return der;
	}
	PKCS8_PRIV_KEY_INFO* p8inf = EVP_PKEY2PKCS8(pkey);
	EVP_PKEY_free(pkey);
	if (p8inf == NULL) return der;
	int len = i2d_PKCS8_PRIV_KEY_INFO(p8inf, NULL);
	if (len < 0)
	{
		PKCS8_PRIV_KEY_INFO_free(p8inf);
		return der;
	}
	der.resize(len);
	unsigned char* priv = &der[0];
	int len2 = i2d_PKCS8_PRIV_KEY_INFO(p8inf, &priv);
	PKCS8_PRIV_KEY_INFO_free(p8inf);
	if (len2 != len) der.wipe();
	return der;
}
示例#7
0
bool BotanDSA::signFinal(ByteString& signature)
{
	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	// Perform the signature operation
	Botan::SecureVector<Botan::byte> signResult;
	try
	{
		BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
		signResult = signer->signature(*rng->getRNG());
	}
	catch (...)
	{
		ERROR_MSG("Could not sign the data");

		delete signer;
		signer = NULL;

		return false;
	}

	// Return the result
	signature.resize(signResult.size());
	memcpy(&signature[0], signResult.begin(), signResult.size());

	delete signer;
	signer = NULL;

	return true;
}
// Encode into PKCS#8 DER
ByteString BotanDSAPrivateKey::PKCS8Encode()
{
	ByteString der;
	createBotanKey();
	if (dsa == NULL) return der;
	const Botan::SecureVector<Botan::byte> ber = Botan::PKCS8::BER_encode(*dsa);
	der.resize(ber.size());
	memcpy(&der[0], ber.begin(), ber.size());
	return der;
}
// Signing functions
bool OSSLECDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign, ByteString& signature, const std::string mechanism)
{
	std::string lowerMechanism;
	lowerMechanism.resize(mechanism.size());
	std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower);

	if (lowerMechanism.compare("ecdsa"))
	{
		ERROR_MSG("Invalid mechanism supplied (%s)", mechanism.c_str());
		return false;
	}

	// Check if the private key is the right type
	if (!privateKey->isOfType(OSSLECPrivateKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	OSSLECPrivateKey* pk = (OSSLECPrivateKey*) privateKey;
	EC_KEY* eckey = pk->getOSSLKey();

	if (eckey == NULL)
	{
		ERROR_MSG("Could not get the OpenSSL private key");

		return false;
	}

	// Use the OpenSSL implementation and not any engine
	ECDSA_set_method(eckey, ECDSA_OpenSSL());

	// Perform the signature operation
	size_t len = pk->getOrderLength();
	if (len == 0)
	{
		ERROR_MSG("Could not get the order length");
		return false;
	}
	signature.resize(2 * len);
	memset(&signature[0], 0, 2 * len);
	ECDSA_SIG *sig = ECDSA_do_sign(dataToSign.const_byte_str(), dataToSign.size(), eckey);
	if (sig == NULL)
	{
		ERROR_MSG("ECDSA sign failed (0x%08X)", ERR_get_error());
		return false;
	}
	// Store the 2 values with padding
	BN_bn2bin(sig->r, &signature[len - BN_num_bytes(sig->r)]);
	BN_bn2bin(sig->s, &signature[2 * len - BN_num_bytes(sig->s)]);
	ECDSA_SIG_free(sig);
	return true;
}
示例#10
0
bool BotanDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
{
	// Check parameters
	if ((ppSymmetricKey == NULL) ||
	    (publicKey == NULL) ||
	    (privateKey == NULL))
	{
		return false;
	}

	// Get keys
	Botan::DH_PublicKey* pub = ((BotanDHPublicKey*) publicKey)->getBotanKey();
	Botan::DH_PrivateKey* priv = ((BotanDHPrivateKey*) privateKey)->getBotanKey();
	if (pub == NULL || priv == NULL)
	{
		ERROR_MSG("Failed to get Botan DH keys");

		return false;
	}

	// Derive the secret
	Botan::SymmetricKey sk;
	try
	{
		Botan::PK_Key_Agreement ka(*priv, "Raw");
		sk = ka.derive_key(0, pub->public_value());
	}
	catch (...)
	{
		ERROR_MSG("Botan DH key agreement failed");

		return false;
	}

	ByteString secret;
	secret.resize(sk.length());
	memcpy(&secret[0], sk.begin(), sk.length());

	*ppSymmetricKey = new SymmetricKey(sk.length() * 8);
	if (*ppSymmetricKey == NULL)
	{
		ERROR_MSG("Can't create DH secret");

		return false;
	}
	if (!(*ppSymmetricKey)->setKeyBits(secret))
	{
		delete *ppSymmetricKey;
		*ppSymmetricKey = NULL;
		return false;
	}

	return true;
}
示例#11
0
// Convert an OpenSSL BIGNUM to a ByteString
ByteString OSSL::bn2ByteString(const BIGNUM* bn)
{
	ByteString rv;

	if (bn != NULL)
	{
		rv.resize(BN_num_bytes(bn));
		BN_bn2bin(bn, &rv[0]);
	}

	return rv;
}
示例#12
0
bool OSSLGOST::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLGOSTPrivateKey* pk = (OSSLGOSTPrivateKey*) currentPrivateKey;

	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	// Perform the signature operation
	EVP_PKEY* pkey = pk->getOSSLKey();
	unsigned int outLen;

	if (pkey == NULL)
	{
		ERROR_MSG("Could not get the OpenSSL private key");

		EVP_MD_CTX_cleanup(&curCTX);

		return false;
	}

	signature.resize(EVP_PKEY_size(pkey));
	outLen = signature.size();
	if (!EVP_SignFinal(&curCTX, &signature[0], &outLen, pkey))
	{
		ERROR_MSG("EVP_SignFinal failed");

		EVP_MD_CTX_cleanup(&curCTX);

		return false;
	}

	signature.resize(outLen);

	EVP_MD_CTX_cleanup(&curCTX);

	return true;
}
示例#13
0
// Convert an OpenSSL EC GROUP to a ByteString
ByteString OSSL::grp2ByteString(const EC_GROUP* grp)
{
	ByteString rv;

	if (grp != NULL)
	{
		rv.resize(i2d_ECPKParameters(grp, NULL));
		unsigned char *p = &rv[0];
		i2d_ECPKParameters(grp, &p);
	}

	return rv;
}
示例#14
0
// Convert an OpenSSL EC POINT in the given EC GROUP to a ByteString
ByteString OSSL::pt2ByteString(const EC_POINT* pt, const EC_GROUP* grp)
{
	ByteString raw;

	if (pt == NULL || grp == NULL)
		return raw;

	size_t len = EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
	raw.resize(len);
	EC_POINT_point2oct(grp, pt, POINT_CONVERSION_UNCOMPRESSED, &raw[0], len, NULL);

	return DERUTIL::raw2Octet(raw);
}
示例#15
0
// Convert an OpenSSL NID to a ByteString
ByteString OSSL::oid2ByteString(int nid)
{
	ByteString rv;

	if (nid != NID_undef)
	{
		rv.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
		unsigned char *p = &rv[0];
		i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
	}

	return rv;
}
示例#16
0
// Set from OpenSSL representation
void OSSLGOSTPrivateKey::setFromOSSL(const EVP_PKEY* pkey)
{
	const EC_KEY* eckey = (const EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	const BIGNUM* priv = EC_KEY_get0_private_key(eckey);
	setD(OSSL::bn2ByteString(priv));

	ByteString inEC;
	int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
	inEC.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
	unsigned char *p = &inEC[0];
	i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
	setEC(inEC);
}
bool BotanSymmetricAlgorithm::decryptFinal(ByteString& data)
{
	if (!SymmetricAlgorithm::decryptFinal(data))
	{
		delete cryption;
		cryption = NULL;

		return false;
	}

	// Read data
	int bytesRead = 0;
	try
	{
		cryption->end_msg();
		size_t outLen = cryption->remaining();
		data.resize(outLen);
		if (outLen > 0)
			bytesRead = cryption->read(&data[0], outLen);
	}
	catch (...)
	{
		ERROR_MSG("Failed to decrypt the data");

		delete cryption;
		cryption = NULL;

		return false;
	}

	// Clean up
	delete cryption;
	cryption = NULL;

	// Resize the output block
	data.resize(bytesRead);

	return true;
}
示例#18
0
// Set from OpenSSL representation
void OSSLGOSTPublicKey::setFromOSSL(const EVP_PKEY* pkey)
{
	ByteString der;
	int len = i2d_PUBKEY((EVP_PKEY*) pkey, NULL);
	if (len != 37 + 64)
	{
		ERROR_MSG("bad GOST public key encoding length %d", len);
		return;
	}
	der.resize(len);
	unsigned char *p = &der[0];
	i2d_PUBKEY((EVP_PKEY*) pkey, &p);
	// can check: der is prefix + 64 bytes
	setQ(der.substr(37));

	ByteString inEC;
	const EC_KEY* eckey = (const EC_KEY*) EVP_PKEY_get0((EVP_PKEY*) pkey);
	int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey));
	inEC.resize(i2d_ASN1_OBJECT(OBJ_nid2obj(nid), NULL));
	p = &inEC[0];
	i2d_ASN1_OBJECT(OBJ_nid2obj(nid), &p);
	setEC(inEC);
}
示例#19
0
// Encode into PKCS#8 DER
ByteString BotanRSAPrivateKey::PKCS8Encode()
{
	ByteString der;
	createBotanKey();
	if (rsa == NULL) return der;
#if BOTAN_VERSION_MINOR == 11
	const Botan::secure_vector<Botan::byte> ber = Botan::PKCS8::BER_encode(*rsa);
#else
	const Botan::SecureVector<Botan::byte> ber = Botan::PKCS8::BER_encode(*rsa);
#endif
	der.resize(ber.size());
	memcpy(&der[0], &ber[0], ber.size());
	return der;
}
示例#20
0
bool OSAttribute::peekValue(ByteString& value) const
{
	switch (attributeType)
	{
		case BOOL:
			value.resize(sizeof(boolValue));
			memcpy(&value[0], &boolValue, value.size());
			return true;

		case ULONG:
			value.resize(sizeof(ulongValue));
			memcpy(&value[0], &ulongValue, value.size());
			return true;

		case BYTESTR:
			value.resize(byteStrValue.size());
			memcpy(&value[0], byteStrValue.const_byte_str(), value.size());
			return true;

		default:
			return false;
	}
}
示例#21
0
// Encode into PKCS#8 DER
ByteString BotanGOSTPrivateKey::PKCS8Encode()
{
	ByteString der;
	createBotanKey();
	if (eckey == NULL) return der;
	// Force EC_DOMPAR_ENC_OID
	const size_t PKCS8_VERSION = 0;
#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
	const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
	const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
	const Botan::secure_vector<Botan::byte> ber =
		Botan::DER_Encoder()
		.start_cons(Botan::SEQUENCE)
		    .encode(PKCS8_VERSION)
		    .encode(alg_id)
		    .encode(eckey->private_key_bits(), Botan::OCTET_STRING)
		.end_cons()
	    .get_contents();
#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
	const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
	const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
	const Botan::secure_vector<Botan::byte> ber =
		Botan::DER_Encoder()
		.start_cons(Botan::SEQUENCE)
		    .encode(PKCS8_VERSION)
		    .encode(alg_id)
		    .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
		.end_cons()
	    .get_contents();
#else
	const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
	const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
	const Botan::SecureVector<Botan::byte> ber =
		Botan::DER_Encoder()
		.start_cons(Botan::SEQUENCE)
		.encode(PKCS8_VERSION)
		    .encode(alg_id)
		    .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
		.end_cons()
	    .get_contents();
#endif
	der.resize(ber.size());
	memcpy(&der[0], &ber[0], ber.size());
        return der;
}
示例#22
0
void OSSLGOSTPublicKey::setQ(const ByteString& inQ)
{
	GOSTPublicKey::setQ(inQ);

	if (inQ.size() != 64)
	{
		ERROR_MSG("bad GOST public key size %zu", q.size());
		return;
	}

	ByteString der;
	der.resize(37 + 64);
	memcpy(&der[0], gost_prefix, 37);
	memcpy(&der[37], inQ.const_byte_str(), 64);
	const unsigned char *p = &der[0];
	if (d2i_PUBKEY(&pkey, &p, (long) der.size()) == NULL)
		ERROR_MSG("d2i_PUBKEY failed");
}
示例#23
0
bool OSSLDH::deriveKey(SymmetricKey **ppSymmetricKey, PublicKey* publicKey, PrivateKey* privateKey)
{
	// Check parameters
	if ((ppSymmetricKey == NULL) ||
	    (publicKey == NULL) ||
	    (privateKey == NULL))
	{
		return false;
	}

	// Get keys
	DH *pub = ((OSSLDHPublicKey *)publicKey)->getOSSLKey();
	DH *priv = ((OSSLDHPrivateKey *)privateKey)->getOSSLKey();
	if (pub == NULL || pub->pub_key == NULL || priv == NULL)
	{
		ERROR_MSG("Failed to get OpenSSL DH keys");

		return false;
	}

	// Derive the secret
	ByteString secret;
	secret.resize(DH_size(priv));;

	if (DH_compute_key(&secret[0], pub->pub_key, priv) <= 0)
	{
		ERROR_MSG("DH key derivation failed (0x%08X)", ERR_get_error());

		return false;
	}

	*ppSymmetricKey = new SymmetricKey;
	if (*ppSymmetricKey == NULL)
		return false;
	if (!(*ppSymmetricKey)->setKeyBits(secret))
	{
		delete *ppSymmetricKey;
		*ppSymmetricKey = NULL;
		return false;
	}

	return true;
}
示例#24
0
bool BotanGOST::signFinal(ByteString& signature)
{
	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	// Perform the signature operation
#if BOTAN_VERSION_MINOR == 11
	std::vector<Botan::byte> signResult;
#else
	Botan::SecureVector<Botan::byte> signResult;
#endif
	try
	{
		BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
		signResult = signer->signature(*rng->getRNG());
	}
	catch (...)
	{
		ERROR_MSG("Could not sign the data");

		delete signer;
		signer = NULL;

		return false;
	}

	// Return the result
	signature.resize(signResult.size());
#if BOTAN_VERSION_MINOR == 11
	memcpy(&signature[0], signResult.data(), signResult.size());
#else
	memcpy(&signature[0], signResult.begin(), signResult.size());
#endif

	delete signer;
	signer = NULL;

	return true;
}
示例#25
0
// Signing functions
bool OSSLDSA::sign(PrivateKey* privateKey, const ByteString& dataToSign,
		   ByteString& signature, const AsymMech::Type mechanism,
		   const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	if (mechanism == AsymMech::DSA)
	{
		// Separate implementation for DSA signing without hash computation

		// Check if the private key is the right type
		if (!privateKey->isOfType(OSSLDSAPrivateKey::type))
		{
			ERROR_MSG("Invalid key type supplied");

			return false;
		}

		OSSLDSAPrivateKey* pk = (OSSLDSAPrivateKey*) privateKey;
		DSA* dsa = pk->getOSSLKey();

		// Perform the signature operation
		unsigned int sigLen = pk->getOutputLength();
		signature.resize(sigLen);
		memset(&signature[0], 0, sigLen);
		int dLen = dataToSign.size();
		DSA_SIG* sig = DSA_do_sign(dataToSign.const_byte_str(), dLen, dsa);
		if (sig == NULL)
			return false;
		// Store the 2 values with padding
		BN_bn2bin(sig->r, &signature[sigLen / 2 - BN_num_bytes(sig->r)]);
		BN_bn2bin(sig->s, &signature[sigLen - BN_num_bytes(sig->s)]);
		DSA_SIG_free(sig);
		return true;
	}
	else
	{
		// Call default implementation
		return AsymmetricAlgorithm::sign(privateKey, dataToSign, signature, mechanism, param, paramLen);
	}
}
// Encode into PKCS#8 DER
ByteString BotanECDHPrivateKey::PKCS8Encode()
{
	ByteString der;
	createBotanKey();
	if (eckey == NULL) return der;
	const size_t PKCS8_VERSION = 0;
	// No OID for ECDH
	const Botan::OID oid("1.2.840.10045.2.1");
	// Force EC_DOMPAR_ENC_OID
	const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
	const Botan::AlgorithmIdentifier alg_id(oid, parameters);
	const Botan::SecureVector<Botan::byte> ber =
		Botan::DER_Encoder()
		.start_cons(Botan::SEQUENCE)
		    .encode(PKCS8_VERSION)
		    .encode(alg_id)
		    .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
		.end_cons()
	    .get_contents();
	der.resize(ber.size());
	memcpy(&der[0], ber.begin(), ber.size());
	return der;
}
示例#27
0
bool OSSLDSA::signFinal(ByteString& signature)
{
	// Save necessary state before calling super class signFinal
	OSSLDSAPrivateKey* pk = (OSSLDSAPrivateKey*) currentPrivateKey;

	if (!AsymmetricAlgorithm::signFinal(signature))
	{
		return false;
	}

	ByteString hash;

	bool bFirstResult = pCurrentHash->hashFinal(hash);

	delete pCurrentHash;
	pCurrentHash = NULL;

	if (!bFirstResult)
	{
		return false;
	}

	DSA* dsa = pk->getOSSLKey();

	// Perform the signature operation
	unsigned int sigLen = pk->getOutputLength();
	signature.resize(sigLen);
	memset(&signature[0], 0, sigLen);
	DSA_SIG* sig = DSA_do_sign(&hash[0], hash.size(), dsa);
	if (sig == NULL)
		return false;
	// Store the 2 values with padding
	BN_bn2bin(sig->r, &signature[sigLen / 2 - BN_num_bytes(sig->r)]);
	BN_bn2bin(sig->s, &signature[sigLen - BN_num_bytes(sig->s)]);
	DSA_SIG_free(sig);
	return true;
}
bool OSSLEVPMacAlgorithm::verifyFinal(ByteString& signature)
{
	if (!MacAlgorithm::verifyFinal(signature))
	{
		return false;
	}

	ByteString macResult;
	unsigned int outLen = EVP_MD_size(getEVPHash());
	macResult.resize(outLen);

	if (!HMAC_Final(&curCTX, &macResult[0], &outLen))
	{
		ERROR_MSG("HMAC_Final failed");

		HMAC_CTX_cleanup(&curCTX);

		return false;
	}

	HMAC_CTX_cleanup(&curCTX);

	return macResult == signature;
}
示例#29
0
static bool decodeAttributeMap(std::map<CK_ATTRIBUTE_TYPE,OSAttribute>& map, const unsigned char *binary, size_t size)
{
	for (size_t pos = 0; pos < size; )
	{
		// finished?
		if (pos == size) break;

		CK_ATTRIBUTE_TYPE attrType;
		if (pos + sizeof(attrType) > size)
		{
			goto overrun;
		}
		memcpy(&attrType, binary + pos, sizeof(attrType));
		pos += sizeof(attrType);

		AttributeKind attrKind;
		if (pos + sizeof(AttributeKind) > size)
		{
			goto overrun;
		}
		memcpy(&attrKind, binary + pos, sizeof(attrKind));
		pos += sizeof(attrKind);

		// Verify using attributeKind()?

		switch (attrKind)
		{
			case akBoolean:
			{
				bool value;
				if (pos + sizeof(value) > size)
				{
					goto overrun;
				}
				memcpy(&value, binary + pos, sizeof(value));
				pos += sizeof(value);

				map.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attrType, value));
			}
			break;

			case akInteger:
			{
				unsigned long value;
				if (pos + sizeof(value) > size)
				{
					goto overrun;
				}
				memcpy(&value, binary + pos, sizeof(value));
				pos += sizeof(value);

				map.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attrType, value));
			}
			break;

			case akBinary:
			{
				ByteString value;
				unsigned long len;
				if (pos + sizeof(len) > size)
				{
					goto overrun;
				}
				memcpy(&len, binary + pos, sizeof(len));
				pos += sizeof(len);

				if (pos + len > size)
				{
					goto overrun;
				}
				value.resize(len);
				memcpy(&value[0], binary + pos, len);
				pos += len;

				map.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attrType, value));
			}
			break;

			case akMechSet:
			{
				unsigned long len;
				if (pos + sizeof(len) > size)
				{
					goto overrun;
				}
				memcpy(&len, binary + pos, sizeof(len));
				pos += sizeof(len);

				if (pos + len > size)
				{
					goto overrun;
				}

				std::set<CK_MECHANISM_TYPE> value;
				if (!decodeMechanismTypeSet(value, binary + pos, len)) {
					return false;
				}
				pos += len;

				map.insert(std::pair<CK_ATTRIBUTE_TYPE,OSAttribute> (attrType, value));
			}
			break;

			default:
			ERROR_MSG("unsupported attribute kind in attribute map");

			return false;
		}
	}

	return true;

overrun:
	ERROR_MSG("attribute map template overrun");

	return false;
}
示例#30
0
// Decryption functions
bool BotanRSA::decrypt(PrivateKey* privateKey, const ByteString& encryptedData,
		       ByteString& data, const AsymMech::Type padding)
{
	// Check if the private key is the right type
	if (!privateKey->isOfType(BotanRSAPrivateKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	std::string eme;

	switch (padding)
	{
		case AsymMech::RSA_PKCS:
			eme = "PKCS1v15";
			break;
		case AsymMech::RSA_PKCS_OAEP:
			eme = "EME1(SHA-160)";
			break;
		case AsymMech::RSA:
			eme = "Raw";
			break;
		default:
			ERROR_MSG("Invalid padding mechanism supplied (%i)", padding);

			return false;
	}

	BotanRSAPrivateKey* pk = (BotanRSAPrivateKey*) privateKey;
	Botan::RSA_PrivateKey* botanKey = pk->getBotanKey();

	if (!botanKey)
	{
		ERROR_MSG("Could not get the Botan private key");

		return false;
	}

	Botan::PK_Decryptor_EME* decryptor = NULL;
	try
	{
		decryptor = new Botan::PK_Decryptor_EME(*botanKey, eme);
	}
	catch (...)
	{
		ERROR_MSG("Could not create the decryptor token");

		return false;
	}

	// Perform the decryption operation
#if BOTAN_VERSION_MINOR == 11
	Botan::secure_vector<Botan::byte> decResult;
#else
	Botan::SecureVector<Botan::byte> decResult;
#endif
	try
	{
		decResult = decryptor->decrypt(encryptedData.const_byte_str(), encryptedData.size());
	}
	catch (...)
	{
		ERROR_MSG("Could not decrypt the data");

		delete decryptor;

		return false;
	}

	// Return the result
	if (padding == AsymMech::RSA)
	{
		// We compensate that Botan removes leading zeros
		int modSize = pk->getN().size();
		int decSize = decResult.size();
		data.resize(modSize);
#if BOTAN_VERSION_MINOR == 11
		memcpy(&data[0] + modSize - decSize, decResult.data(), decSize);
#else
		memcpy(&data[0] + modSize - decSize, decResult.begin(), decSize);
#endif
	}
	else
	{
		data.resize(decResult.size());
#if BOTAN_VERSION_MINOR == 11
		memcpy(&data[0], decResult.data(), decResult.size());
#else
		memcpy(&data[0], decResult.begin(), decResult.size());
#endif
	}

	delete decryptor;

	return true;
}