Example #1
0
bool BotanRSA::reconstructPublicKey(PublicKey** ppPublicKey, ByteString& serialisedData)
{
	// Check input
	if ((ppPublicKey == NULL) ||
	    (serialisedData.size() == 0))
	{
		return false;
	}

	BotanRSAPublicKey* pub = new BotanRSAPublicKey();

	if (!pub->deserialise(serialisedData))
	{
		delete pub;

		return false;
	}

	*ppPublicKey = pub;

	return true;
}
Example #2
0
// Encryption functions
bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data,
		       ByteString& encryptedData, const AsymMech::Type padding)
{
	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::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;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		return false;
	}

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

		return false;
	}

	// Perform the encryption operation
#if BOTAN_VERSION_MINOR == 11
	std::vector<Botan::byte> encResult;
#else
	Botan::SecureVector<Botan::byte> encResult;
#endif
	try
	{
		BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
		encResult = encryptor->encrypt(data.const_byte_str(), data.size(), *rng->getRNG());
	}
	catch (...)
	{
		ERROR_MSG("Could not encrypt the data");

		delete encryptor;

		return false;
	}

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

	delete encryptor;

	return true;
}
Example #3
0
bool BotanRSA::verifyInit(PublicKey* publicKey, const AsymMech::Type mechanism,
			  const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism, param, paramLen))
	{
		return false;
	}

	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	std::string emsa;
	std::ostringstream request;
	size_t sLen;

	switch (mechanism)
	{
		case AsymMech::RSA_MD5_PKCS:
			emsa = "EMSA3(MD5)";
			break;
		case AsymMech::RSA_SHA1_PKCS:
			emsa = "EMSA3(SHA-160)";
			break;
		case AsymMech::RSA_SHA224_PKCS:
			emsa = "EMSA3(SHA-224)";
			break;
		case AsymMech::RSA_SHA256_PKCS:
			emsa = "EMSA3(SHA-256)";
			break;
		case AsymMech::RSA_SHA384_PKCS:
			emsa = "EMSA3(SHA-384)";
			break;
		case AsymMech::RSA_SHA512_PKCS:
			emsa = "EMSA3(SHA-512)";
			break;
		case AsymMech::RSA_SHA1_PKCS_PSS:
			if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA1 ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA1)
			{
				ERROR_MSG("Invalid parameters");
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
			if (sLen > ((publicKey->getBitLength()+6)/8-2-20))
			{
				ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
					  (unsigned long)sLen, publicKey->getBitLength());
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			request << "EMSA4(SHA-160,MGF1," << sLen << ")";
			emsa = request.str();
			break;
		case AsymMech::RSA_SHA224_PKCS_PSS:
			if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA224 ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA224)
			{
				ERROR_MSG("Invalid parameters");
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
			if (sLen > ((publicKey->getBitLength()+6)/8-2-28))
			{
				ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
					  (unsigned long)sLen, publicKey->getBitLength());
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			request << "EMSA4(SHA-224,MGF1," << sLen << ")";
			emsa = request.str();
			break;
		case AsymMech::RSA_SHA256_PKCS_PSS:
			if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA256 ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA256)
			{
				ERROR_MSG("Invalid parameters");
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
			if (sLen > ((publicKey->getBitLength()+6)/8-2-32))
			{
				ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
					  (unsigned long)sLen, publicKey->getBitLength());
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			request << "EMSA4(SHA-256,MGF1," << sLen << ")";
			emsa = request.str();
			break;
		case AsymMech::RSA_SHA384_PKCS_PSS:
			if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA384 ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA384)
			{
				ERROR_MSG("Invalid parameters");
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
			if (sLen > ((publicKey->getBitLength()+6)/8-2-48))
			{
				ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
					  (unsigned long)sLen, publicKey->getBitLength());
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			request << "EMSA4(SHA-384,MGF1," << sLen << ")";
			emsa = request.str();
			break;
		case AsymMech::RSA_SHA512_PKCS_PSS:
			if (param == NULL || paramLen != sizeof(RSA_PKCS_PSS_PARAMS) ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->hashAlg != HashAlgo::SHA512 ||
			    ((RSA_PKCS_PSS_PARAMS*) param)->mgf != AsymRSAMGF::MGF1_SHA512)
			{
				ERROR_MSG("Invalid parameters");
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			sLen = ((RSA_PKCS_PSS_PARAMS*) param)->sLen;
			if (sLen > ((publicKey->getBitLength()+6)/8-2-64))
			{
				ERROR_MSG("sLen (%lu) is too large for current key size (%lu)",
					  (unsigned long)sLen, publicKey->getBitLength());
				ByteString dummy;
				AsymmetricAlgorithm::verifyFinal(dummy);
				return false;
			}
			request << "EMSA4(SHA-512,MGF1," << sLen << ")";
			emsa = request.str();
			break;
		case AsymMech::RSA_SSL:
			emsa = "EMSA3(Parallel(MD5,SHA-160))";
			break;
		default:
			ERROR_MSG("Invalid mechanism supplied (%i)", mechanism);

			ByteString dummy;
			AsymmetricAlgorithm::verifyFinal(dummy);

			return false;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) currentPublicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	try
	{
		verifier = new Botan::PK_Verifier(*botanKey, emsa);
	}
	catch (...)
	{
		ERROR_MSG("Could not create the verifier token");

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	return true;
}
Example #4
0
// Verification functions
bool BotanRSA::verify(PublicKey* publicKey, const ByteString& originalData,
		      const ByteString& signature, const AsymMech::Type mechanism,
		      const void* param /* = NULL */, const size_t paramLen /* = 0 */)
{
	std::string emsa = "";

	switch (mechanism)
	{
		case AsymMech::RSA:
			emsa = "Raw";
			break;
		case AsymMech::RSA_PKCS:
			emsa = "EMSA3(Raw)";
			break;
		default:
			// Call the generic function
			return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism, param, paramLen);
	}

	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		return false;
	}

	try
	{
		verifier = new Botan::PK_Verifier(*botanKey, emsa);
	}
	catch (...)
	{
		ERROR_MSG("Could not create the verifier token");

		return false;
	}

	// Perform the verify operation
	bool verResult;
	try
	{
		verResult = verifier->verify_message(originalData.const_byte_str(),
							originalData.size(),
							signature.const_byte_str(),
							signature.size());
	}
	catch (...)
	{
		ERROR_MSG("Could not check the signature");

		delete verifier;
		verifier = NULL;

		return false;
	}

	delete verifier;
	verifier = NULL;

	return verResult;
}
Example #5
0
// Encryption functions
bool BotanRSA::encrypt(PublicKey* publicKey, const ByteString& data, ByteString& encryptedData, const std::string padding)
{
	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	std::string lowerPadding;
	lowerPadding.resize(padding.size());
	std::transform(padding.begin(), padding.end(), lowerPadding.begin(), tolower);
	std::string eme;

	if (!lowerPadding.compare("rsa-pkcs"))
	{
		eme = "PKCS1v15";
	}
	else if (!lowerPadding.compare("rsa-pkcs-oaep"))
	{
		eme = "EME1(SHA-160)";
	}
	else if (!lowerPadding.compare("rsa-raw"))
	{
		eme = "Raw";
	}
	else
	{
		ERROR_MSG("Invalid padding mechanism supplied (%s)", padding.c_str());

		return false;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		return false;
	}

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

		return false;
	}

	// Perform the encryption operation
	Botan::SecureVector<Botan::byte> encResult;
	try
	{
		BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
		encResult = encryptor->encrypt(data.const_byte_str(), data.size(), *rng->getRNG());
	}
	catch (...)
	{
		ERROR_MSG("Could not encrypt the data");

		delete encryptor;

		return false;
	}

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

	delete encryptor;

	return true;
}
Example #6
0
bool BotanRSA::verifyInit(PublicKey* publicKey, const std::string mechanism)
{
	if (!AsymmetricAlgorithm::verifyInit(publicKey, mechanism))
	{
		return false;
	}

	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	std::string lowerMechanism;
	lowerMechanism.resize(mechanism.size());
	std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower);
	std::string emsa;

	if (!lowerMechanism.compare("rsa-md5-pkcs"))
	{
		emsa = "EMSA3(MD5)";
	}
	else if (!lowerMechanism.compare("rsa-sha1-pkcs"))
	{
		emsa = "EMSA3(SHA-160)";
	}
	else if (!lowerMechanism.compare("rsa-sha224-pkcs"))
	{
		emsa = "EMSA3(SHA-224)";
	}
	else if (!lowerMechanism.compare("rsa-sha256-pkcs"))
	{
		emsa = "EMSA3(SHA-256)";
	}
	else if (!lowerMechanism.compare("rsa-sha384-pkcs"))
	{
		emsa = "EMSA3(SHA-384)";
	}
	else if (!lowerMechanism.compare("rsa-sha512-pkcs"))
	{
		emsa = "EMSA3(SHA-512)";
	}
	else if (!lowerMechanism.compare("rsa-ssl"))
	{
		emsa = "EMSA3(Parallel(MD5,SHA-160))";
	}
	else
	{
		ERROR_MSG("Invalid mechanism supplied (%s)", mechanism.c_str());

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) currentPublicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	try
	{
		verifier = new Botan::PK_Verifier(*botanKey, emsa);
	}
	catch (...)
	{
		ERROR_MSG("Could not create the verifier token");

		ByteString dummy;
		AsymmetricAlgorithm::verifyFinal(dummy);

		return false;
	}

	return true;
}
Example #7
0
// Verification functions
bool BotanRSA::verify(PublicKey* publicKey, const ByteString& originalData, const ByteString& signature, const std::string mechanism)
{
	std::string lowerMechanism;
	lowerMechanism.resize(mechanism.size());
	std::transform(mechanism.begin(), mechanism.end(), lowerMechanism.begin(), tolower);
	std::string emsa = "";

	if (!lowerMechanism.compare("rsa-pkcs"))
	{
		emsa = "EMSA3(Raw)";
	}
	else if (!lowerMechanism.compare("rsa-raw"))
	{
		emsa = "Raw";
	}
	else
	{
		// Call the generic function
		return AsymmetricAlgorithm::verify(publicKey, originalData, signature, mechanism);
	}

	// Check if the public key is the right type
	if (!publicKey->isOfType(BotanRSAPublicKey::type))
	{
		ERROR_MSG("Invalid key type supplied");

		return false;
	}

	BotanRSAPublicKey* pk = (BotanRSAPublicKey*) publicKey;
	Botan::RSA_PublicKey* botanKey = pk->getBotanKey();

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

		return false;
	}

	try
	{
		verifier = new Botan::PK_Verifier(*botanKey, emsa);
	}
	catch (...)
	{
		ERROR_MSG("Could not create the verifier token");

		return false;
	}

	// Perform the verify operation
	bool verResult;
	try
	{
		verResult = verifier->verify_message(originalData.const_byte_str(),
							originalData.size(),
							signature.const_byte_str(),
							signature.size());
	}
	catch (...)
	{
		ERROR_MSG("Could not check the signature");

		delete verifier;
		verifier = NULL;

		return false;
	}

	delete verifier;
	verifier = NULL;

	return verResult;
}