summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/rtc_base/ssl_certificate.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/rtc_base/ssl_certificate.cc')
-rw-r--r--third_party/libwebrtc/rtc_base/ssl_certificate.cc139
1 files changed, 139 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/ssl_certificate.cc b/third_party/libwebrtc/rtc_base/ssl_certificate.cc
new file mode 100644
index 0000000000..d1fd57fca5
--- /dev/null
+++ b/third_party/libwebrtc/rtc_base/ssl_certificate.cc
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2004 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "rtc_base/ssl_certificate.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/algorithm/container.h"
+#include "absl/strings/string_view.h"
+#include "rtc_base/checks.h"
+#include "rtc_base/openssl.h"
+#ifdef OPENSSL_IS_BORINGSSL
+#include "rtc_base/boringssl_identity.h"
+#else
+#include "rtc_base/openssl_identity.h"
+#endif
+#include "rtc_base/ssl_fingerprint.h"
+#include "rtc_base/third_party/base64/base64.h"
+
+namespace rtc {
+
+//////////////////////////////////////////////////////////////////////
+// SSLCertificateStats
+//////////////////////////////////////////////////////////////////////
+
+SSLCertificateStats::SSLCertificateStats(
+ std::string&& fingerprint,
+ std::string&& fingerprint_algorithm,
+ std::string&& base64_certificate,
+ std::unique_ptr<SSLCertificateStats> issuer)
+ : fingerprint(std::move(fingerprint)),
+ fingerprint_algorithm(std::move(fingerprint_algorithm)),
+ base64_certificate(std::move(base64_certificate)),
+ issuer(std::move(issuer)) {}
+
+SSLCertificateStats::~SSLCertificateStats() {}
+
+std::unique_ptr<SSLCertificateStats> SSLCertificateStats::Copy() const {
+ return std::make_unique<SSLCertificateStats>(
+ std::string(fingerprint), std::string(fingerprint_algorithm),
+ std::string(base64_certificate), issuer ? issuer->Copy() : nullptr);
+}
+
+//////////////////////////////////////////////////////////////////////
+// SSLCertificate
+//////////////////////////////////////////////////////////////////////
+
+std::unique_ptr<SSLCertificateStats> SSLCertificate::GetStats() 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.
+ std::string digest_algorithm;
+ if (!GetSignatureDigestAlgorithm(&digest_algorithm))
+ return nullptr;
+
+ // `SSLFingerprint::Create` can fail if the algorithm returned by
+ // `SSLCertificate::GetSignatureDigestAlgorithm` is not supported by the
+ // implementation of `SSLCertificate::ComputeDigest`. This currently happens
+ // with MD5- and SHA-224-signed certificates when linked to libNSS.
+ std::unique_ptr<SSLFingerprint> ssl_fingerprint =
+ SSLFingerprint::Create(digest_algorithm, *this);
+ if (!ssl_fingerprint)
+ return nullptr;
+ std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
+
+ Buffer der_buffer;
+ ToDER(&der_buffer);
+ std::string der_base64;
+ Base64::EncodeFromArray(der_buffer.data(), der_buffer.size(), &der_base64);
+
+ return std::make_unique<SSLCertificateStats>(std::move(fingerprint),
+ std::move(digest_algorithm),
+ std::move(der_base64), nullptr);
+}
+
+//////////////////////////////////////////////////////////////////////
+// SSLCertChain
+//////////////////////////////////////////////////////////////////////
+
+SSLCertChain::SSLCertChain(std::unique_ptr<SSLCertificate> single_cert) {
+ certs_.push_back(std::move(single_cert));
+}
+
+SSLCertChain::SSLCertChain(std::vector<std::unique_ptr<SSLCertificate>> certs)
+ : certs_(std::move(certs)) {}
+
+SSLCertChain::SSLCertChain(SSLCertChain&& rhs) = default;
+
+SSLCertChain& SSLCertChain::operator=(SSLCertChain&&) = default;
+
+SSLCertChain::~SSLCertChain() = default;
+
+std::unique_ptr<SSLCertChain> SSLCertChain::Clone() const {
+ std::vector<std::unique_ptr<SSLCertificate>> new_certs(certs_.size());
+ absl::c_transform(
+ certs_, new_certs.begin(),
+ [](const std::unique_ptr<SSLCertificate>& cert)
+ -> std::unique_ptr<SSLCertificate> { return cert->Clone(); });
+ return std::make_unique<SSLCertChain>(std::move(new_certs));
+}
+
+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
+std::unique_ptr<SSLCertificate> SSLCertificate::FromPEMString(
+ absl::string_view pem_string) {
+#ifdef OPENSSL_IS_BORINGSSL
+ return BoringSSLCertificate::FromPEMString(pem_string);
+#else
+ return OpenSSLCertificate::FromPEMString(pem_string);
+#endif
+}
+
+} // namespace rtc