diff options
| author | Tim Costen <tim.costen@isode.com> | 2019-10-04 09:03:59 (GMT) |
|---|---|---|
| committer | Tim Costen <tim.costen@isode.com> | 2019-10-04 12:25:33 (GMT) |
| commit | 2ad1938c50f9fe57fe3dd98eb9f4bb711ac52acd (patch) | |
| tree | c18d0317b1f750bad3d413ed5bc6ec40a2e0bfbb /Swiften/TLS/OpenSSL/OpenSSLContext.cpp | |
| parent | df07a5e1e654c5fe4b513b8b0e41a392e9955cdf (diff) | |
| download | swift-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.cpp | 13 |
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 | } |
Swift