[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.
|