From b5ae8c3a9ec236321d705f9a79234777fc28b5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Thu, 30 Dec 2010 20:19:42 +0100 Subject: Show certificate fingerprint in 'Trust certificate' dialog. diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp index 37ac755..4a54152 100644 --- a/Swift/QtUI/QtLoginWindow.cpp +++ b/Swift/QtUI/QtLoginWindow.cpp @@ -401,7 +401,8 @@ bool QtLoginWindow::askUserToTrustCertificatePermanently(const String& message, dialog.setText("The certificate presented by the server is not valid."); dialog.setInformativeText(P2QSTRING(message) + "\n\nWould you like to permanently trust this certificate? This must only be done if you know it is correct."); - QString detailedText = "Subject: " + P2QSTRING(certificate->getSubjectName()); + QString detailedText = "Subject: " + P2QSTRING(certificate->getSubjectName()) + "\n"; + detailedText += "SHA-1 Fingerprint: " + P2QSTRING(certificate->getSHA1Fingerprint()); dialog.setDetailedText(detailedText); dialog.setStandardButtons(QMessageBox::Yes | QMessageBox::No); diff --git a/Swiften/SConscript b/Swiften/SConscript index a4eb75d..a9b6f41 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -290,6 +290,7 @@ if env["SCONS_STAGE"] == "build" : File("StringCodecs/UnitTest/HMACSHA1Test.cpp"), File("StringCodecs/UnitTest/PBKDF2Test.cpp"), File("TLS/UnitTest/ServerIdentityVerifierTest.cpp"), + File("TLS/UnitTest/CertificateTest.cpp"), File("VCards/UnitTest/VCardManagerTest.cpp"), ]) diff --git a/Swiften/StringCodecs/Hexify.cpp b/Swiften/StringCodecs/Hexify.cpp index 8259912..c762d9b 100644 --- a/Swiften/StringCodecs/Hexify.cpp +++ b/Swiften/StringCodecs/Hexify.cpp @@ -15,6 +15,12 @@ namespace Swift { +String Hexify::hexify(unsigned char byte) { + std::ostringstream result; + result << std::hex << std::setw(2) << std::setfill('0') << boost::numeric_cast(byte); + return String(result.str()); +} + String Hexify::hexify(const ByteArray& data) { std::ostringstream result; result << std::hex; diff --git a/Swiften/StringCodecs/Hexify.h b/Swiften/StringCodecs/Hexify.h index cf51bda..5eaabda 100644 --- a/Swiften/StringCodecs/Hexify.h +++ b/Swiften/StringCodecs/Hexify.h @@ -12,6 +12,7 @@ namespace Swift { class Hexify { public: + static String hexify(unsigned char byte); static String hexify(const ByteArray& data); }; } diff --git a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp index 760d661..4ed871a 100644 --- a/Swiften/StringCodecs/UnitTest/HexifyTest.cpp +++ b/Swiften/StringCodecs/UnitTest/HexifyTest.cpp @@ -16,12 +16,17 @@ using namespace Swift; class HexifyTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(HexifyTest); CPPUNIT_TEST(testHexify); + CPPUNIT_TEST(testHexify_Byte); CPPUNIT_TEST_SUITE_END(); public: void testHexify() { CPPUNIT_ASSERT_EQUAL(String("4206b23ca6b0a643d20d89b04ff58cf78b8096ed"), Hexify::hexify(ByteArray("\x42\x06\xb2\x3c\xa6\xb0\xa6\x43\xd2\x0d\x89\xb0\x4f\xf5\x8c\xf7\x8b\x80\x96\xed"))); } + + void testHexify_Byte() { + CPPUNIT_ASSERT_EQUAL(String("b2"), Hexify::hexify(0xb2)); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(HexifyTest); diff --git a/Swiften/TLS/Certificate.cpp b/Swiften/TLS/Certificate.cpp index 7d61b22..984d668 100644 --- a/Swiften/TLS/Certificate.cpp +++ b/Swiften/TLS/Certificate.cpp @@ -4,7 +4,12 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#include "Swiften/TLS/Certificate.h" +#include + +#include + +#include +#include namespace Swift { @@ -14,4 +19,16 @@ const char* Certificate::ID_ON_DNSSRV_OID = "1.3.6.1.5.5.7.8.7"; Certificate::~Certificate() { } +String Certificate::getSHA1Fingerprint() const { + ByteArray hash = SHA1::getHash(toDER()); + std::ostringstream s; + for (size_t i = 0; i < hash.getSize(); ++i) { + if (i > 0) { + s << ":"; + } + s << Hexify::hexify(hash[i]).getUTF8String(); + } + return String(s.str()); +} + } diff --git a/Swiften/TLS/Certificate.h b/Swiften/TLS/Certificate.h index 89c1de6..e01aa74 100644 --- a/Swiften/TLS/Certificate.h +++ b/Swiften/TLS/Certificate.h @@ -31,6 +31,8 @@ namespace Swift { virtual ByteArray toDER() const = 0; + virtual String getSHA1Fingerprint() const; + protected: static const char* ID_ON_XMPPADDR_OID; static const char* ID_ON_DNSSRV_OID; diff --git a/Swiften/TLS/SimpleCertificate.h b/Swiften/TLS/SimpleCertificate.h index 2db8291..7af8530 100644 --- a/Swiften/TLS/SimpleCertificate.h +++ b/Swiften/TLS/SimpleCertificate.h @@ -55,7 +55,11 @@ namespace Swift { } ByteArray toDER() const { - return ByteArray(); + return der; + } + + void setDER(const ByteArray& der) { + this->der = der; } private: @@ -63,6 +67,7 @@ namespace Swift { private: String subjectName; + ByteArray der; std::vector commonNames; std::vector dnsNames; std::vector xmppAddresses; diff --git a/Swiften/TLS/UnitTest/CertificateTest.cpp b/Swiften/TLS/UnitTest/CertificateTest.cpp new file mode 100644 index 0000000..b5e69c3 --- /dev/null +++ b/Swiften/TLS/UnitTest/CertificateTest.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include + +#include +#include +#include + +#include +#include + +using namespace Swift; + +class CertificateTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(CertificateTest); + CPPUNIT_TEST(testGetSHA1Fingerprint); + CPPUNIT_TEST_SUITE_END(); + + public: + void testGetSHA1Fingerprint() { + SimpleCertificate::ref testling = boost::make_shared(); + testling->setDER(ByteArray("abcdefg")); + + CPPUNIT_ASSERT_EQUAL(String("2f:b5:e1:34:19:fc:89:24:68:65:e7:a3:24:f4:76:ec:62:4e:87:40"), testling->getSHA1Fingerprint()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(CertificateTest); -- cgit v0.10.2-6-g49f6