4
0
mirror of https://github.com/QuasarApp/qca.git synced 2025-05-06 15:59:34 +00:00

RSA Keys are permutable, can encrypt with private and decrypt with public

[REVIEW]: 114416
This commit is contained in:
Adnan RIHAN 2013-12-16 22:15:49 +01:00
parent 9ea9d6203f
commit 17cf1841f7
4 changed files with 117 additions and 5 deletions
include/QtCrypto
plugins/qca-ossl
src
unittest/rsaunittest

@ -594,6 +594,13 @@ public:
*/
bool canEncrypt() const;
/**
Test if this key can be used for decryption
\return true if the key can be used for decryption
*/
bool canDecrypt() const;
/**
Test if the key can be used for verifying signatures
@ -617,6 +624,18 @@ public:
*/
SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg);
/**
Decrypt the message
\param in the cipher (encrypted) data
\param out the plain text data
\param alg the algorithm to use
\note This synchronous operation may require event handling, and so
it must not be called from the same thread as an EventHandler.
*/
bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg);
/**
Initialise the signature verification process
@ -863,6 +882,13 @@ public:
*/
bool canDecrypt() const;
/**
Test if this key can be used for encryption
\return true if the key can be used for encryption
*/
bool canEncrypt() const;
/**
Test if this key can be used for signing
@ -870,6 +896,14 @@ public:
*/
bool canSign() const;
/**
The maximum message size that can be encrypted with a specified
algorithm
\param alg the algorithm to check
*/
int maximumEncryptSize(EncryptionAlgorithm alg) const;
/**
Decrypt the message
@ -882,6 +916,14 @@ public:
*/
bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg);
/**
Encrypt a message using a specified algorithm
\param a the message to encrypt
\param alg the algorithm to use
*/
SecureArray encrypt(const SecureArray &a, EncryptionAlgorithm alg);
/**
Initialise the message signature process

@ -1747,9 +1747,9 @@ public:
virtual SecureArray encrypt(const SecureArray &in, EncryptionAlgorithm alg)
{
RSA *rsa = evp.pkey->pkey.rsa;
SecureArray buf = in;
int max = maximumEncryptSize(alg);
if(buf.size() > max)
buf.resize(max);
SecureArray result(RSA_size(rsa));
@ -1764,7 +1764,12 @@ public:
default: return SecureArray(); break;
}
int ret = RSA_public_encrypt(buf.size(), (unsigned char *)buf.data(), (unsigned char *)result.data(), rsa, pad);
int ret;
if (isPrivate())
ret = RSA_private_encrypt(buf.size(), (unsigned char *)buf.data(), (unsigned char *)result.data(), rsa, pad);
else
ret = RSA_public_encrypt(buf.size(), (unsigned char *)buf.data(), (unsigned char *)result.data(), rsa, pad);
if(ret < 0)
return SecureArray();
result.resize(ret);
@ -1775,10 +1780,9 @@ public:
virtual bool decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg)
{
RSA *rsa = evp.pkey->pkey.rsa;
SecureArray result(RSA_size(rsa));
int pad;
switch(alg)
{
case EME_PKCS1v15: pad = RSA_PKCS1_PADDING; break;
@ -1788,7 +1792,12 @@ public:
default: return false; break;
}
int ret = RSA_private_decrypt(in.size(), (unsigned char *)in.data(), (unsigned char *)result.data(), rsa, pad);
int ret;
if (isPrivate())
ret = RSA_private_decrypt(in.size(), (unsigned char *)in.data(), (unsigned char *)result.data(), rsa, pad);
else
ret = RSA_public_decrypt(in.size(), (unsigned char *)in.data(), (unsigned char *)result.data(), rsa, pad);
if(ret < 0)
return false;
result.resize(ret);

@ -804,6 +804,11 @@ bool PublicKey::canEncrypt() const
return isRSA();
}
bool PublicKey::canDecrypt() const
{
return isRSA();
}
bool PublicKey::canVerify() const
{
return (isRSA() || isDSA());
@ -819,6 +824,11 @@ SecureArray PublicKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg)
return static_cast<PKeyContext *>(context())->key()->encrypt(a, alg);
}
bool PublicKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg)
{
return static_cast<PKeyContext *>(context())->key()->decrypt(in, out, alg);
}
void PublicKey::startVerify(SignatureAlgorithm alg, SignatureFormat format)
{
if(isDSA() && format == DefaultFormat)
@ -964,16 +974,31 @@ bool PrivateKey::canDecrypt() const
return isRSA();
}
bool PrivateKey::canEncrypt() const
{
return isRSA();
}
bool PrivateKey::canSign() const
{
return (isRSA() || isDSA());
}
int PrivateKey::maximumEncryptSize(EncryptionAlgorithm alg) const
{
return static_cast<const PKeyContext *>(context())->key()->maximumEncryptSize(alg);
}
bool PrivateKey::decrypt(const SecureArray &in, SecureArray *out, EncryptionAlgorithm alg)
{
return static_cast<PKeyContext *>(context())->key()->decrypt(in, out, alg);
}
SecureArray PrivateKey::encrypt(const SecureArray &a, EncryptionAlgorithm alg)
{
return static_cast<PKeyContext *>(context())->key()->encrypt(a, alg);
}
void PrivateKey::startSign(SignatureAlgorithm alg, SignatureFormat format)
{
if(isDSA() && format == DefaultFormat)

@ -34,6 +34,7 @@ private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void testrsa();
void testAsymmetricEncryption();
private:
QCA::Initializer* m_init;
@ -78,6 +79,7 @@ void RSAUnitTest::testrsa()
QCOMPARE( rsaKey.isPublic(), false );
QCOMPARE( rsaKey.canSign(), true);
QCOMPARE( rsaKey.canDecrypt(), true);
QCOMPARE( rsaKey.canEncrypt(), true);
QCA::RSAPrivateKey rsaPrivKey = rsaKey.toRSA();
QCOMPARE( rsaPrivKey.bitSize(), keysize );
@ -144,6 +146,40 @@ void RSAUnitTest::testrsa()
}
}
void RSAUnitTest::testAsymmetricEncryption()
{
QCA::RSAPrivateKey rsaPrivKey1 = QCA::KeyGenerator().createRSA(512, 65537, "qca-ossl").toRSA();
QCA::RSAPublicKey rsaPubKey1 = rsaPrivKey1.toPublicKey().toRSA();
QCA::RSAPrivateKey rsaPrivKey2 = QCA::KeyGenerator().createRSA(512, 65537, "qca-ossl").toRSA();
// QCA::RSAPublicKey rsaPubKey2 = rsaPrivKey2.toPublicKey().toRSA();
const QCA::SecureArray clearText = "Hello World !";
QCA::SecureArray testText;
QCA::SecureArray cipherText;
// Test keys #1: Enc with public, dec with private
QVERIFY( rsaPubKey1.maximumEncryptSize(QCA::EME_PKCS1v15) >= clearText.size() );
cipherText = rsaPubKey1.encrypt(clearText, QCA::EME_PKCS1v15);
QVERIFY( rsaPrivKey1.decrypt(cipherText, &testText, QCA::EME_PKCS1v15) );
QCOMPARE( clearText, testText );
testText.clear();
// ---
// Test keys #2 to decipher key #1
QVERIFY( !rsaPrivKey2.decrypt(cipherText, &testText, QCA::EME_PKCS1v15) );
QVERIFY( testText.isEmpty() );
// ---
// Test keys #2: Enc with private, dec with public
cipherText.clear();
QVERIFY( rsaPrivKey1.maximumEncryptSize(QCA::EME_PKCS1v15) >= clearText.size() );
cipherText = rsaPrivKey1.encrypt(clearText, QCA::EME_PKCS1v15);
QVERIFY( rsaPubKey1.decrypt(cipherText, &testText, QCA::EME_PKCS1v15) );
QCOMPARE( clearText, testText );
testText.clear();
// ---
}
QTEST_MAIN(RSAUnitTest)