summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdwin Mons <edwin.mons@isode.com>2019-01-18 15:25:58 (GMT)
committerEdwin Mons <edwin.mons@isode.com>2019-01-18 20:27:03 (GMT)
commit68dd665d51c925a118cfced4583942b7157b59de (patch)
treefc4144d4a3284fdd68c34b8d3bf6c0d107998a6b /Swiften/TLS/UnitTest/ClientServerTest.cpp
parent9b12c9751cf8fd1658dfd948c4d854b0e1407b0d (diff)
downloadswift-68dd665d51c925a118cfced4583942b7157b59de.zip
swift-68dd665d51c925a118cfced4583942b7157b59de.tar.bz2
Allow ownership transfer of certificates
OpenSSL TLS contexts assume ownership of any additional certificate passed into it. The CertificateFactory now returns a vector of unique_ptrs, and OpenSSLContext will do the needful with releasing ownership at the right moment. A unit test has been added that uses a chained certificate in client/server context. Before the fix, this test would either fail, or result in a segmentation fault, depending on the mood of OpenSSL. Test-Information: Unit tests pass on Debian 9 Ran manual tests with server test code, tested both chained and single certificates, and no longer observed crashes when accepting a connection. Change-Id: I21814969e45c7d77e9a1af14f2c958c4c0311cd0
Diffstat (limited to 'Swiften/TLS/UnitTest/ClientServerTest.cpp')
-rw-r--r--Swiften/TLS/UnitTest/ClientServerTest.cpp110
1 files changed, 108 insertions, 2 deletions
diff --git a/Swiften/TLS/UnitTest/ClientServerTest.cpp b/Swiften/TLS/UnitTest/ClientServerTest.cpp
index e60364e..24bd7c5 100644
--- a/Swiften/TLS/UnitTest/ClientServerTest.cpp
+++ b/Swiften/TLS/UnitTest/ClientServerTest.cpp
@@ -84,7 +84,49 @@ S05kF7XRpludRB4QkAJt5BNNv6BPP7HPIKyR/rq94ONvzVPAo7uASyFE2sMBsfwP
84pXAI1LVolPCoUC13jEkKdmc8kMSxU+XtsvFryNhkfQtZfSg+nBRFYptFE7GrZ9WY 84pXAI1LVolPCoUC13jEkKdmc8kMSxU+XtsvFryNhkfQtZfSg+nBRFYptFE7GrZ9WY
85GMSL4g== 85GMSL4g==
86-----END CERTIFICATE----- 86-----END CERTIFICATE-----
87)"}}; 87)"},
88 {"casigned.example.com",
89R"(-----BEGIN CERTIFICATE-----
90MIIDYTCCAkmgAwIBAgIJAPEpYlUWlJW8MA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
91BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMQ4wDAYDVQQKDAVJc29kZTEPMA0GA1UE
92AwwGVGVzdENBMB4XDTE4MDExODAwMDAwMFoXDTQ5MDExODAwMDAwMFowTjELMAkG
93A1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQxDjAMBgNVBAoMBUlzb2RlMR0wGwYD
94VQQDDBRjYXNpZ25lZC5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
95ADCCAQoCggEBAKw4iCscGIDCc55mwxgJsn/v2GEorpE9zHYsMfl6px2aRLGgB8ki
96xYyNiEPA/b/ilShRp7pp22LPb5O3aOVVWzAs5FTvPdFY2vS8YIxR6XSKXO3u4Q8/
97w8CR0AbKpeCtL0TwSl1u76nq6ORMep6QGsTjDLQ7wUwdShL4qV4nIGxJWon/5GI0
98nl4Xr/wzmysbMjAMSiWOR90DNZMvqQBBhQcJdqdirc+whR8gOhIMvJBn5jlMuFEB
99zL/bR+kG/zFuD0EMsMTy6TETefYuxeWmhuzQENyAV5+1v48G/1a9zzN9Y0xQ6T0N
100ppbLzq+/zhxT1eBN8/O0bAGUzzk1VSFvouECAwEAAaNQME4wHQYDVR0OBBYEFCnR
101umlxjdaUvcpf77zahrDmPnt1MB8GA1UdIwQYMBaAFAbbhPAKtD5YzxQqGH2Um4/f
102OmdFMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEPrTTKS+7A4dJJh
103gSAS44ZYyR8/kt9Y3V4qxJM2xrOrW6rM8N15n2i/osSy0AYHiPuvgDG+D7hLt5Ct
1047jZKrp3JRsBaU8//9k6+euwVyWS+EKo/eb7qtSNibZOk7GwrXekJMbRXz1cHTKnW
1050R8UG+EMkOqKQh5dhWuEBXff9SYLTALf0/i+/Ixl3b9rQ6zpY/7UwBdlWLaliM1i
106odIgVu1XRE6Su+bGMa1L5ArniN0LMFq9Mxag2H0V7Kru7vIvbBkL7U6tbi7u26hv
107q4kUFROW2U2C02FTmJeSEBvWoDyMoVjKkmaTL0+vDSQRPGtCsvCgaCXgOwU2Po9s
1088jjHQxg=
109-----END CERTIFICATE-----
110-----BEGIN CERTIFICATE-----
111MIIDUzCCAjugAwIBAgIJAPEpYlUWlJW7MA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
112BAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMQ4wDAYDVQQKDAVJc29kZTEPMA0GA1UE
113AwwGVGVzdENBMB4XDTE4MDExODAwMDAwMFoXDTQ5MDExODAwMDAwMFowQDELMAkG
114A1UEBhMCR0IxEDAOBgNVBAgMB0VuZ2xhbmQxDjAMBgNVBAoMBUlzb2RlMQ8wDQYD
115VQQDDAZUZXN0Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiCA+9
116bdSHFNPOgbsnhrKbLJP+1lxWTe06+ExwJA3QgCKsR13MsAK8rhmuNB0k8ZIFJL+c
117yUOUgw0370eP940QAtK+HinJpvaGEZKEwaB8VUCjzFTb7zUBio1Y7B45aawEV3qT
118Lzcnil3f7vPIxnAoaptzPriySdggIsimj+y6AWum5FUPyfZzF7EnYfF/VH8V/ZNX
119fku7PPbaeDHvu4EF/0s8P+/l6jddz8dqbDMjH3GDM8sjryWPQPNDjKZ1x80BIdyq
120s9m/kXqIIySNwdIa/X+nYTMchUa5y46n2N4n0RA4F+rf+Ni1Cxk9Ejmmz5hinV+t
121Yzh6jsbB7yZiqEnzAgMBAAGjUDBOMB0GA1UdDgQWBBQG24TwCrQ+WM8UKhh9lJuP
1223zpnRTAfBgNVHSMEGDAWgBQG24TwCrQ+WM8UKhh9lJuP3zpnRTAMBgNVHRMEBTAD
123AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBMHQ3WMEhkEc0VoOEw3mbsngt1eyJz+nFM
124FeGdRb7JSwpJfe/yBxyGodGyHsQJPVole6sUdq8S1QGT547PkgDHc6Btoq96Mahq
125brgfx1JL9a1F8qaqcENebHc7ltW8kps4xtdlithfo4nKaciYZ5mKbug+AFv569mb
126LU3F282dyW1dLa7+L8dGbb8Ntpnp0BB0Cotm4GX3Xi6Y+fikouqcmXj7vX+uMhG4
127pQpXqb2ML1Gev4w6XUsnls+OJok97x99NsOcqtwqsLJS/sg0cpwrgZ9+50hQKlHO
1288H6hhNjGBkvpIiNsWb9UOc+Id86J+drs9Ed93Eyyvwnq2XcqPGF3
129-----END CERTIFICATE-----)"}};
88std::map<std::string, std::string> privateKeyPEM = { 130std::map<std::string, std::string> privateKeyPEM = {
89 {"montague.example", 131 {"montague.example",
90R"(-----BEGIN PRIVATE KEY----- 132R"(-----BEGIN PRIVATE KEY-----
@@ -192,6 +234,36 @@ mgPPV65cznhofUsg2QenT8zKisvYPYN3p3p9Jo6IqHyT/CCymwIB4OMZITiwXxQs
192PMAxlZGkX3Uri5A8Ln3QQ46elanI2TlC+ZDa84gu/Gw691JWCfsaSaQDTJKnGqos 234PMAxlZGkX3Uri5A8Ln3QQ46elanI2TlC+ZDa84gu/Gw691JWCfsaSaQDTJKnGqos
193dwiNVl130YWaJLjiA9Poc2llKtypfQ8= 235dwiNVl130YWaJLjiA9Poc2llKtypfQ8=
194-----END PRIVATE KEY----- 236-----END PRIVATE KEY-----
237)"},
238 {"casigned.example.com",
239R"(-----BEGIN PRIVATE KEY-----
240MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsOIgrHBiAwnOe
241ZsMYCbJ/79hhKK6RPcx2LDH5eqcdmkSxoAfJIsWMjYhDwP2/4pUoUae6adtiz2+T
242t2jlVVswLORU7z3RWNr0vGCMUel0ilzt7uEPP8PAkdAGyqXgrS9E8Epdbu+p6ujk
243THqekBrE4wy0O8FMHUoS+KleJyBsSVqJ/+RiNJ5eF6/8M5srGzIwDEoljkfdAzWT
244L6kAQYUHCXanYq3PsIUfIDoSDLyQZ+Y5TLhRAcy/20fpBv8xbg9BDLDE8ukxE3n2
245LsXlpobs0BDcgFeftb+PBv9Wvc8zfWNMUOk9DaaWy86vv84cU9XgTfPztGwBlM85
246NVUhb6LhAgMBAAECggEAP5KesUstwFoHU/GbEsSBn7hpp3Pc/MBTOUwXJoCgL81C
247jk8EkLrFMZ0NL/WNtcduR/PcdnOdCFyKU3zgu8dGYgIwRyoJJ74lFTJ0cVfLVbm9
248lBcZ/QcMu4kXwWoM0WMcj9YjnVnWHmMYlS2mFeIb/5HQnrdwIyisr1QbMSZAUbgn
249HOLSjkd0KUcXxwP9HfE/8zUFbUsv/wPHE9T5eWqZz7lKZRvgUyk3jYElpewxqPvR
250HPOq9BN87ft7rPzmmZ4JCU2tM5MEQONo3jT5pljTU/iz4pfs1HArHS+/zZbGcoiu
251AhODErhLucodwZ07MZsE9KAdGPGUeob4SgMwmkIiAQKBgQDYZ33DHOgYd5Fa7Tqv
252TC77Nbpjmnk5lyoInNf+7pxBTgqIuKbpS6Ctq76nHI0qerNfd44LqojQEJ9S5rbL
2533s+HR+pypx3DyysE92uLaVsF4rfwZeEpJyQ1Q9NGbsKVb2nNrdGs3LZhG5PL+JQT
2548lS9h/sMIbh5Gd/Dkt8a2HlTawKBgQDLu3YdXWeWUOcq63YrLFDO+RUGsCe1cf+2
2553wTmMRgxfzpAPDZKymUPwrJNd1ddCQiRVKg91pLhlDl8B89Q4iWdOpYnE6vrnw3w
2566iEdEyA6IauvEvD3JPXHGtVHKBS/wz06wQVGzsgMvVun1w32SDzTGZ/somvkN1UE
257BTMRVqXB4wKBgCgkgnq4GQG45FjGmtU7v5dP7yRc2lHpjZ2NYq/imU+v51pXTncG
258VWcB7drX/AO+QRnbdpkJaFmYS8W4EH6e9UY1+/KKt4XDYVaJgwSYZY8g8FgCvhLB
259NQFAdKejEitgQHMr5DI5uwcmc3MpyGYu1LNXzyT/+FVWjGCeFQ7IyzDDAoGAXK9I
260+ez/bkQaFs2OMe/0R2TL6wIC3qohMpndSbf2ELaX0pdR/856EaR6p4FujlXIvw0r
261iQ5wPg3H5SRMbbikchYwL1DkusnedsadD/QeijO9PmW4mEcJRW5wrvGOFvuEhJFB
262jEgQfLM82muc33lXqpYSyn3N5cJCfBS9edrYiA8CgYEA0Tsa4KvwzmBXzy2jexUT
263PPYtV9S7hS0D7Owf5SBI1wtWczOu3Y6DsCG4mbDi/tvo1dxC9d5Ns8RXHH9mtdyn
2648VUuSu24lk7VZ0OP5/byiAGqC2urDFGe0iBqePdb+3uS1g132LzAJm4RqBYw4Xjd
265P6n9b0V3iodcFLMTy1ShJ+I=
266-----END PRIVATE KEY-----
195)"}}; 267)"}};
196 268
197auto montagueEncryptedPEM = R"(-----BEGIN RSA PRIVATE KEY----- 269auto montagueEncryptedPEM = R"(-----BEGIN RSA PRIVATE KEY-----
@@ -568,6 +640,40 @@ TEST(ClientServerTest, testClientServerBasicCommunicationEncryptedPrivateKeyRigh
568 })->second))); 640 })->second)));
569} 641}
570 642
643TEST(ClientServerTest, testClientServerBasicCommunicationWithChainedCert) {
644 auto clientContext = createTLSContext(TLSContext::Mode::Client);
645 auto serverContext = createTLSContext(TLSContext::Mode::Server);
646
647 TLSClientServerEventHistory events(clientContext.get(), serverContext.get());
648
649 ClientServerConnector connector(clientContext.get(), serverContext.get());
650
651 auto tlsFactories = std::make_shared<PlatformTLSFactories>();
652
653 ASSERT_TRUE(serverContext->setCertificateChain(tlsFactories->getCertificateFactory()->createCertificateChain(createByteArray(certificatePEM["casigned.example.com"]))));
654
655 auto privateKey = tlsFactories->getCertificateFactory()->createPrivateKey(createSafeByteArray(privateKeyPEM["casigned.example.com"]));
656 ASSERT_NE(nullptr, privateKey.get());
657 ASSERT_TRUE(serverContext->setPrivateKey(privateKey));
658
659 serverContext->accept();
660 clientContext->connect();
661
662 clientContext->handleDataFromApplication(createSafeByteArray("This is a test message from the client."));
663 serverContext->handleDataFromApplication(createSafeByteArray("This is a test message from the server."));
664
665 auto serverEvent = std::find_if(events.events.begin(), events.events.end(), [](std::pair<std::string, TLSEvent>& event){
666 return event.first == "server" && (event.second.type() == typeid(TLSDataForApplication));
667 });
668 ASSERT_NE(events.events.end(), serverEvent);
669 ASSERT_EQ(safeByteArrayToString(createSafeByteArray("This is a test message from the client.")), safeByteArrayToString(boost::apply_visitor(TLSEventToSafeByteArrayVisitor(), serverEvent->second)));
670 auto clientEvent = std::find_if(events.events.begin(), events.events.end(), [](std::pair<std::string, TLSEvent>& event){
671 return event.first == "client" && (event.second.type() == typeid(TLSDataForApplication));
672 });
673 ASSERT_NE(events.events.end(), clientEvent);
674 ASSERT_EQ(safeByteArrayToString(createSafeByteArray("This is a test message from the server.")), safeByteArrayToString(boost::apply_visitor(TLSEventToSafeByteArrayVisitor(), clientEvent->second)));
675}
676
571TEST(ClientServerTest, testSettingPrivateKeyWithWrongPassword) { 677TEST(ClientServerTest, testSettingPrivateKeyWithWrongPassword) {
572 auto clientContext = createTLSContext(TLSContext::Mode::Client); 678 auto clientContext = createTLSContext(TLSContext::Mode::Client);
573 auto serverContext = createTLSContext(TLSContext::Mode::Server); 679 auto serverContext = createTLSContext(TLSContext::Mode::Server);
@@ -610,7 +716,7 @@ TEST(ClientServerTest, testClientServerSNIRequestedHostAvailable) {
610 serverContext->onServerNameRequested.connect([&](const std::string& requestedName) { 716 serverContext->onServerNameRequested.connect([&](const std::string& requestedName) {
611 if (certificatePEM.find(requestedName) != certificatePEM.end() && privateKeyPEM.find(requestedName) != privateKeyPEM.end()) { 717 if (certificatePEM.find(requestedName) != certificatePEM.end() && privateKeyPEM.find(requestedName) != privateKeyPEM.end()) {
612 auto certChain = tlsFactories->getCertificateFactory()->createCertificateChain(createByteArray(certificatePEM[requestedName])); 718 auto certChain = tlsFactories->getCertificateFactory()->createCertificateChain(createByteArray(certificatePEM[requestedName]));
613 ASSERT_EQ(true, serverContext->setCertificateChain(certChain)); 719 ASSERT_EQ(true, serverContext->setCertificateChain(std::move(certChain)));
614 720
615 auto privateKey = tlsFactories->getCertificateFactory()->createPrivateKey(createSafeByteArray(privateKeyPEM[requestedName])); 721 auto privateKey = tlsFactories->getCertificateFactory()->createPrivateKey(createSafeByteArray(privateKeyPEM[requestedName]));
616 ASSERT_NE(nullptr, privateKey.get()); 722 ASSERT_NE(nullptr, privateKey.get());