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