Implement certificate chain stats.
There was an implementation, but it relied on SSLCertificate::GetChain,
which was never implemented. Except in the fake certificate classes
used by the stats collector tests, hence the tests were passing.
Instead of implementing GetChain, we decided (in
https://webrtc-review.googlesource.com/c/src/+/6500) to add
methods that return a SSLCertChain directly, since it results in a
somewhat cleaner object model.
So this CL switches everything to use the "chain" methods, and gets
rid of the obsolete methods and member variables.
Bug: webrtc:8920
Change-Id: Ie9d7d53654ba859535462521b54c788adec7badf
Reviewed-on: https://webrtc-review.googlesource.com/56961
Commit-Queue: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Zhi Huang <zhihuang@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22177}
diff --git a/rtc_base/fakesslidentity.cc b/rtc_base/fakesslidentity.cc
index 296f09c..825c89b 100644
--- a/rtc_base/fakesslidentity.cc
+++ b/rtc_base/fakesslidentity.cc
@@ -20,19 +20,10 @@
namespace rtc {
-FakeSSLCertificate::FakeSSLCertificate(const std::string& data)
- : data_(data), digest_algorithm_(DIGEST_SHA_1), expiration_time_(-1) {}
-
-FakeSSLCertificate::FakeSSLCertificate(const std::vector<std::string>& certs)
- : data_(certs.front()),
+FakeSSLCertificate::FakeSSLCertificate(const std::string& pem_string)
+ : pem_string_(pem_string),
digest_algorithm_(DIGEST_SHA_1),
- expiration_time_(-1) {
- std::vector<std::string>::const_iterator it;
- // Skip certs[0].
- for (it = certs.begin() + 1; it != certs.end(); ++it) {
- certs_.push_back(FakeSSLCertificate(*it));
- }
-}
+ expiration_time_(-1) {}
FakeSSLCertificate::FakeSSLCertificate(const FakeSSLCertificate&) = default;
@@ -43,12 +34,13 @@
}
std::string FakeSSLCertificate::ToPEMString() const {
- return data_;
+ return pem_string_;
}
void FakeSSLCertificate::ToDER(Buffer* der_buffer) const {
std::string der_string;
- RTC_CHECK(SSLIdentity::PemToDer(kPemTypeCertificate, data_, &der_string));
+ RTC_CHECK(
+ SSLIdentity::PemToDer(kPemTypeCertificate, pem_string_, &der_string));
der_buffer->SetData(der_string.c_str(), der_string.size());
}
@@ -74,30 +66,40 @@
unsigned char* digest,
size_t size,
size_t* length) const {
- *length =
- rtc::ComputeDigest(algorithm, data_.c_str(), data_.size(), digest, size);
+ *length = rtc::ComputeDigest(algorithm, pem_string_.c_str(),
+ pem_string_.size(), digest, size);
return (*length != 0);
}
-std::unique_ptr<SSLCertChain> FakeSSLCertificate::GetChain() const {
- if (certs_.empty())
- return nullptr;
- std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
- std::transform(certs_.begin(), certs_.end(), new_certs.begin(), DupCert);
- return MakeUnique<SSLCertChain>(std::move(new_certs));
+FakeSSLIdentity::FakeSSLIdentity(const std::string& pem_string)
+ : FakeSSLIdentity(FakeSSLCertificate(pem_string)) {}
+
+FakeSSLIdentity::FakeSSLIdentity(const std::vector<std::string>& pem_strings) {
+ std::vector<std::unique_ptr<SSLCertificate>> certs;
+ for (const std::string& pem_string : pem_strings) {
+ certs.push_back(MakeUnique<FakeSSLCertificate>(pem_string));
+ }
+ cert_chain_ = MakeUnique<SSLCertChain>(std::move(certs));
}
-FakeSSLIdentity::FakeSSLIdentity(const std::string& data) : cert_(data) {}
-
FakeSSLIdentity::FakeSSLIdentity(const FakeSSLCertificate& cert)
- : cert_(cert) {}
+ : cert_chain_(MakeUnique<SSLCertChain>(&cert)) {}
+
+FakeSSLIdentity::FakeSSLIdentity(const FakeSSLIdentity& o)
+ : cert_chain_(o.cert_chain_->UniqueCopy()) {}
+
+FakeSSLIdentity::~FakeSSLIdentity() = default;
FakeSSLIdentity* FakeSSLIdentity::GetReference() const {
return new FakeSSLIdentity(*this);
}
-const FakeSSLCertificate& FakeSSLIdentity::certificate() const {
- return cert_;
+const SSLCertificate& FakeSSLIdentity::certificate() const {
+ return cert_chain_->Get(0);
+}
+
+const SSLCertChain& FakeSSLIdentity::cert_chain() const {
+ return *cert_chain_.get();
}
std::string FakeSSLIdentity::PrivateKeyToPEMString() const {
diff --git a/rtc_base/fakesslidentity.h b/rtc_base/fakesslidentity.h
index 52aaf05..4494a52 100644
--- a/rtc_base/fakesslidentity.h
+++ b/rtc_base/fakesslidentity.h
@@ -18,13 +18,11 @@
namespace rtc {
-class FakeSSLCertificate : public rtc::SSLCertificate {
+class FakeSSLCertificate : public SSLCertificate {
public:
// SHA-1 is the default digest algorithm because it is available in all build
// configurations used for unit testing.
- explicit FakeSSLCertificate(const std::string& data);
-
- explicit FakeSSLCertificate(const std::vector<std::string>& certs);
+ explicit FakeSSLCertificate(const std::string& pem_string);
FakeSSLCertificate(const FakeSSLCertificate&);
~FakeSSLCertificate() override;
@@ -39,32 +37,33 @@
unsigned char* digest,
size_t size,
size_t* length) const override;
- std::unique_ptr<SSLCertChain> GetChain() const override;
void SetCertificateExpirationTime(int64_t expiration_time);
void set_digest_algorithm(const std::string& algorithm);
private:
- static std::unique_ptr<SSLCertificate> DupCert(FakeSSLCertificate cert) {
- return cert.GetUniqueReference();
- }
- static void DeleteCert(SSLCertificate* cert) { delete cert; }
- std::string data_;
- std::vector<FakeSSLCertificate> certs_;
+ std::string pem_string_;
std::string digest_algorithm_;
// Expiration time in seconds relative to epoch, 1970-01-01T00:00:00Z (UTC).
int64_t expiration_time_;
};
-class FakeSSLIdentity : public rtc::SSLIdentity {
+class FakeSSLIdentity : public SSLIdentity {
public:
- explicit FakeSSLIdentity(const std::string& data);
+ explicit FakeSSLIdentity(const std::string& pem_string);
+ // For a certificate chain.
+ explicit FakeSSLIdentity(const std::vector<std::string>& pem_strings);
explicit FakeSSLIdentity(const FakeSSLCertificate& cert);
+ explicit FakeSSLIdentity(const FakeSSLIdentity& o);
+
+ ~FakeSSLIdentity() override;
+
// SSLIdentity implementation.
FakeSSLIdentity* GetReference() const override;
- const FakeSSLCertificate& certificate() const override;
+ const SSLCertificate& certificate() const override;
+ const SSLCertChain& cert_chain() const override;
// Not implemented.
std::string PrivateKeyToPEMString() const override;
// Not implemented.
@@ -73,7 +72,7 @@
virtual bool operator==(const SSLIdentity& other) const;
private:
- FakeSSLCertificate cert_;
+ std::unique_ptr<SSLCertChain> cert_chain_;
};
} // namespace rtc
diff --git a/rtc_base/opensslidentity.cc b/rtc_base/opensslidentity.cc
index 69ce5ac..9f7c63b 100644
--- a/rtc_base/opensslidentity.cc
+++ b/rtc_base/opensslidentity.cc
@@ -366,10 +366,6 @@
return true;
}
-std::unique_ptr<SSLCertChain> OpenSSLCertificate::GetChain() const {
- return nullptr;
-}
-
bool OpenSSLCertificate::ComputeDigest(const std::string& algorithm,
unsigned char* digest,
size_t size,
@@ -590,6 +586,10 @@
return *static_cast<const OpenSSLCertificate*>(&cert_chain_->Get(0));
}
+const SSLCertChain& OpenSSLIdentity::cert_chain() const {
+ return *cert_chain_.get();
+}
+
OpenSSLIdentity* OpenSSLIdentity::GetReference() const {
return new OpenSSLIdentity(WrapUnique(key_pair_->GetReference()),
WrapUnique(cert_chain_->Copy()));
diff --git a/rtc_base/opensslidentity.h b/rtc_base/opensslidentity.h
index a700a1d..c1dc49f 100644
--- a/rtc_base/opensslidentity.h
+++ b/rtc_base/opensslidentity.h
@@ -92,7 +92,6 @@
size_t* length);
bool GetSignatureDigestAlgorithm(std::string* algorithm) const override;
- std::unique_ptr<SSLCertChain> GetChain() const override;
int64_t CertificateExpirationTime() const override;
@@ -118,6 +117,7 @@
~OpenSSLIdentity() override;
const OpenSSLCertificate& certificate() const override;
+ const SSLCertChain& cert_chain() const override;
OpenSSLIdentity* GetReference() const override;
// Configure an SSL context object to use our key and certificate.
diff --git a/rtc_base/opensslstreamadapter.cc b/rtc_base/opensslstreamadapter.cc
index d715e27..c0fb108 100644
--- a/rtc_base/opensslstreamadapter.cc
+++ b/rtc_base/opensslstreamadapter.cc
@@ -288,13 +288,6 @@
role_ = role;
}
-std::unique_ptr<SSLCertificate> OpenSSLStreamAdapter::GetPeerCertificate()
- const {
- return peer_certificate_ ? std::unique_ptr<SSLCertificate>(
- peer_certificate_->GetReference())
- : nullptr;
-}
-
bool OpenSSLStreamAdapter::SetPeerCertificateDigest(
const std::string& digest_alg,
const unsigned char* digest_val,
@@ -324,7 +317,7 @@
peer_certificate_digest_value_.SetData(digest_val, digest_len);
peer_certificate_digest_algorithm_ = digest_alg;
- if (!peer_certificate_) {
+ if (!peer_cert_chain_) {
// Normal case, where the digest is set before we obtain the certificate
// from the handshake.
return true;
@@ -831,7 +824,7 @@
RTC_LOG(LS_VERBOSE) << " -- success";
// By this point, OpenSSL should have given us a certificate, or errored
// out if one was missing.
- RTC_DCHECK(peer_certificate_ || !client_auth_enabled());
+ RTC_DCHECK(peer_cert_chain_ || !client_auth_enabled());
state_ = SSL_CONNECTED;
if (!waiting_to_verify_peer_certificate()) {
@@ -928,7 +921,7 @@
ssl_ctx_ = nullptr;
}
identity_.reset();
- peer_certificate_.reset();
+ peer_cert_chain_.reset();
// Clear the DTLS timer
Thread::Current()->Clear(this, MSG_TIMEOUT);
@@ -1062,15 +1055,18 @@
}
bool OpenSSLStreamAdapter::VerifyPeerCertificate() {
- if (!has_peer_certificate_digest() || !peer_certificate_) {
+ if (!has_peer_certificate_digest() || !peer_cert_chain_ ||
+ !peer_cert_chain_->GetSize()) {
RTC_LOG(LS_WARNING) << "Missing digest or peer certificate.";
return false;
}
+ const OpenSSLCertificate* leaf_cert =
+ static_cast<const OpenSSLCertificate*>(&peer_cert_chain_->Get(0));
unsigned char digest[EVP_MAX_MD_SIZE];
size_t digest_length;
if (!OpenSSLCertificate::ComputeDigest(
- peer_certificate_->x509(), peer_certificate_digest_algorithm_, digest,
+ leaf_cert->x509(), peer_certificate_digest_algorithm_, digest,
sizeof(digest), &digest_length)) {
RTC_LOG(LS_WARNING) << "Failed to compute peer cert digest.";
return false;
@@ -1092,7 +1088,7 @@
std::unique_ptr<SSLCertChain> OpenSSLStreamAdapter::GetPeerSSLCertChain()
const {
- return std::unique_ptr<SSLCertChain>(peer_cert_chain_->Copy());
+ return peer_cert_chain_ ? peer_cert_chain_->UniqueCopy() : nullptr;
}
int OpenSSLStreamAdapter::SSLVerifyCallback(X509_STORE_CTX* store, void* arg) {
@@ -1104,9 +1100,6 @@
#if defined(OPENSSL_IS_BORINGSSL)
STACK_OF(X509)* chain = SSL_get_peer_full_cert_chain(ssl);
- // Creates certificate.
- stream->peer_certificate_.reset(
- new OpenSSLCertificate(sk_X509_value(chain, 0)));
// Creates certificate chain.
std::vector<std::unique_ptr<SSLCertificate>> cert_chain;
for (X509* cert : chain) {
@@ -1116,7 +1109,8 @@
#else
// Record the peer's certificate.
X509* cert = SSL_get_peer_certificate(ssl);
- stream->peer_certificate_.reset(new OpenSSLCertificate(cert));
+ stream->peer_cert_chain_.reset(
+ new SSLCertChain(new OpenSSLCertificate(cert)));
X509_free(cert);
#endif
diff --git a/rtc_base/opensslstreamadapter.h b/rtc_base/opensslstreamadapter.h
index b43dcc7..97ab557 100644
--- a/rtc_base/opensslstreamadapter.h
+++ b/rtc_base/opensslstreamadapter.h
@@ -69,8 +69,6 @@
size_t digest_len,
SSLPeerCertificateDigestError* error = nullptr) override;
- std::unique_ptr<SSLCertificate> GetPeerCertificate() const override;
-
std::unique_ptr<SSLCertChain> GetPeerSSLCertChain() const override;
// Goes from state SSL_NONE to either SSL_CONNECTING or SSL_WAIT, depending
@@ -197,9 +195,8 @@
// Our key and certificate.
std::unique_ptr<OpenSSLIdentity> identity_;
- // The certificate that the peer presented. Initially null, until the
+ // The certificate chain that the peer presented. Initially null, until the
// connection is established.
- std::unique_ptr<OpenSSLCertificate> peer_certificate_;
std::unique_ptr<SSLCertChain> peer_cert_chain_;
bool peer_certificate_verified_ = false;
// The digest of the certificate that the peer must present.
diff --git a/rtc_base/rtccertificate.cc b/rtc_base/rtccertificate.cc
index dd6f40a..2887895 100644
--- a/rtc_base/rtccertificate.cc
+++ b/rtc_base/rtccertificate.cc
@@ -46,6 +46,10 @@
return identity_->certificate();
}
+const SSLCertChain& RTCCertificate::ssl_cert_chain() const {
+ return identity_->cert_chain();
+}
+
RTCCertificatePEM RTCCertificate::ToPEM() const {
return RTCCertificatePEM(identity_->PrivateKeyToPEMString(),
ssl_certificate().ToPEMString());
diff --git a/rtc_base/rtccertificate.h b/rtc_base/rtccertificate.h
index 47f0e0c..f13caba 100644
--- a/rtc_base/rtccertificate.h
+++ b/rtc_base/rtccertificate.h
@@ -58,6 +58,7 @@
// relative to epoch, 1970-01-01T00:00:00Z.
bool HasExpired(uint64_t now) const;
const SSLCertificate& ssl_certificate() const;
+ const SSLCertChain& ssl_cert_chain() const;
// TODO(hbos): If possible, remove once RTCCertificate and its
// ssl_certificate() is used in all relevant places. Should not pass around
diff --git a/rtc_base/sslidentity.cc b/rtc_base/sslidentity.cc
index e035d9e..1514e52 100644
--- a/rtc_base/sslidentity.cc
+++ b/rtc_base/sslidentity.cc
@@ -43,30 +43,6 @@
}
std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats() const {
- // We have a certificate and optionally a chain of certificates. This forms a
- // linked list, starting with |this|, then the first element of |chain| and
- // ending with the last element of |chain|. The "issuer" of a certificate is
- // the next certificate in the chain. Stats are produced for each certificate
- // in the list. Here, the "issuer" is the issuer's stats.
- std::unique_ptr<SSLCertChain> chain = GetChain();
- std::unique_ptr<SSLCertificateStats> issuer;
- if (chain) {
- // The loop runs in reverse so that the |issuer| is known before the
- // |cert|'s stats.
- for (ptrdiff_t i = chain->GetSize() - 1; i >= 0; --i) {
- const SSLCertificate* cert = &chain->Get(i);
- issuer = cert->GetStats(std::move(issuer));
- }
- }
- return GetStats(std::move(issuer));
-}
-
-std::unique_ptr<SSLCertificate> SSLCertificate::GetUniqueReference() const {
- return WrapUnique(GetReference());
-}
-
-std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats(
- std::unique_ptr<SSLCertificateStats> issuer) const {
// TODO(bemasc): Move this computation to a helper class that caches these
// values to reduce CPU use in |StatsCollector::GetStats|. This will require
// adding a fast |SSLCertificate::Equals| to detect certificate changes.
@@ -89,11 +65,13 @@
std::string der_base64;
Base64::EncodeFromArray(der_buffer.data(), der_buffer.size(), &der_base64);
- return std::unique_ptr<SSLCertificateStats>(new SSLCertificateStats(
- std::move(fingerprint),
- std::move(digest_algorithm),
- std::move(der_base64),
- std::move(issuer)));
+ return rtc::MakeUnique<SSLCertificateStats>(std::move(fingerprint),
+ std::move(digest_algorithm),
+ std::move(der_base64), nullptr);
+}
+
+std::unique_ptr<SSLCertificate> SSLCertificate::GetUniqueReference() const {
+ return WrapUnique(GetReference());
}
KeyParams::KeyParams(KeyType key_type) {
@@ -228,6 +206,28 @@
return new SSLCertChain(std::move(new_certs));
}
+std::unique_ptr<SSLCertChain> SSLCertChain::UniqueCopy() const {
+ return WrapUnique(Copy());
+}
+
+std::unique_ptr<SSLCertificateStats> SSLCertChain::GetStats() const {
+ // We have a linked list of certificates, starting with the first element of
+ // |certs_| and ending with the last element of |certs_|. The "issuer" of a
+ // certificate is the next certificate in the chain. Stats are produced for
+ // each certificate in the list. Here, the "issuer" is the issuer's stats.
+ std::unique_ptr<SSLCertificateStats> issuer;
+ // The loop runs in reverse so that the |issuer| is known before the
+ // certificate issued by |issuer|.
+ for (ptrdiff_t i = certs_.size() - 1; i >= 0; --i) {
+ std::unique_ptr<SSLCertificateStats> new_stats = certs_[i]->GetStats();
+ if (new_stats) {
+ new_stats->issuer = std::move(issuer);
+ }
+ issuer = std::move(new_stats);
+ }
+ return issuer;
+}
+
// static
SSLCertificate* SSLCertificate::FromPEMString(const std::string& pem_string) {
return OpenSSLCertificate::FromPEMString(pem_string);
diff --git a/rtc_base/sslidentity.h b/rtc_base/sslidentity.h
index 952e2ab..d14610b 100644
--- a/rtc_base/sslidentity.h
+++ b/rtc_base/sslidentity.h
@@ -67,10 +67,6 @@
std::unique_ptr<SSLCertificate> GetUniqueReference() const;
- // Returns null. This is deprecated. Please use
- // SSLStreamAdapter::GetPeerSSLCertChain
- virtual std::unique_ptr<SSLCertChain> GetChain() const = 0;
-
// Returns a PEM encoded string representation of the certificate.
virtual std::string ToPEMString() const = 0;
@@ -91,14 +87,10 @@
// or -1 if an expiration time could not be retrieved.
virtual int64_t CertificateExpirationTime() const = 0;
- // Gets information (fingerprint, etc.) about this certificate and its chain
- // (if it has a certificate chain). This is used for certificate stats, see
+ // Gets information (fingerprint, etc.) about this certificate. This is used
+ // for certificate stats, see
// https://w3c.github.io/webrtc-stats/#certificatestats-dict*.
std::unique_ptr<SSLCertificateStats> GetStats() const;
-
- private:
- std::unique_ptr<SSLCertificateStats> GetStats(
- std::unique_ptr<SSLCertificateStats> issuer) const;
};
// SSLCertChain is a simple wrapper for a vector of SSLCertificates. It serves
@@ -122,6 +114,13 @@
// Returns a new SSLCertChain object instance wrapping the same underlying
// certificate chain. Caller is responsible for freeing the returned object.
SSLCertChain* Copy() const;
+ // Same as above, but returning a unique_ptr for convenience.
+ std::unique_ptr<SSLCertChain> UniqueCopy() const;
+
+ // Gets information (fingerprint, etc.) about this certificate chain. This is
+ // used for certificate stats, see
+ // https://w3c.github.io/webrtc-stats/#certificatestats-dict*.
+ std::unique_ptr<SSLCertificateStats> GetStats() const;
private:
std::vector<std::unique_ptr<SSLCertificate>> certs_;
@@ -241,8 +240,10 @@
// TODO(hbos,torbjorng): Rename to a less confusing name.
virtual SSLIdentity* GetReference() const = 0;
- // Returns a temporary reference to the certificate.
+ // Returns a temporary reference to the end-entity (leaf) certificate.
virtual const SSLCertificate& certificate() const = 0;
+ // Returns a temporary reference to the entire certificate chain.
+ virtual const SSLCertChain& cert_chain() const = 0;
virtual std::string PrivateKeyToPEMString() const = 0;
virtual std::string PublicKeyToPEMString() const = 0;
diff --git a/rtc_base/sslidentity_unittest.cc b/rtc_base/sslidentity_unittest.cc
index c26d8d7..e1dbe05 100644
--- a/rtc_base/sslidentity_unittest.cc
+++ b/rtc_base/sslidentity_unittest.cc
@@ -175,8 +175,7 @@
reinterpret_cast<const unsigned char*>(der.c_str()),
der.length()));
}
- info.identity.reset(
- new rtc::FakeSSLIdentity(rtc::FakeSSLCertificate(info.pems)));
+ info.identity.reset(new rtc::FakeSSLIdentity(info.pems));
// Strip header/footer and newline characters of PEM strings.
for (size_t i = 0; i < info.pems.size(); ++i) {
rtc::replace_substrs("-----BEGIN CERTIFICATE-----", 27,
@@ -186,20 +185,14 @@
rtc::replace_substrs("\n", 1,
"", 0, &info.pems[i]);
}
- // Fingerprint of leaf certificate.
- std::unique_ptr<rtc::SSLFingerprint> fp(
- rtc::SSLFingerprint::Create("sha-1", &info.identity->certificate()));
- EXPECT_TRUE(fp);
- info.fingerprints.push_back(fp->GetRfc4572Fingerprint());
- // Fingerprints of the rest of the chain.
- std::unique_ptr<rtc::SSLCertChain> chain =
- info.identity->certificate().GetChain();
- if (chain) {
- for (size_t i = 0; i < chain->GetSize(); i++) {
- fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain->Get(i)));
- EXPECT_TRUE(fp);
- info.fingerprints.push_back(fp->GetRfc4572Fingerprint());
- }
+ // Fingerprints for the whole certificate chain, starting with leaf
+ // certificate.
+ const rtc::SSLCertChain& chain = info.identity->cert_chain();
+ std::unique_ptr<rtc::SSLFingerprint> fp;
+ for (size_t i = 0; i < chain.GetSize(); i++) {
+ fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain.Get(i)));
+ EXPECT_TRUE(fp);
+ info.fingerprints.push_back(fp->GetRfc4572Fingerprint());
}
EXPECT_EQ(info.ders.size(), info.fingerprints.size());
return info;
@@ -477,7 +470,7 @@
EXPECT_EQ(info.fingerprints.size(), info.ders.size());
std::unique_ptr<rtc::SSLCertificateStats> first_stats =
- info.identity->certificate().GetStats();
+ info.identity->cert_chain().GetStats();
rtc::SSLCertificateStats* cert_stats = first_stats.get();
for (size_t i = 0; i < info.ders.size(); ++i) {
EXPECT_EQ(cert_stats->fingerprint, info.fingerprints[i]);
diff --git a/rtc_base/sslstreamadapter.h b/rtc_base/sslstreamadapter.h
index 560dd59..c04fb34 100644
--- a/rtc_base/sslstreamadapter.h
+++ b/rtc_base/sslstreamadapter.h
@@ -201,11 +201,7 @@
size_t digest_len,
SSLPeerCertificateDigestError* error = nullptr) = 0;
- // Retrieves the peer's X.509 certificate, if a connection has been
- // established.
- virtual std::unique_ptr<SSLCertificate> GetPeerCertificate() const = 0;
-
- // Retrieves the peer's certificate chain including leaf, if a
+ // Retrieves the peer's certificate chain including leaf certificate, if a
// connection has been established.
virtual std::unique_ptr<SSLCertChain> GetPeerSSLCertChain() const = 0;
diff --git a/rtc_base/sslstreamadapter_unittest.cc b/rtc_base/sslstreamadapter_unittest.cc
index 41ff09b..ce96274 100644
--- a/rtc_base/sslstreamadapter_unittest.cc
+++ b/rtc_base/sslstreamadapter_unittest.cc
@@ -597,10 +597,13 @@
}
std::unique_ptr<rtc::SSLCertificate> GetPeerCertificate(bool client) {
+ std::unique_ptr<rtc::SSLCertChain> chain;
if (client)
- return client_ssl_->GetPeerCertificate();
+ chain = client_ssl_->GetPeerSSLCertChain();
else
- return server_ssl_->GetPeerCertificate();
+ chain = server_ssl_->GetPeerSSLCertChain();
+ return (chain && chain->GetSize()) ? chain->Get(0).GetUniqueReference()
+ : nullptr;
}
bool GetSslCipherSuite(bool client, int* retval) {
@@ -971,11 +974,10 @@
TestHandshake();
std::unique_ptr<rtc::SSLCertChain> cert_chain =
client_ssl_->GetPeerSSLCertChain();
- std::unique_ptr<rtc::SSLCertificate> certificate =
- client_ssl_->GetPeerCertificate();
ASSERT_NE(nullptr, cert_chain);
EXPECT_EQ(1u, cert_chain->GetSize());
- EXPECT_EQ(cert_chain->Get(0).ToPEMString(), certificate->ToPEMString());
+ EXPECT_EQ(cert_chain->Get(0).ToPEMString(),
+ server_identity_->certificate().ToPEMString());
}
TEST_F(SSLStreamAdapterTestDTLSCertChain, TwoCertHandshake) {
@@ -1388,9 +1390,6 @@
std::string client_peer_string = client_peer_cert->ToPEMString();
ASSERT_NE(kCERT_PEM, client_peer_string);
- // It must not have a chain, because the test certs are self-signed.
- ASSERT_FALSE(client_peer_cert->GetChain());
-
// The server should have a peer certificate after the handshake.
std::unique_ptr<rtc::SSLCertificate> server_peer_cert =
GetPeerCertificate(false);
@@ -1398,9 +1397,6 @@
// It's kCERT_PEM
ASSERT_EQ(kCERT_PEM, server_peer_cert->ToPEMString());
-
- // It must not have a chain, because the test certs are self-signed.
- ASSERT_FALSE(server_peer_cert->GetChain());
}
// Test getting the used DTLS ciphers.