示例#1
0
void RSATests::testEncryptDecrypt()
{
	AsymmetricKeyPair* kp;
	RSAParameters p;

	// Public exponents to test
	std::vector<ByteString> exponents;
	exponents.push_back("010001");
	exponents.push_back("03");
	exponents.push_back("0B");
	exponents.push_back("11");

	// Key sizes to test
	std::vector<size_t> keySizes;
	keySizes.push_back(1024);
	keySizes.push_back(1280);
	keySizes.push_back(2048);
	//keySizes.push_back(4096);

	// Paddings to test
	std::vector<AsymMech::Type> paddings;
	paddings.push_back(AsymMech::RSA_PKCS);
	paddings.push_back(AsymMech::RSA_PKCS_OAEP);
	paddings.push_back(AsymMech::RSA);

	for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
	{
		for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
		{
			p.setE(*e);
			p.setBitLength(*k);

			// Generate key-pair
			CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));

			RNG* rng = CryptoFactory::i()->getRNG();

			for (std::vector<AsymMech::Type>::iterator pad = paddings.begin(); pad != paddings.end(); pad++)
			{
				// Generate some test data to encrypt based on the selected padding
				ByteString testData;

				if (*pad == AsymMech::RSA_PKCS)
				{
					CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 12));
				}
				else if (*pad == AsymMech::RSA_PKCS_OAEP)
				{
					CPPUNIT_ASSERT(rng->generateRandom(testData, (*k >> 3) - 42));
				}
				else if (*pad == AsymMech::RSA)
示例#2
0
void RSATests::testKeyGeneration()
{
	AsymmetricKeyPair* kp;
	RSAParameters p;

	// Public exponents to test
	std::vector<ByteString> exponents;
	exponents.push_back("010001");
	exponents.push_back("03");
	exponents.push_back("0B");
	exponents.push_back("11");

	// Key sizes to test
	std::vector<size_t> keySizes;
	keySizes.push_back(1024);
#ifndef WITH_FIPS
	keySizes.push_back(1025);
#endif
	keySizes.push_back(1280);
	keySizes.push_back(2048);
	//keySizes.push_back(4096);

	for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
	{
		for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
		{
			p.setE(*e);
			p.setBitLength(*k);

			// Generate key-pair
			CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));

			RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
			RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();

			CPPUNIT_ASSERT(pub->getBitLength() == *k);
			CPPUNIT_ASSERT(priv->getBitLength() == *k);
			CPPUNIT_ASSERT(pub->getE() == *e);
			CPPUNIT_ASSERT(priv->getE() == *e);

			rsa->recycleKeyPair(kp);
		}
	}
}
示例#3
0
bool BotanRSA::reconstructParameters(AsymmetricParameters** ppParams, ByteString& serialisedData)
{
	// Check input parameters
	if ((ppParams == NULL) || (serialisedData.size() == 0))
	{
		return false;
	}

	RSAParameters* params = new RSAParameters();

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

		return false;
	}

	*ppParams = params;

	return true;
}
示例#4
0
void RSATests::testPKCS8()
{
	// Generate a 1024-bit key-pair for testing
	AsymmetricKeyPair* kp;
	RSAParameters p;

	p.setE("010001");
	p.setBitLength(1024);

	CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
	CPPUNIT_ASSERT(kp != NULL);

	RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();
	CPPUNIT_ASSERT(priv != NULL);

	// Encode and decode the private key
	ByteString pkcs8 = priv->PKCS8Encode();
	CPPUNIT_ASSERT(pkcs8.size() != 0);

	RSAPrivateKey* dPriv = (RSAPrivateKey*) rsa->newPrivateKey();
	CPPUNIT_ASSERT(dPriv != NULL);

	CPPUNIT_ASSERT(dPriv->PKCS8Decode(pkcs8));

	CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
	CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
	CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
	CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
	CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
	CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
	CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
	CPPUNIT_ASSERT(priv->getE() == dPriv->getE());

	rsa->recycleKeyPair(kp);
	rsa->recyclePrivateKey(dPriv);
}
示例#5
0
// Key factory
bool BotanRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
{
	// Check parameters
	if ((ppKeyPair == NULL) ||
	    (parameters == NULL))
	{
		return false;
	}

	if (!parameters->areOfType(RSAParameters::type))
	{
		ERROR_MSG("Invalid parameters supplied for RSA key generation");

		return false;
	}

	RSAParameters* params = (RSAParameters*) parameters;

	if (params->getBitLength() < getMinKeySize() || params->getBitLength() > getMaxKeySize())
	{
		ERROR_MSG("This RSA key size (%lu) is not supported", params->getBitLength());

		return false;
	}

	// Retrieve the desired public exponent
	unsigned long e = params->getE().long_val();

	// Check the public exponent
	if ((e == 0) || (e % 2 != 1))
	{
		ERROR_MSG("Invalid RSA public exponent %d", e);

		return false;
	}

	// Create an asymmetric key-pair object to return
	BotanRSAKeyPair* kp = new BotanRSAKeyPair();

	// Generate the key-pair
	Botan::RSA_PrivateKey* rsa = NULL;
	try {
		BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
		rsa = new Botan::RSA_PrivateKey(*rng->getRNG(),	params->getBitLength(),	e);
	}
	catch (std::exception& ex) {
		ERROR_MSG("RSA key generation failed: %s", ex.what());

		delete kp;

		return false;
	}

	((BotanRSAPublicKey*) kp->getPublicKey())->setFromBotan(rsa);
	((BotanRSAPrivateKey*) kp->getPrivateKey())->setFromBotan(rsa);

	*ppKeyPair = kp;

	// Release the key
	delete rsa;

	return true;
}
示例#6
0
// Key factory
bool OSSLRSA::generateKeyPair(AsymmetricKeyPair** ppKeyPair, AsymmetricParameters* parameters, RNG* /*rng = NULL */)
{
	// Check parameters
	if ((ppKeyPair == NULL) ||
	    (parameters == NULL))
	{
		return false;
	}

	if (!parameters->areOfType(RSAParameters::type))
	{
		ERROR_MSG("Invalid parameters supplied for RSA key generation");

		return false;
	}

	RSAParameters* params = (RSAParameters*) parameters;

	if (params->getBitLength() < getMinKeySize() || params->getBitLength() > getMaxKeySize())
	{
		ERROR_MSG("This RSA key size (%lu) is not supported", params->getBitLength());

		return false;
	}

	if (params->getBitLength() < 1024)
	{
		WARNING_MSG("Using an RSA key size < 1024 bits is not recommended");
	}

	// Retrieve the desired public exponent
	unsigned long e = params->getE().long_val();

	// Check the public exponent
	if ((e == 0) || (e % 2 != 1))
	{
		ERROR_MSG("Invalid RSA public exponent %d", e);

		return false;
	}

	// Generate the key-pair
	RSA* rsa = RSA_generate_key(params->getBitLength(), e, NULL, NULL);

	// Check if the key was successfully generated
	if (rsa == NULL)
	{
		ERROR_MSG("RSA key generation failed (0x%08X)", ERR_get_error());

		return false;
	}

	// Create an asymmetric key-pair object to return
	OSSLRSAKeyPair* kp = new OSSLRSAKeyPair();

	((OSSLRSAPublicKey*) kp->getPublicKey())->setFromOSSL(rsa);
	((OSSLRSAPrivateKey*) kp->getPrivateKey())->setFromOSSL(rsa);

	*ppKeyPair = kp;

	// Release the key
	RSA_free(rsa);

	return true;
}
示例#7
0
void RSATests::testSigningVerifying()
{
	AsymmetricKeyPair* kp;
	RSAParameters p;

	// Public exponents to test
	std::vector<ByteString> exponents;
	exponents.push_back("010001");
	exponents.push_back("03");
	exponents.push_back("0B");
	exponents.push_back("11");

	// Key sizes to test
	std::vector<size_t> keySizes;
	keySizes.push_back(1024);
	keySizes.push_back(1280);
	keySizes.push_back(2048);
	//keySizes.push_back(4096);

	// Mechanisms to test
	std::vector<AsymMech::Type> mechanisms;
#ifndef WITH_FIPS
	mechanisms.push_back(AsymMech::RSA_MD5_PKCS);
#endif
	mechanisms.push_back(AsymMech::RSA_SHA1_PKCS);
	mechanisms.push_back(AsymMech::RSA_SHA224_PKCS);
	mechanisms.push_back(AsymMech::RSA_SHA256_PKCS);
	mechanisms.push_back(AsymMech::RSA_SHA384_PKCS);
	mechanisms.push_back(AsymMech::RSA_SHA512_PKCS);
	mechanisms.push_back(AsymMech::RSA_SHA1_PKCS_PSS);
	mechanisms.push_back(AsymMech::RSA_SHA224_PKCS_PSS);
	mechanisms.push_back(AsymMech::RSA_SHA256_PKCS_PSS);
	mechanisms.push_back(AsymMech::RSA_SHA384_PKCS_PSS);
	mechanisms.push_back(AsymMech::RSA_SHA512_PKCS_PSS);
#ifndef WITH_FIPS
	mechanisms.push_back(AsymMech::RSA_SSL);
#endif

	/* Max salt length for SHA512 and 1024-bit RSA is 62 bytes */
	RSA_PKCS_PSS_PARAMS pssParams[] = {
		{ HashAlgo::SHA1,   AsymRSAMGF::MGF1_SHA1,   20 },
		{ HashAlgo::SHA224, AsymRSAMGF::MGF1_SHA224, 0  },
		{ HashAlgo::SHA256, AsymRSAMGF::MGF1_SHA256, 0  },
		{ HashAlgo::SHA384, AsymRSAMGF::MGF1_SHA384, 48 },
		{ HashAlgo::SHA512, AsymRSAMGF::MGF1_SHA512, 62 }
	};

	for (std::vector<ByteString>::iterator e = exponents.begin(); e != exponents.end(); e++)
	{
		for (std::vector<size_t>::iterator k = keySizes.begin(); k != keySizes.end(); k++)
		{
			p.setE(*e);
			p.setBitLength(*k);

			// Generate key-pair
			CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));

			// Generate some data to sign
			ByteString dataToSign;

			RNG* rng = CryptoFactory::i()->getRNG();

			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 567));

			// Test mechanisms that perform internal hashing
			for (std::vector<AsymMech::Type>::iterator m = mechanisms.begin(); m != mechanisms.end(); m++)
			{
				ByteString blockSignature, singlePartSignature;
				void* param = NULL;
				size_t paramLen = 0;
				bool isPSS = false;

				switch (*m)
				{
					case AsymMech::RSA_SHA1_PKCS_PSS:
						param = &pssParams[0];
						paramLen = sizeof(pssParams[0]);
						isPSS = true;
						break;
					case AsymMech::RSA_SHA224_PKCS_PSS:
						param = &pssParams[1];
						paramLen = sizeof(pssParams[1]);
						isPSS = true;
						break;
					case AsymMech::RSA_SHA256_PKCS_PSS:
						param = &pssParams[2];
						paramLen = sizeof(pssParams[2]);
						isPSS = true;
						break;
					case AsymMech::RSA_SHA384_PKCS_PSS:
						param = &pssParams[3];
						paramLen = sizeof(pssParams[3]);
						isPSS = true;
						break;
					case AsymMech::RSA_SHA512_PKCS_PSS:
						param = &pssParams[4];
						paramLen = sizeof(pssParams[4]);
						isPSS = true;
						break;
					default:
						break;
				}

				// Sign the data in blocks
				CPPUNIT_ASSERT(rsa->signInit(kp->getPrivateKey(), *m, param, paramLen));
				CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(0, 134)));
				CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134, 289)));
				CPPUNIT_ASSERT(rsa->signUpdate(dataToSign.substr(134 + 289)));
				CPPUNIT_ASSERT(rsa->signFinal(blockSignature));

				// Sign the data in one pass
				CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, singlePartSignature, *m, param, paramLen));

				// If it is not a PSS signature, check if the two signatures match
				if (!isPSS)
				{
					// Check if the two signatures match
					CPPUNIT_ASSERT(blockSignature == singlePartSignature);
				}

				// Now perform multi-pass verification
				CPPUNIT_ASSERT(rsa->verifyInit(kp->getPublicKey(), *m, param, paramLen));
				CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(0, 125)));
				CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125, 247)));
				CPPUNIT_ASSERT(rsa->verifyUpdate(dataToSign.substr(125 + 247)));
				CPPUNIT_ASSERT(rsa->verifyFinal(blockSignature));

				// And single-pass verification
				CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, singlePartSignature, *m, param, paramLen));
			}

			// Test mechanisms that do not perform internal hashing

			// Test PKCS #1 signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 35));

			// Sign the data
			ByteString signature;
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS));

			// Verify the signature
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS));

			// Test raw RSA signing
			size_t byteSize = *k >> 3;

			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, byteSize));

			// Strip the topmost bit
			dataToSign[0] &= 0x7F;

			// Sign the data
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA));

			// Verify the signature
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA));

#ifdef WITH_RAW_PSS
			// Test raw (SHA1) PKCS PSS signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 20));
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[0], sizeof(pssParams[0])));

			// Test raw (SHA224) PKCS PSS signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 28));
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[1], sizeof(pssParams[1])));

			// Test raw (SHA256) PKCS PSS signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 32));
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[2], sizeof(pssParams[2])));

			// Test raw (SHA384) PKCS PSS signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 48));
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[3], sizeof(pssParams[3])));

			// Test raw (SHA512) PKCS PSS signing
			CPPUNIT_ASSERT(rng->generateRandom(dataToSign, 64));
			CPPUNIT_ASSERT(rsa->sign(kp->getPrivateKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
			CPPUNIT_ASSERT(rsa->verify(kp->getPublicKey(), dataToSign, signature, AsymMech::RSA_PKCS_PSS, &pssParams[4], sizeof(pssParams[4])));
#endif

			rsa->recycleKeyPair(kp);
		}
	}
}
示例#8
0
void RSATests::testSerialisation()
{
	// Generate a 1024-bit key-pair for testing
	AsymmetricKeyPair* kp;
	RSAParameters p;

	p.setE("010001");
	p.setBitLength(1024);

	CPPUNIT_ASSERT(rsa->generateKeyPair(&kp, &p));
	CPPUNIT_ASSERT(kp != NULL);

	// Serialise the parameters
	ByteString serialisedParams = p.serialise();

	// Deserialise the parameters
	AsymmetricParameters* dP;

	CPPUNIT_ASSERT(rsa->reconstructParameters(&dP, serialisedParams));
	CPPUNIT_ASSERT(dP->areOfType(RSAParameters::type));

	RSAParameters* ddP = (RSAParameters*) dP;

	CPPUNIT_ASSERT(p.getE() == ddP->getE());
	CPPUNIT_ASSERT(p.getBitLength() == ddP->getBitLength());
	rsa->recycleParameters(dP);

	// Serialise the key-pair
	ByteString serialisedKP = kp->serialise();

	CPPUNIT_ASSERT(serialisedKP.size() != 0);

	// Deserialise the key-pair
	AsymmetricKeyPair* dKP;

	CPPUNIT_ASSERT(rsa->reconstructKeyPair(&dKP, serialisedKP));
	CPPUNIT_ASSERT(serialisedKP.size() == 0);
	CPPUNIT_ASSERT(dKP != NULL);

	RSAPublicKey* pub = (RSAPublicKey*) kp->getPublicKey();
	RSAPrivateKey* priv = (RSAPrivateKey*) kp->getPrivateKey();

	RSAPublicKey* dPub = (RSAPublicKey*) dKP->getPublicKey();
	RSAPrivateKey* dPriv = (RSAPrivateKey*) dKP->getPrivateKey();

	CPPUNIT_ASSERT(pub->getN() == dPub->getN());
	CPPUNIT_ASSERT(pub->getE() == dPub->getE());

	CPPUNIT_ASSERT(priv->getP() == dPriv->getP());
	CPPUNIT_ASSERT(priv->getQ() == dPriv->getQ());
	CPPUNIT_ASSERT(priv->getPQ() == dPriv->getPQ());
	CPPUNIT_ASSERT(priv->getDP1() == dPriv->getDP1());
	CPPUNIT_ASSERT(priv->getDQ1() == dPriv->getDQ1());
	CPPUNIT_ASSERT(priv->getD() == dPriv->getD());
	CPPUNIT_ASSERT(priv->getN() == dPriv->getN());
	CPPUNIT_ASSERT(priv->getE() == dPriv->getE());

	// Serialise and deserialise the public key
	ByteString serialisedPub = pub->serialise();

	RSAPublicKey* desPub;

	CPPUNIT_ASSERT(rsa->reconstructPublicKey((PublicKey**) &desPub, serialisedPub));
	CPPUNIT_ASSERT(serialisedPub.size() == 0);
	CPPUNIT_ASSERT(desPub != NULL);

	CPPUNIT_ASSERT(pub->getN() == desPub->getN());
	CPPUNIT_ASSERT(pub->getE() == desPub->getE());

	// Serialise and deserialise the private key
	ByteString serialisedPriv = priv->serialise();

	RSAPrivateKey* desPriv;

	CPPUNIT_ASSERT(rsa->reconstructPrivateKey((PrivateKey**) &desPriv, serialisedPriv));
	CPPUNIT_ASSERT(serialisedPriv.size() == 0);
	CPPUNIT_ASSERT(desPriv != NULL);

	CPPUNIT_ASSERT(priv->getP() == desPriv->getP());
	CPPUNIT_ASSERT(priv->getQ() == desPriv->getQ());
	CPPUNIT_ASSERT(priv->getPQ() == desPriv->getPQ());
	CPPUNIT_ASSERT(priv->getDP1() == desPriv->getDP1());
	CPPUNIT_ASSERT(priv->getDQ1() == desPriv->getDQ1());
	CPPUNIT_ASSERT(priv->getD() == desPriv->getD());
	CPPUNIT_ASSERT(priv->getN() == desPriv->getN());
	CPPUNIT_ASSERT(priv->getE() == desPriv->getE());

	rsa->recycleKeyPair(kp);
	rsa->recycleKeyPair(dKP);
	rsa->recyclePublicKey(desPub);
	rsa->recyclePrivateKey(desPriv);
}