qca/unittest/cms/cms.cpp
Brad Hards 9fb4705fa6 General update to the CMS test.
1. Merge the .h into the .cpp
2. Update the qmake buildsystem to match
3. Add CMake support
4. Update the certificates, which had expired. Once
again, I'm using the test certs from http://openvalidation.org.

svn path=/trunk/kdesupport/qca/; revision=594720
2006-10-12 04:24:55 +00:00

502 lines
15 KiB
C++

/**
* Copyright (C) 2006 Brad Hards <bradh@frogmouth.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <QtCrypto>
#include <QtTest/QtTest>
class CMSut : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void cleanupTestCase();
void xcrypt_data();
void xcrypt();
void signverify_data();
void signverify();
void signverify_message_data();
void signverify_message();
void signverify_message_invalid_data();
void signverify_message_invalid();
private:
QCA::Initializer* m_init;
};
void CMSut::initTestCase()
{
m_init = new QCA::Initializer;
#include "../fixpaths.include"
}
void CMSut::cleanupTestCase()
{
delete m_init;
}
void CMSut::xcrypt_data()
{
QTest::addColumn<QByteArray>("testText");
QTest::newRow("empty") << QByteArray("");
QTest::newRow("0") << QByteArray("0");
QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01");
QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()");
}
void CMSut::xcrypt()
{
QStringList providersToTest;
providersToTest.append("qca-openssl");
foreach(const QString provider, providersToTest) {
if( !QCA::isSupported( "cert", provider ) )
QWARN( QString( "Certificate not supported for "+provider).toLocal8Bit() );
else if( !QCA::isSupported( "cms", provider ) )
QWARN( QString( "CMS not supported for "+provider).toLocal8Bit() );
else {
QCA::Certificate pubCert = QCA::Certificate::fromPEMFile( "User.pem",0, provider );
QCOMPARE( pubCert.isNull(), false );
QCA::SecureMessageKey secMsgKey;
QCA::CertificateChain chain;
chain += pubCert;
secMsgKey.setX509CertificateChain( chain );
QCA::CMS cms;
QCA::SecureMessage msg(&cms);
QCOMPARE( msg.canClearsign(), false );
QCOMPARE( msg.canSignAndEncrypt(), false );
QCOMPARE( msg.type(), QCA::SecureMessage::CMS );
msg.setRecipient(secMsgKey);
QFETCH( QByteArray, testText );
msg.startEncrypt();
msg.update(testText);
msg.end();
msg.waitForFinished(-1);
QByteArray encryptedResult1 = msg.read();
QCOMPARE( encryptedResult1.isEmpty(), false );
msg.reset();
msg.setRecipient(secMsgKey);
msg.startEncrypt();
msg.update( testText );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.success() );
QByteArray encryptedResult2 = msg.read();
QCOMPARE( encryptedResult2.isEmpty(), false );
QCA::ConvertResult res;
QSecureArray passPhrase = "start";
QCA::PrivateKey privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &res );
QCOMPARE( res, QCA::ConvertGood );
secMsgKey.setX509PrivateKey( privKey );
QCA::SecureMessageKeyList privKeyList;
privKeyList += secMsgKey;
QCA::CMS cms2;
cms2.setPrivateKeys( privKeyList );
QCA::SecureMessage msg2( &cms2 );
msg2.startDecrypt();
msg2.update( encryptedResult1 );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray decryptedResult1 = msg2.read();
QCOMPARE( decryptedResult1, testText );
msg2.reset();
msg2.startDecrypt();
msg2.update( encryptedResult1 );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray decryptedResult2 = msg2.read();
QCOMPARE( decryptedResult1, decryptedResult2 );
QCOMPARE( msg2.canClearsign(), false );
QCOMPARE( msg2.canSignAndEncrypt(), false );
QCOMPARE( msg2.type(), QCA::SecureMessage::CMS );
}
}
};
void CMSut::signverify_data()
{
QTest::addColumn<QByteArray>("testText");
QTest::newRow("empty") << QByteArray("");
QTest::newRow("0") << QByteArray("0");
QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01");
QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()");
}
// This one tests Detached format.
void CMSut::signverify()
{
QStringList providersToTest;
providersToTest.append("qca-openssl");
foreach(const QString provider, providersToTest) {
if( !QCA::isSupported( "cert", provider ) )
QWARN( QString( "Certificate not supported for "+provider).toLocal8Bit() );
else if( !QCA::isSupported( "cms", provider ) )
QWARN( QString( "CMS not supported for "+provider).toLocal8Bit() );
else {
QCA::ConvertResult res;
QSecureArray passPhrase = "start";
QCA::PrivateKey privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::Certificate pubCert = QCA::Certificate::fromPEMFile( "User.pem", &res, provider);
QCOMPARE( res, QCA::ConvertGood );
QCOMPARE( pubCert.isNull(), false );
QCA::CertificateChain chain;
chain += pubCert;
QCA::SecureMessageKey secMsgKey;
secMsgKey.setX509CertificateChain( chain );
secMsgKey.setX509PrivateKey( privKey );
QCA::SecureMessageKeyList privKeyList;
privKeyList += secMsgKey;
QCA::CMS cms2;
cms2.setPrivateKeys( privKeyList );
QCA::SecureMessage msg2( &cms2 );
msg2.setSigners( privKeyList );
QCOMPARE( msg2.canClearsign(), false );
QCOMPARE( msg2.canSignAndEncrypt(), false );
QCOMPARE( msg2.type(), QCA::SecureMessage::CMS );
QFETCH( QByteArray, testText );
msg2.startSign(QCA::SecureMessage::Detached);
msg2.update( testText );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray signedResult1 = msg2.signature();
QCOMPARE( signedResult1.isEmpty(), false );
msg2.reset();
msg2.setSigners( privKeyList );
msg2.startSign(QCA::SecureMessage::Detached);
msg2.update( testText );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray signedResult2 = msg2.signature();
QCOMPARE( signedResult2.isEmpty(), false );
QCA::CMS cms;
QCA::Certificate caCert = QCA::Certificate::fromPEMFile( "RootCAcert.pem", &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::CertificateCollection caCertCollection;
caCertCollection.addCertificate(caCert);
cms.setTrustedCertificates( caCertCollection );
QCA::SecureMessage msg( &cms );
QCOMPARE( msg.canClearsign(), false );
QCOMPARE( msg.canSignAndEncrypt(), false );
QCOMPARE( msg.type(), QCA::SecureMessage::CMS );
msg.startVerify( signedResult1 );
msg.update( testText );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QEXPECT_FAIL( "empty", "We don't seem to be able to verify signature of a zero length message", Continue);
QVERIFY( msg.verifySuccess() );
msg.reset();
msg.startVerify( signedResult2);
msg.update( testText );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QEXPECT_FAIL( "empty", "We don't seem to be able to verify signature of a zero length message", Continue);
QVERIFY( msg.verifySuccess() );
msg.reset();
// This tests junk on the end of the signature - should fail
msg.startVerify( signedResult2 + "junk");
msg.update( testText );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QCOMPARE( msg.verifySuccess(), false );
msg.reset();
// This tests junk on the end of the message - should fail
msg.startVerify( signedResult2 );
msg.update( testText+"junk" );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QCOMPARE( msg.verifySuccess(), false );
}
}
};
void CMSut::signverify_message_data()
{
QTest::addColumn<QByteArray>("testText");
QTest::newRow("empty") << QByteArray("");
QTest::newRow("0") << QByteArray("0");
QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01");
QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()");
}
// This one tests Message format
void CMSut::signverify_message()
{
QStringList providersToTest;
providersToTest.append("qca-openssl");
foreach(const QString provider, providersToTest) {
if( !QCA::isSupported( "cert", provider ) )
QWARN( QString( "Certificate not supported for "+provider).toLocal8Bit() );
else if( !QCA::isSupported( "cms", provider ) )
QWARN( QString( "CMS not supported for "+provider).toLocal8Bit() );
else {
QCA::ConvertResult res;
QSecureArray passPhrase = "start";
QCA::PrivateKey privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::Certificate pubCert = QCA::Certificate::fromPEMFile( "User.pem", &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCOMPARE( pubCert.isNull(), false );
QCA::CertificateChain chain;
chain += pubCert;
QCA::SecureMessageKey secMsgKey;
secMsgKey.setX509CertificateChain( chain );
secMsgKey.setX509PrivateKey( privKey );
QCA::SecureMessageKeyList privKeyList;
privKeyList += secMsgKey;
QCA::CMS cms2;
cms2.setPrivateKeys( privKeyList );
QCA::SecureMessage msg2( &cms2 );
msg2.setSigners( privKeyList );
QCOMPARE( msg2.canClearsign(), false );
QCOMPARE( msg2.canSignAndEncrypt(), false );
QCOMPARE( msg2.type(), QCA::SecureMessage::CMS );
QFETCH( QByteArray, testText );
msg2.startSign( QCA::SecureMessage::Message );
msg2.update( testText );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray signedResult1 = msg2.read();
QCOMPARE( signedResult1.isEmpty(), false );
msg2.reset();
msg2.setSigners( privKeyList );
msg2.startSign(QCA::SecureMessage::Message);
msg2.update( testText );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray signedResult2 = msg2.read();
QCOMPARE( signedResult2.isEmpty(), false );
QCA::CMS cms;
QCA::Certificate caCert = QCA::Certificate::fromPEMFile( "RootCAcert.pem", &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::CertificateCollection caCertCollection;
caCertCollection.addCertificate(caCert);
cms.setTrustedCertificates( caCertCollection );
QCA::SecureMessage msg( &cms );
QCOMPARE( msg.canClearsign(), false );
QCOMPARE( msg.canSignAndEncrypt(), false );
QCOMPARE( msg.type(), QCA::SecureMessage::CMS );
msg.startVerify( );
msg.update( signedResult1 );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QVERIFY( msg.verifySuccess() );
msg.reset();
msg.startVerify( );
msg.update( signedResult2 );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QVERIFY( msg.verifySuccess() );
msg.reset();
msg.startVerify( );
msg.update( signedResult2 );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QCOMPARE( msg.verifySuccess(), true );
}
}
};
void CMSut::signverify_message_invalid_data()
{
QTest::addColumn<QByteArray>("testText");
QTest::newRow("empty") << QByteArray("");
QTest::newRow("0") << QByteArray("0");
QTest::newRow("07") << QByteArray("07899847jkjjfasjaJKJLJkljklj&kjlj;/**-+.01");
QTest::newRow("dubious") << QByteArray("~!#**$#&&%^@#^&()");
}
// This one tests Message format
void CMSut::signverify_message_invalid()
{
QStringList providersToTest;
providersToTest.append("qca-openssl");
foreach(const QString provider, providersToTest) {
if( !QCA::isSupported( "cert", provider ) )
QWARN( QString( "Certificate not supported for "+provider).toLocal8Bit() );
else if( !QCA::isSupported( "cms", provider ) )
QWARN( QString( "CMS not supported for "+provider).toLocal8Bit() );
else {
QCA::ConvertResult res;
QSecureArray passPhrase = "start";
QCA::PrivateKey privKey = QCA::PrivateKey::fromPEMFile( "Userkey.pem", passPhrase, &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::Certificate pubCert = QCA::Certificate::fromPEMFile( "User.pem", &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCOMPARE( pubCert.isNull(), false );
QCA::CertificateChain chain;
chain += pubCert;
QCA::SecureMessageKey secMsgKey;
secMsgKey.setX509CertificateChain( chain );
secMsgKey.setX509PrivateKey( privKey );
QCA::SecureMessageKeyList privKeyList;
privKeyList += secMsgKey;
QCA::CMS cms2;
cms2.setPrivateKeys( privKeyList );
QCA::SecureMessage msg2( &cms2 );
msg2.setSigners( privKeyList );
QCOMPARE( msg2.canClearsign(), false );
QCOMPARE( msg2.canSignAndEncrypt(), false );
QCOMPARE( msg2.type(), QCA::SecureMessage::CMS );
QFETCH( QByteArray, testText );
msg2.startSign( QCA::SecureMessage::Message );
msg2.update( testText );
msg2.end();
msg2.waitForFinished(-1);
QVERIFY( msg2.success() );
QByteArray signedResult1 = msg2.read();
QCOMPARE( signedResult1.isEmpty(), false );
QCA::CMS cms;
QCA::Certificate caCert = QCA::Certificate::fromPEMFile( "RootCAcert.pem", &res, provider );
QCOMPARE( res, QCA::ConvertGood );
QCA::CertificateCollection caCertCollection;
caCertCollection.addCertificate(caCert);
cms.setTrustedCertificates( caCertCollection );
QCA::SecureMessage msg( &cms );
QCOMPARE( msg.canClearsign(), false );
QCOMPARE( msg.canSignAndEncrypt(), false );
QCOMPARE( msg.type(), QCA::SecureMessage::CMS );
// This is just to break things
// signedResult1[30] = signedResult1[30] + 1;
signedResult1[signedResult1.size()-2] = 0x00;
msg.startVerify( );
msg.update( signedResult1 );
msg.end();
msg.waitForFinished(-1);
QVERIFY( msg.wasSigned() );
QVERIFY( msg.success() );
QCOMPARE( msg.verifySuccess(), false );
}
}
};
QTEST_MAIN(CMSut)
#include "cms.moc"