Chromium Code Reviews| Index: webrtc/rtc_base/opensslidentity.cc |
| diff --git a/webrtc/rtc_base/opensslidentity.cc b/webrtc/rtc_base/opensslidentity.cc |
| index a6b6e1c38eb908e076356d6c219bf2befb1293f3..5beb03723d79a18c0b184904c4599f5424d09661 100644 |
| --- a/webrtc/rtc_base/opensslidentity.cc |
| +++ b/webrtc/rtc_base/opensslidentity.cc |
| @@ -10,7 +10,9 @@ |
| #include "webrtc/rtc_base/opensslidentity.h" |
| +#include <algorithm> |
| #include <memory> |
| +#include <vector> |
| // Must be included first before openssl headers. |
| #include "webrtc/rtc_base/win32.h" // NOLINT |
| @@ -278,8 +280,22 @@ 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); |
| + AddReference(x509_); |
| + for (size_t i = 1; i < sk_X509_num(chain); ++i) { |
| + X509* x509 = sk_X509_value(chain, i); |
| + cert_chain_.push_back(new OpenSSLCertificate(x509)); |
| + } |
| +} |
| + |
| 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 +378,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; }); |
|
davidben_webrtc
2017/09/26 23:21:46
This does unnecessarily allocations since you don'
|
| + return chain; |
| } |
| bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm, |
| @@ -401,7 +425,16 @@ 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_); |
| + for (auto cert_it = cert_chain_.begin(); cert_it != cert_chain_.end(); |
| + ++cert_it) { |
| + sk_X509_push(stack_x509, (*cert_it)->x509()); |
| + } |
| + return new OpenSSLCertificate(stack_x509); |
|
davidben_webrtc
2017/09/26 23:21:46
This seems unnecessarily complicated. You could ad
|
| } |
| std::string OpenSSLCertificate::ToPEMString() const { |
| @@ -440,12 +473,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 |
| } |