[Opalvoip-svn] SF.net SVN: opalvoip:[34905] ptlib/trunk
Brought to you by:
csoutheren,
rjongbloed
From: <rjo...@us...> - 2016-08-02 18:26:25
|
Revision: 34905 http://sourceforge.net/p/opalvoip/code/34905 Author: rjongbloed Date: 2016-08-02 18:26:23 +0000 (Tue, 02 Aug 2016) Log Message: ----------- When attaching certificate file to a SSL context, make sure we also include the CA chain that might be present. Modified Paths: -------------- ptlib/trunk/include/ptclib/pssl.h ptlib/trunk/src/ptclib/pssl.cxx Modified: ptlib/trunk/include/ptclib/pssl.h =================================================================== --- ptlib/trunk/include/ptclib/pssl.h 2016-08-02 15:55:27 UTC (rev 34904) +++ ptlib/trunk/include/ptclib/pssl.h 2016-08-02 18:26:23 UTC (rev 34905) @@ -362,9 +362,13 @@ virtual void PrintOn(ostream & strm) const { strm << GetSubjectName(); } + typedef std::list<x509_st *> X509_Chain; + const X509_Chain & GetChain() const { return m_chain; } + protected: void FreeCertificate(); x509_st * m_certificate; + X509_Chain m_chain; }; Modified: ptlib/trunk/src/ptclib/pssl.cxx =================================================================== --- ptlib/trunk/src/ptclib/pssl.cxx 2016-08-02 15:55:27 UTC (rev 34904) +++ ptlib/trunk/src/ptclib/pssl.cxx 2016-08-02 18:26:23 UTC (rev 34905) @@ -551,6 +551,10 @@ if (m_certificate != NULL) { X509_free(m_certificate); m_certificate = NULL; + + for (X509_Chain::iterator it = m_chain.begin(); it != m_chain.end(); ++it) + X509_free(*it); + m_chain.clear(); } } @@ -674,6 +678,9 @@ PBoolean PSSLCertificate::Load(const PFilePath & certFile, PSSLFileTypes fileType) { + if (fileType == PSSLFileTypeDEFAULT) + return Load(certFile, PSSLFileTypePEM) || Load(certFile, PSSLFileTypeASN1); + FreeCertificate(); PSSL_BIO in; @@ -682,6 +689,8 @@ return false; } + X509 * ca; + switch (fileType) { case PSSLFileTypeASN1 : m_certificate = d2i_X509_bio(in, NULL); @@ -693,22 +702,16 @@ case PSSLFileTypePEM : m_certificate = PEM_read_bio_X509(in, NULL, NULL, NULL); - if (m_certificate != NULL) - break; + if (m_certificate == NULL) { + PTRACE(2, "Invalid PEM certificate file \"" << certFile << '"'); + return false; + } + while ((ca = PEM_read_bio_X509(in, NULL, NULL, NULL)) != NULL) + m_chain.push_back(ca); + break; - PTRACE(2, "Invalid PEM certificate file \"" << certFile << '"'); - return false; - default : - m_certificate = PEM_read_bio_X509(in, NULL, NULL, NULL); - if (m_certificate != NULL) - break; - - m_certificate = d2i_X509_bio(in, NULL); - if (m_certificate != NULL) - break; - - PTRACE(2, "Invalid certificate file \"" << certFile << '"'); + PTRACE(2, "Unsupported certificate file \"" << certFile << '"'); return false; } @@ -2060,9 +2063,31 @@ bool PSSLContext::UseCertificate(const PSSLCertificate & certificate) { - return PAssertNULL(m_context) != NULL && - certificate.IsValid() && - SSL_CTX_use_certificate(m_context, certificate) > 0; + if (PAssertNULL(m_context) == NULL) + return false; + + if (!certificate.IsValid()) + return false; + + if (SSL_CTX_use_certificate(m_context, certificate) == 0) { + PTRACE(2, "Could not use certificate: " << PSSLError()); + return false; + } + + SSL_CTX_clear_chain_certs(m_context); + + const PSSLCertificate::X509_Chain & chain = certificate.GetChain(); + for (PSSLCertificate::X509_Chain::const_iterator it = chain.begin(); it != chain.end(); ++it) { + X509 * ca = X509_dup(*it); + if (!SSL_CTX_add0_chain_cert(m_context, ca)) { + PTRACE(2, "Could not use certificate chain: " << PSSLError()); + X509_free(ca); + return false; + } + } + + PTRACE(5, "Using certificate with " << chain.size() << " CAs in chain"); + return true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |