Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(679)

Unified Diff: rtc_base/opensslidentity.cc

Issue 3010363002: Implement GetChain for OpenSSLCertificate.
Patch Set: Adding unit tests and clean up. Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « rtc_base/opensslidentity.h ('k') | rtc_base/opensslidentity_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: rtc_base/opensslidentity.cc
diff --git a/rtc_base/opensslidentity.cc b/rtc_base/opensslidentity.cc
index 075a1b5485a80c745ee84b4991af0b86017df4f0..b22b0a5ca5485ca3046dd665d2c6795d57f4b445 100644
--- a/rtc_base/opensslidentity.cc
+++ b/rtc_base/opensslidentity.cc
@@ -10,7 +10,9 @@
#include "rtc_base/opensslidentity.h"
+#include <algorithm>
#include <memory>
+#include <vector>
// Must be included first before openssl headers.
#include "rtc_base/win32.h" // NOLINT
@@ -278,6 +280,19 @@ 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) {
SSLIdentityParams actual_params(params);
@@ -306,13 +321,18 @@ OpenSSLCertificate* OpenSSLCertificate::FromPEMString(
BIO_set_mem_eof_return(bio, 0);
X509* x509 =
PEM_read_bio_X509(bio, nullptr, nullptr, const_cast<char*>("\0"));
+ STACK_OF(X509)* x509s = sk_X509_new_null();
+ while (x509 != nullptr) {
+ sk_X509_push(x509s, x509);
+ x509 = PEM_read_bio_X509(bio, nullptr, nullptr, const_cast<char*>("\0"));
+ }
BIO_free(bio); // Frees the BIO, but not the pointed-to string.
- if (!x509)
+ if (sk_X509_num(x509s) == 0)
return nullptr;
- OpenSSLCertificate* ret = new OpenSSLCertificate(x509);
- X509_free(x509);
+ OpenSSLCertificate* ret = new OpenSSLCertificate(x509s);
+ sk_X509_pop_free(x509s, X509_free);
return ret;
}
@@ -362,10 +382,11 @@ 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::unique_ptr<SSLCertChain> chain(new SSLCertChain(cert_chain_));
+ return chain;
}
bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm,
@@ -398,10 +419,27 @@ bool OpenSSLCertificate::ComputeDigest(const X509* x509,
OpenSSLCertificate::~OpenSSLCertificate() {
X509_free(x509_);
+ for (SSLCertificate* cert : cert_chain_) {
+ delete cert;
+ }
+}
+
+X509* OpenSSLCertificate::GetX509Reference() const {
+ if (x509_ != nullptr) {
+ AddReference(x509_);
+ }
+ return x509_;
}
OpenSSLCertificate* OpenSSLCertificate::GetReference() const {
- 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) {
+ OpenSSLCertificate* cert = reinterpret_cast<OpenSSLCertificate*>(*cert_it);
+ sk_X509_push(stack_x509, cert->x509());
+ }
+ return new OpenSSLCertificate(stack_x509);
}
std::string OpenSSLCertificate::ToPEMString() const {
@@ -418,6 +456,11 @@ std::string OpenSSLCertificate::ToPEMString() const {
BIO_get_mem_data(bio, &buffer);
std::string ret(buffer);
BIO_free(bio);
+ for (size_t i = 0; i < cert_chain_.size(); ++i) {
+ OpenSSLCertificate* cert =
+ reinterpret_cast<OpenSSLCertificate*>(cert_chain_[i]);
+ ret += cert->ToPEMString();
+ }
return ret;
}
@@ -440,16 +483,28 @@ 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
}
bool OpenSSLCertificate::operator==(const OpenSSLCertificate& other) const {
+ if (this->cert_chain_.size() != other.cert_chain_.size()) {
+ return false;
+ }
+ for (size_t i = 0; i < cert_chain_.size(); ++i) {
+ OpenSSLCertificate* cert =
+ reinterpret_cast<OpenSSLCertificate*>(cert_chain_[i]);
+ OpenSSLCertificate* other_cert =
+ reinterpret_cast<OpenSSLCertificate*>(other.cert_chain_[i]);
+ if (*cert != *other_cert) {
+ return false;
+ }
+ }
return X509_cmp(this->x509_, other.x509_) == 0;
}
@@ -553,6 +608,16 @@ bool OpenSSLIdentity::ConfigureIdentity(SSL_CTX* ctx) {
LogSSLErrors("Configuring key and certificate");
return false;
}
+ // If Chains are available, use it.
+ std::unique_ptr<SSLCertChain> cert_chain = certificate_->GetChain();
+ for (size_t i = 0; cert_chain != nullptr && i < cert_chain->GetSize(); ++i) {
+ const OpenSSLCertificate* cert =
+ reinterpret_cast<const OpenSSLCertificate*>(&cert_chain->Get(i));
+ if (!SSL_CTX_add_extra_chain_cert(ctx, cert->GetX509Reference())) {
+ LogSSLErrors("Configuring intermediate certificate");
+ return false;
+ }
+ }
return true;
}
« no previous file with comments | « rtc_base/opensslidentity.h ('k') | rtc_base/opensslidentity_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698