summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Costen <tim.costen@isode.com>2019-10-04 09:03:59 (GMT)
committerTim Costen <tim.costen@isode.com>2019-10-04 12:25:33 (GMT)
commit2ad1938c50f9fe57fe3dd98eb9f4bb711ac52acd (patch)
treec18d0317b1f750bad3d413ed5bc6ec40a2e0bfbb /Swiften/TLS/OpenSSL/OpenSSLContext.cpp
parentdf07a5e1e654c5fe4b513b8b0e41a392e9955cdf (diff)
downloadswift-2ad1938c50f9fe57fe3dd98eb9f4bb711ac52acd.zip
swift-2ad1938c50f9fe57fe3dd98eb9f4bb711ac52acd.tar.bz2
Correct leaks in OpenSSL interface
Remove increment of reference count on first certificate added to a new SSL context - the call to SSL_CTX_use_certificate does this internally. When adding extra certificates to the context via calls to SSL_CTX_add_extra_certificate, the explicit increment of the reference count is still required to prevent destruction of the certificates when the SSL context is freed. In OpenSSLContext::setPrivateKey, make sure the EVP_PKEY returned by PEM_read_bio_PrivateKey is tidied up, by wrapping it in a shared_ptr which calls EVP_PKEY_free. Add a new Unit test which creates an SSL context and inserts a multi-element certificate chain and a private key. JIRA: SWIFT-423 Bug: Release-notes: Manual: Change-Id: I82c66139a9dfe7a925eb39f73721200895a689e2 Test-information: Leak testing performed via ASAN-compiled MLink unit tests - now no leaks/errors reported associated with TLS Contexts and Certificates. Swiften unit test runs as expected.
Diffstat (limited to 'Swiften/TLS/OpenSSL/OpenSSLContext.cpp')
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp13
1 files changed, 6 insertions, 7 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 32d6470..d9560de 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -579,13 +579,11 @@ bool OpenSSLContext::setCertificateChain(const std::vector<std::shared_ptr<Certi
579 return false; 579 return false;
580 } 580 }
581 581
582 // This increments the reference count on the X509 certificate automatically
582 if (SSL_CTX_use_certificate(context_.get(), openSSLCert->getInternalX509().get()) != 1) { 583 if (SSL_CTX_use_certificate(context_.get(), openSSLCert->getInternalX509().get()) != 1) {
583 return false; 584 return false;
584 } 585 }
585 586
586 // Increment reference count on certificate so that it does not get freed when the SSL context is destroyed
587 openSSLCert->incrementReferenceCount();
588
589 if (certificateChain.size() > 1) { 587 if (certificateChain.size() > 1) {
590 for (auto certificate = certificateChain.begin() + 1; certificate != certificateChain.end(); ++certificate) { 588 for (auto certificate = certificateChain.begin() + 1; certificate != certificateChain.end(); ++certificate) {
591 auto openSSLCert = dynamic_cast<OpenSSLCertificate*>(certificate->get()); 589 auto openSSLCert = dynamic_cast<OpenSSLCertificate*>(certificate->get());
@@ -597,7 +595,7 @@ bool OpenSSLContext::setCertificateChain(const std::vector<std::shared_ptr<Certi
597 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl; 595 SWIFT_LOG(warning) << "Trying to load empty certificate chain." << std::endl;
598 return false; 596 return false;
599 } 597 }
600 598 // Have to manually increment reference count as SSL_CTX_add_extra_chain_cert does not do so
601 openSSLCert->incrementReferenceCount(); 599 openSSLCert->incrementReferenceCount();
602 } 600 }
603 } 601 }
@@ -644,16 +642,17 @@ bool OpenSSLContext::setPrivateKey(const PrivateKey::ref& privateKey) {
644 safePassword.push_back(0); 642 safePassword.push_back(0);
645 password = safePassword.data(); 643 password = safePassword.data();
646 } 644 }
647 auto resultKey = PEM_read_bio_PrivateKey(bio.get(), nullptr, empty_or_preset_password_cb, password); 645 // Make sure resultKey is tidied up by wrapping it in a shared_ptr
646 auto resultKey = std::shared_ptr<EVP_PKEY>(PEM_read_bio_PrivateKey(bio.get(), nullptr, empty_or_preset_password_cb, password), EVP_PKEY_free);
648 if (resultKey) { 647 if (resultKey) {
649 if (handle_) { 648 if (handle_) {
650 auto result = SSL_use_PrivateKey(handle_.get(), resultKey);; 649 auto result = SSL_use_PrivateKey(handle_.get(), resultKey.get());
651 if (result != 1) { 650 if (result != 1) {
652 return false; 651 return false;
653 } 652 }
654 } 653 }
655 else { 654 else {
656 auto result = SSL_CTX_use_PrivateKey(context_.get(), resultKey); 655 auto result = SSL_CTX_use_PrivateKey(context_.get(), resultKey.get());
657 if (result != 1) { 656 if (result != 1) {
658 return false; 657 return false;
659 } 658 }