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
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
-rw-r--r--Swiften/TLS/CertificateFactory.cpp4
-rw-r--r--Swiften/TLS/CertificateFactory.h2
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.cpp8
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h2
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp9
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h2
-rw-r--r--Swiften/TLS/TLSContext.cpp2
-rw-r--r--Swiften/TLS/TLSContext.h2
-rw-r--r--Swiften/TLS/UnitTest/CertificateTest.cpp2
-rw-r--r--Swiften/TLS/UnitTest/ClientServerTest.cpp110
10 files changed, 125 insertions, 18 deletions
diff --git a/Swiften/TLS/CertificateFactory.cpp b/Swiften/TLS/CertificateFactory.cpp
index 303bcf7..aaf27d9 100644
--- a/Swiften/TLS/CertificateFactory.cpp
+++ b/Swiften/TLS/CertificateFactory.cpp
@@ -23,9 +23,9 @@ namespace Swift {
23CertificateFactory::~CertificateFactory() { 23CertificateFactory::~CertificateFactory() {
24} 24}
25 25
26std::vector<Certificate::ref> CertificateFactory::createCertificateChain(const ByteArray& /* data */) { 26std::vector<std::unique_ptr<Certificate>> CertificateFactory::createCertificateChain(const ByteArray& /* data */) {
27 assert(false); 27 assert(false);
28 return std::vector<Certificate::ref>(); 28 return std::vector<std::unique_ptr<Certificate>>();
29} 29}
30 30
31PrivateKey::ref CertificateFactory::createPrivateKey(const SafeByteArray& data, boost::optional<SafeByteArray> password) { 31PrivateKey::ref CertificateFactory::createPrivateKey(const SafeByteArray& data, boost::optional<SafeByteArray> password) {
diff --git a/Swiften/TLS/CertificateFactory.h b/Swiften/TLS/CertificateFactory.h
index cb7fb6e..619031c 100644
--- a/Swiften/TLS/CertificateFactory.h
+++ b/Swiften/TLS/CertificateFactory.h
@@ -19,7 +19,7 @@ namespace Swift {
19 virtual ~CertificateFactory(); 19 virtual ~CertificateFactory();
20 20
21 virtual Certificate* createCertificateFromDER(const ByteArray& der) = 0; 21 virtual Certificate* createCertificateFromDER(const ByteArray& der) = 0;
22 virtual std::vector<Certificate::ref> createCertificateChain(const ByteArray& data); 22 virtual std::vector<std::unique_ptr<Certificate>> createCertificateChain(const ByteArray& data);
23 PrivateKey::ref createPrivateKey(const SafeByteArray& data, boost::optional<SafeByteArray> password = boost::optional<SafeByteArray>()); 23 PrivateKey::ref createPrivateKey(const SafeByteArray& data, boost::optional<SafeByteArray> password = boost::optional<SafeByteArray>());
24 }; 24 };
25} 25}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.cpp
index c94702c..5eb626b 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.cpp
@@ -20,8 +20,8 @@ Certificate* OpenSSLCertificateFactory::createCertificateFromDER(const ByteArray
20 return new OpenSSLCertificate(der); 20 return new OpenSSLCertificate(der);
21} 21}
22 22
23std::vector<Certificate::ref> OpenSSLCertificateFactory::createCertificateChain(const ByteArray& data) { 23std::vector<std::unique_ptr<Certificate>> OpenSSLCertificateFactory::createCertificateChain(const ByteArray& data) {
24 std::vector<Certificate::ref> certificateChain; 24 std::vector<std::unique_ptr<Certificate>> certificateChain;
25 25
26 if (data.size() > std::numeric_limits<int>::max()) { 26 if (data.size() > std::numeric_limits<int>::max()) {
27 return certificateChain; 27 return certificateChain;
@@ -35,11 +35,11 @@ std::vector<Certificate::ref> OpenSSLCertificateFactory::createCertificateChain(
35 auto x509certFromPEM = PEM_read_bio_X509(bio.get(), &openSSLCert, nullptr, nullptr); 35 auto x509certFromPEM = PEM_read_bio_X509(bio.get(), &openSSLCert, nullptr, nullptr);
36 if (x509certFromPEM && openSSLCert) { 36 if (x509certFromPEM && openSSLCert) {
37 std::shared_ptr<X509> x509Cert(openSSLCert, X509_free); 37 std::shared_ptr<X509> x509Cert(openSSLCert, X509_free);
38 certificateChain.push_back(std::make_shared<OpenSSLCertificate>(x509Cert)); 38 certificateChain.emplace_back(std::make_unique<OpenSSLCertificate>(x509Cert));
39 openSSLCert = nullptr; 39 openSSLCert = nullptr;
40 while ((x509certFromPEM = PEM_read_bio_X509(bio.get(), &openSSLCert, nullptr, nullptr)) != nullptr) { 40 while ((x509certFromPEM = PEM_read_bio_X509(bio.get(), &openSSLCert, nullptr, nullptr)) != nullptr) {
41 std::shared_ptr<X509> x509Cert(openSSLCert, X509_free); 41 std::shared_ptr<X509> x509Cert(openSSLCert, X509_free);
42 certificateChain.push_back(std::make_shared<OpenSSLCertificate>(x509Cert)); 42 certificateChain.emplace_back(std::make_unique<OpenSSLCertificate>(x509Cert));
43 openSSLCert = nullptr; 43 openSSLCert = nullptr;
44 } 44 }
45 } 45 }
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
index af45a33..48e9b2c 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
@@ -16,6 +16,6 @@ namespace Swift {
16 virtual ~OpenSSLCertificateFactory() override final; 16 virtual ~OpenSSLCertificateFactory() override final;
17 17
18 virtual Certificate* createCertificateFromDER(const ByteArray& der) override final; 18 virtual Certificate* createCertificateFromDER(const ByteArray& der) override final;
19 virtual std::vector<Certificate::ref> createCertificateChain(const ByteArray& data) override final; 19 virtual std::vector<std::unique_ptr<Certificate>> createCertificateChain(const ByteArray& data) override final;
20 }; 20 };
21} 21}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 968ef8f..e9889bc 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -338,14 +338,14 @@ void OpenSSLContext::sendPendingDataToApplication() {
338 } 338 }
339} 339}
340 340
341bool OpenSSLContext::setCertificateChain(const std::vector<Certificate::ref>& certificateChain) { 341bool OpenSSLContext::setCertificateChain(std::vector<std::unique_ptr<Certificate>>&& certificateChain) {
342 if (certificateChain.size() == 0) { 342 if (certificateChain.size() == 0) {
343 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl; 343 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl;
344 return false; 344 return false;
345 } 345 }
346 346
347 // load endpoint certificate 347 // load endpoint certificate
348 auto openSSLCert = std::dynamic_pointer_cast<OpenSSLCertificate>(certificateChain[0]); 348 auto openSSLCert = dynamic_cast<OpenSSLCertificate*>(certificateChain[0].get());
349 if (!openSSLCert) { 349 if (!openSSLCert) {
350 return false; 350 return false;
351 } 351 }
@@ -355,8 +355,8 @@ bool OpenSSLContext::setCertificateChain(const std::vector<Certificate::ref>& ce
355 } 355 }
356 356
357 if (certificateChain.size() > 1) { 357 if (certificateChain.size() > 1) {
358 for (auto certificate : range(certificateChain.begin() + 1, certificateChain.end())) { 358 for (auto certificate = certificateChain.begin() + 1; certificate != certificateChain.end(); ++certificate) {
359 auto openSSLCert = std::dynamic_pointer_cast<OpenSSLCertificate>(certificate); 359 auto openSSLCert = dynamic_cast<OpenSSLCertificate*>(certificate->get());
360 if (!openSSLCert) { 360 if (!openSSLCert) {
361 return false; 361 return false;
362 } 362 }
@@ -364,6 +364,7 @@ bool OpenSSLContext::setCertificateChain(const std::vector<Certificate::ref>& ce
364 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl; 364 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl;
365 return false; 365 return false;
366 } 366 }
367 certificate->release();
367 } 368 }
368 } 369 }
369 370
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index cfa852a..c18a6f4 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -45,7 +45,7 @@ namespace Swift {
45 void connect() override final; 45 void connect() override final;
46 void connect(const std::string& requestHostname) override final; 46 void connect(const std::string& requestHostname) override final;
47 47
48 bool setCertificateChain(const std::vector<Certificate::ref>& certificateChain) override final; 48 bool setCertificateChain(std::vector<std::unique_ptr<Certificate>>&& certificateChain) override final;
49 bool setPrivateKey(const PrivateKey::ref& privateKey) override final; 49 bool setPrivateKey(const PrivateKey::ref& privateKey) override final;
50 bool setClientCertificate(CertificateWithKey::ref cert) override final; 50 bool setClientCertificate(CertificateWithKey::ref cert) override final;
51 void setAbortTLSHandshake(bool abort) override final; 51 void setAbortTLSHandshake(bool abort) override final;
diff --git a/Swiften/TLS/TLSContext.cpp b/Swiften/TLS/TLSContext.cpp
index cc05834..666ea7f 100644
--- a/Swiften/TLS/TLSContext.cpp
+++ b/Swiften/TLS/TLSContext.cpp
@@ -21,7 +21,7 @@ void TLSContext::connect(const std::string& /* serverName */) {
21 assert(false); 21 assert(false);
22} 22}
23 23
24bool TLSContext::setCertificateChain(const std::vector<Certificate::ref>& /* certificateChain */) { 24bool TLSContext::setCertificateChain(std::vector<std::unique_ptr<Certificate>>&& /* certificateChain */) {
25 assert(false); 25 assert(false);
26 return false; 26 return false;
27} 27}
diff --git a/Swiften/TLS/TLSContext.h b/Swiften/TLS/TLSContext.h
index 9b0a2eb..003069f 100644
--- a/Swiften/TLS/TLSContext.h
+++ b/Swiften/TLS/TLSContext.h
@@ -28,7 +28,7 @@ namespace Swift {
28 virtual void connect() = 0; 28 virtual void connect() = 0;
29 virtual void connect(const std::string& serverName); 29 virtual void connect(const std::string& serverName);
30 30
31 virtual bool setCertificateChain(const std::vector<Certificate::ref>& /* certificateChain */); 31 virtual bool setCertificateChain(std::vector<std::unique_ptr<Certificate>>&& /* certificateChain */);
32 virtual bool setPrivateKey(const PrivateKey::ref& /* privateKey */); 32 virtual bool setPrivateKey(const PrivateKey::ref& /* privateKey */);
33 33
34 virtual bool setClientCertificate(CertificateWithKey::ref cert) = 0; 34 virtual bool setClientCertificate(CertificateWithKey::ref cert) = 0;
diff --git a/Swiften/TLS/UnitTest/CertificateTest.cpp b/Swiften/TLS/UnitTest/CertificateTest.cpp
index aac2cfb..d5bf210 100644
--- a/Swiften/TLS/UnitTest/CertificateTest.cpp
+++ b/Swiften/TLS/UnitTest/CertificateTest.cpp
@@ -73,7 +73,7 @@ zqCzpwGL
73 auto certificateChain = tlsFactories.getCertificateFactory()->createCertificateChain(createByteArray(PEMCertificate)); 73 auto certificateChain = tlsFactories.getCertificateFactory()->createCertificateChain(createByteArray(PEMCertificate));
74 CPPUNIT_ASSERT_EQUAL(size_t(1), certificateChain.size()); 74 CPPUNIT_ASSERT_EQUAL(size_t(1), certificateChain.size());
75 75
76 auto certificate = certificateChain[0]; 76 auto certificate = certificateChain[0].get();
77 CPPUNIT_ASSERT_EQUAL(std::string("/CN=montague.example"), certificate->getSubjectName()); 77 CPPUNIT_ASSERT_EQUAL(std::string("/CN=montague.example"), certificate->getSubjectName());
78 } 78 }
79 79
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());