diff options
| -rw-r--r-- | Swiften/TLS/ServerIdentityVerifier.cpp | 6 | ||||
| -rw-r--r-- | Swiften/TLS/ServerIdentityVerifier.h | 3 | ||||
| -rw-r--r-- | Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp | 20 |
3 files changed, 26 insertions, 3 deletions
diff --git a/Swiften/TLS/ServerIdentityVerifier.cpp b/Swiften/TLS/ServerIdentityVerifier.cpp index 226e94b..da116e5 100644 --- a/Swiften/TLS/ServerIdentityVerifier.cpp +++ b/Swiften/TLS/ServerIdentityVerifier.cpp @@ -6,19 +6,19 @@ #include <Swiften/TLS/ServerIdentityVerifier.h> #include <boost/algorithm/string.hpp> #include <Swiften/IDN/IDNConverter.h> namespace Swift { -ServerIdentityVerifier::ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter) : domainValid(false) { +ServerIdentityVerifier::ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter, bool checkServer) : domainValid(false), checkServer_(checkServer) { domain = jid.getDomain(); boost::optional<std::string> domainResult = idnConverter->getIDNAEncoded(domain); if (!!domainResult) { encodedDomain = *domainResult; domainValid = true; } } bool ServerIdentityVerifier::certificateVerifies(Certificate::ref certificate) { @@ -30,24 +30,26 @@ bool ServerIdentityVerifier::certificateVerifies(Certificate::ref certificate) { // DNS names std::vector<std::string> dnsNames = certificate->getDNSNames(); for (const auto& dnsName : dnsNames) { if (matchesDomain(dnsName)) { return true; } } hasSAN |= !dnsNames.empty(); + std::string prefix = (checkServer_) ? "_xmpp-server." : "_xmpp-client."; + // SRV names std::vector<std::string> srvNames = certificate->getSRVNames(); for (const auto& srvName : srvNames) { // Only match SRV names that begin with the service; this isn't required per // spec, but we're being purist about this. - if (boost::starts_with(srvName, "_xmpp-client.") && matchesDomain(srvName.substr(std::string("_xmpp-client.").size(), srvName.npos))) { + if (boost::starts_with(srvName, prefix) && matchesDomain(srvName.substr(prefix.size(), srvName.npos))) { return true; } } hasSAN |= !srvNames.empty(); // XmppAddr std::vector<std::string> xmppAddresses = certificate->getXMPPAddresses(); for (const auto& xmppAddress : xmppAddresses) { if (matchesAddress(xmppAddress)) { diff --git a/Swiften/TLS/ServerIdentityVerifier.h b/Swiften/TLS/ServerIdentityVerifier.h index f40c683..f2cf46f 100644 --- a/Swiften/TLS/ServerIdentityVerifier.h +++ b/Swiften/TLS/ServerIdentityVerifier.h @@ -12,23 +12,24 @@ #include <Swiften/Base/API.h> #include <Swiften/JID/JID.h> #include <Swiften/TLS/Certificate.h> namespace Swift { class IDNConverter; class SWIFTEN_API ServerIdentityVerifier { public: - ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter); + ServerIdentityVerifier(const JID& jid, IDNConverter* idnConverter, bool checkServer=false); bool certificateVerifies(Certificate::ref); private: bool matchesDomain(const std::string&) const ; bool matchesAddress(const std::string&) const; private: std::string domain; std::string encodedDomain; bool domainValid; + bool checkServer_; }; } diff --git a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp index 30fe423..7379b69 100644 --- a/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp +++ b/Swiften/TLS/UnitTest/ServerIdentityVerifierTest.cpp @@ -29,18 +29,20 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture { CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithoutService); CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithService); CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithServiceAndWildcard); CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithDifferentService); CPPUNIT_TEST(testCertificateVerifies_WithMatchingXmppAddr); CPPUNIT_TEST(testCertificateVerifies_WithMatchingXmppAddrWithWildcard); CPPUNIT_TEST(testCertificateVerifies_WithMatchingInternationalXmppAddr); CPPUNIT_TEST(testCertificateVerifies_WithMatchingCNWithoutSAN); CPPUNIT_TEST(testCertificateVerifies_WithMatchingCNWithSAN); + CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithServerExpected); + CPPUNIT_TEST(testCertificateVerifies_WithMatchingSRVNameWithClientUnexpected); CPPUNIT_TEST_SUITE_END(); public: void setUp() { idnConverter = std::shared_ptr<IDNConverter>(PlatformIDNConverter::create()); } void testCertificateVerifies_WithoutMatchingDNSName() { ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get()); @@ -125,18 +127,36 @@ class ServerIdentityVerifierTest : public CppUnit::TestFixture { void testCertificateVerifies_WithMatchingSRVNameWithDifferentService() { ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get()); SimpleCertificate::ref certificate(new SimpleCertificate()); certificate->addSRVName("_xmpp-server.bar.com"); CPPUNIT_ASSERT(!testling.certificateVerifies(certificate)); } + void testCertificateVerifies_WithMatchingSRVNameWithServerExpected() { + // Server-mode test which gets cert with "xmpp-server" SRV name + ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get(), true); + SimpleCertificate::ref certificate(new SimpleCertificate()); + certificate->addSRVName("_xmpp-server.bar.com"); + + CPPUNIT_ASSERT(testling.certificateVerifies(certificate)); + } + + void testCertificateVerifies_WithMatchingSRVNameWithClientUnexpected() { + // Server-mode test which gets cert with "xmpp-client" SRV name + ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get(), true); + SimpleCertificate::ref certificate(new SimpleCertificate()); + certificate->addSRVName("_xmpp-client.bar.com"); + + CPPUNIT_ASSERT(!testling.certificateVerifies(certificate)); + } + void testCertificateVerifies_WithMatchingXmppAddr() { ServerIdentityVerifier testling(JID("foo@bar.com/baz"), idnConverter.get()); SimpleCertificate::ref certificate(new SimpleCertificate()); certificate->addXMPPAddress("bar.com"); CPPUNIT_ASSERT(testling.certificateVerifies(certificate)); } void testCertificateVerifies_WithMatchingXmppAddrWithWildcard() { |
Swift