示例#1
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;
}
// Wrap/Unwrap keys
bool BotanAES::wrapKey(const SymmetricKey* key, const SymWrap::Type mode, const ByteString& in, ByteString& out)
{
	// Check key bit length; AES only supports 128, 192 or 256 bit keys
	if ((key->getBitLen() != 128) &&
	    (key->getBitLen() != 192) &&
	    (key->getBitLen() != 256))
	{
		ERROR_MSG("Invalid AES key length (%d bits)", key->getBitLen());

		return false;
	}

	// Determine the wrapping mode
	if (mode == SymWrap::AES_KEYWRAP)
	{
		// RFC 3394 AES key wrap
		if (in.size() < 16)
		{
			ERROR_MSG("key data to wrap too small");

			return false;
		}
		if ((in.size() % 8) != 0)
		{
			ERROR_MSG("key data to wrap not aligned");

			return false;
		}

#if BOTAN_VERSION_MINOR == 11
		Botan::secure_vector<Botan::byte> data(in.size());
		memcpy(data.data(), in.const_byte_str(), in.size());
		Botan::secure_vector<Botan::byte> wrapped;
#else
		Botan::MemoryVector<Botan::byte> data(in.size());
		memcpy(data.begin(), in.const_byte_str(), in.size());
		Botan::SecureVector<Botan::byte> wrapped;
#endif
		Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
		Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
		try
		{
			wrapped = Botan::rfc3394_keywrap(data, botanKey, af);
		}
		catch (...)
		{
			ERROR_MSG("AES key wrap failed");

			return false;
		}
		out.resize(wrapped.size());
#if BOTAN_VERSION_MINOR == 11
		memcpy(&out[0], wrapped.data(), out.size());
#else
		memcpy(&out[0], wrapped.begin(), out.size());
#endif

		return  true;
	}
#ifdef HAVE_AES_KEY_WRAP_PAD
	else if (mode == SymWrap::AES_KEYWRAP_PAD)
	{
		// RFC 5649 AES key wrap with pad
#if BOTAN_VERSION_MINOR == 11
		Botan::secure_vector<Botan::byte> data(in.size());
		memcpy(data.data(), in.const_byte_str(), in.size());
		Botan::secure_vector<Botan::byte> wrapped;
#else
		Botan::MemoryVector<Botan::byte> data(in.size());
		memcpy(data.begin(), in.const_byte_str(), in.size());
		Botan::SecureVector<Botan::byte> wrapped;
#endif
		Botan::SymmetricKey botanKey = Botan::SymmetricKey(key->getKeyBits().const_byte_str(), key->getKeyBits().size());
		Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory();
		try
		{
			wrapped = Botan::rfc5649_keywrap(data, botanKey, af);
		}
		catch (...)
		{
			ERROR_MSG("AES key wrap failed");

			return false;
		}
		out.resize(wrapped.size());
#if BOTAN_VERSION_MINOR == 11
		memcpy(&out[0], wrapped.data(), out.size());
#else
		memcpy(&out[0], wrapped.begin(), out.size());
#endif

		return  true;
	}
#endif
	else
	{
		ERROR_MSG("unknown AES key wrap mode %i", mode);

		return false;
	}
}