Index: webrtc/rtc_base/opensslidentity.cc |
diff --git a/webrtc/rtc_base/opensslidentity.cc b/webrtc/rtc_base/opensslidentity.cc |
index a6b6e1c38eb908e076356d6c219bf2befb1293f3..590abb466fc67c6f4b9b9919f4076621c4dd0938 100644 |
--- a/webrtc/rtc_base/opensslidentity.cc |
+++ b/webrtc/rtc_base/opensslidentity.cc |
@@ -16,11 +16,11 @@ |
#include "webrtc/rtc_base/win32.h" // NOLINT |
#include <openssl/bio.h> |
+#include <openssl/bn.h> |
+#include <openssl/crypto.h> |
#include <openssl/err.h> |
#include <openssl/pem.h> |
-#include <openssl/bn.h> |
#include <openssl/rsa.h> |
-#include <openssl/crypto.h> |
#include "webrtc/rtc_base/checks.h" |
#include "webrtc/rtc_base/helpers.h" |
@@ -143,7 +143,7 @@ static X509* MakeCertificate(EVP_PKEY* pkey, const SSLIdentityParams& params) { |
LOG(LS_INFO) << "Returning certificate"; |
return x509; |
- error: |
+error: |
BN_free(serial_number); |
X509_NAME_free(name); |
X509_free(x509); |
@@ -217,8 +217,8 @@ std::string OpenSSLKeyPair::PrivateKeyToPEMString() const { |
RTC_NOTREACHED(); |
return ""; |
} |
- if (!PEM_write_bio_PrivateKey( |
- temp_memory_bio, pkey_, nullptr, nullptr, 0, nullptr, nullptr)) { |
+ if (!PEM_write_bio_PrivateKey(temp_memory_bio, pkey_, nullptr, nullptr, 0, |
+ nullptr, nullptr)) { |
LOG_F(LS_ERROR) << "Failed to write private key"; |
BIO_free(temp_memory_bio); |
RTC_NOTREACHED(); |
@@ -278,8 +278,25 @@ static void PrintCert(X509* x509) { |
} |
#endif |
+OpenSSLCertificate::OpenSSLCertificate(X509* x509) : x509_(x509) { |
+ AddReference(x509_); |
+} |
+ |
+OpenSSLCertificate::OpenSSLCertificate(STACK_OF(X509) * chain) { |
+ x509_ = sk_X509_value(chain, 0); |
+ LOG(LS_INFO) << "leaf_cert:" << x509_->name; |
Taylor Brandstetter
2017/09/26 00:57:26
Are these logs statements intended to be in the fi
pthatcher1
2017/09/26 20:55:07
Even at verbose level I'm not sure they are worth
|
+ AddReference(x509_); |
+ for (size_t i = 1; i < sk_X509_num(chain); ++i) { |
Taylor Brandstetter
2017/09/26 00:57:26
May be a dumb question, but is there a reason for
|
+ X509* x509 = sk_X509_value(chain, i); |
+ AddReference(x509); |
+ LOG(LS_INFO) << "parent certificate name:" << x509->name; |
+ cert_chain_.push_back(new OpenSSLCertificate(x509)); |
pthatcher1
2017/09/26 20:55:07
Passing in the x509 here cause the constructor to
|
+ } |
+} |
+ |
OpenSSLCertificate* OpenSSLCertificate::Generate( |
- OpenSSLKeyPair* key_pair, const SSLIdentityParams& params) { |
+ OpenSSLKeyPair* key_pair, |
+ const SSLIdentityParams& params) { |
SSLIdentityParams actual_params(params); |
if (actual_params.common_name.empty()) { |
// Use a random string, arbitrarily 8chars long. |
@@ -362,10 +379,18 @@ bool OpenSSLCertificate::GetSignatureDigestAlgorithm( |
} |
std::unique_ptr<SSLCertChain> OpenSSLCertificate::GetChain() const { |
- // Chains are not yet supported when using OpenSSL. |
- // OpenSSLStreamAdapter::SSLVerifyCallback currently requires the remote |
- // certificate to be self-signed. |
- return nullptr; |
+ if (cert_chain_.empty()) { |
+ return nullptr; |
+ } |
+ std::vector<SSLCertificate*> new_certs(cert_chain_.size()); |
+ std::transform(cert_chain_.begin(), cert_chain_.end(), new_certs.begin(), |
+ [](OpenSSLCertificate* cert) -> SSLCertificate* { |
+ return cert->GetReference(); |
+ }); |
+ std::unique_ptr<SSLCertChain> chain(new SSLCertChain(new_certs)); |
+ std::for_each(new_certs.begin(), new_certs.end(), |
+ [](SSLCertificate* cert) { delete cert; }); |
pthatcher1
2017/09/26 20:55:07
I find this confusing. We create a copy of the ve
|
+ return chain; |
} |
bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm, |
@@ -401,7 +426,18 @@ OpenSSLCertificate::~OpenSSLCertificate() { |
} |
OpenSSLCertificate* OpenSSLCertificate::GetReference() const { |
- return new OpenSSLCertificate(x509_); |
+ if (cert_chain_.empty()) { |
+ return new OpenSSLCertificate(x509_); |
+ } |
+ STACK_OF(X509)* stack_x509 = sk_X509_new_null(); |
+ sk_X509_push(stack_x509, x509_); |
+ LOG(LS_INFO) << "Push cert to stack:" << x509_->name; |
Taylor Brandstetter
2017/09/26 00:57:26
Same question about log messages. Should be verbos
|
+ for (auto cert_it = cert_chain_.begin(); cert_it != cert_chain_.end(); |
+ ++cert_it) { |
+ LOG(LS_INFO) << "Push cert to stack:" << (*cert_it)->x509()->name; |
+ sk_X509_push(stack_x509, (*cert_it)->x509()); |
+ } |
+ return new OpenSSLCertificate(stack_x509); |
} |
std::string OpenSSLCertificate::ToPEMString() const { |
@@ -440,12 +476,12 @@ void OpenSSLCertificate::ToDER(Buffer* der_buffer) const { |
BIO_free(bio); |
} |
-void OpenSSLCertificate::AddReference() const { |
- RTC_DCHECK(x509_ != nullptr); |
+void OpenSSLCertificate::AddReference(X509* x509) const { |
+ RTC_DCHECK(x509 != nullptr); |
#if defined(OPENSSL_IS_BORINGSSL) |
- X509_up_ref(x509_); |
+ X509_up_ref(x509); |
#else |
- CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); |
+ CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); |
#endif |
} |
@@ -516,9 +552,8 @@ OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( |
return GenerateInternal(params); |
} |
-SSLIdentity* OpenSSLIdentity::FromPEMStrings( |
- const std::string& private_key, |
- const std::string& certificate) { |
+SSLIdentity* OpenSSLIdentity::FromPEMStrings(const std::string& private_key, |
+ const std::string& certificate) { |
std::unique_ptr<OpenSSLCertificate> cert( |
OpenSSLCertificate::FromPEMString(certificate)); |
if (!cert) { |
@@ -533,8 +568,7 @@ SSLIdentity* OpenSSLIdentity::FromPEMStrings( |
return nullptr; |
} |
- return new OpenSSLIdentity(key_pair, |
- cert.release()); |
+ return new OpenSSLIdentity(key_pair, cert.release()); |
} |
const OpenSSLCertificate& OpenSSLIdentity::certificate() const { |
@@ -549,7 +583,7 @@ OpenSSLIdentity* OpenSSLIdentity::GetReference() const { |
bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) { |
// 1 is the documented success return code. |
if (SSL_CTX_use_certificate(ctx, certificate_->x509()) != 1 || |
- SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { |
+ SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { |
LogSSLErrors("Configuring key and certificate"); |
return false; |
} |