diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_base/ssl_fingerprint.cc')
-rw-r--r-- | third_party/libwebrtc/rtc_base/ssl_fingerprint.cc | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_base/ssl_fingerprint.cc b/third_party/libwebrtc/rtc_base/ssl_fingerprint.cc new file mode 100644 index 0000000000..a43bb159c3 --- /dev/null +++ b/third_party/libwebrtc/rtc_base/ssl_fingerprint.cc @@ -0,0 +1,127 @@ +/* + * Copyright 2012 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_fingerprint.h" + +#include <ctype.h> + +#include <cstdint> +#include <memory> +#include <string> + +#include "absl/algorithm/container.h" +#include "absl/strings/string_view.h" +#include "api/array_view.h" +#include "rtc_base/logging.h" +#include "rtc_base/message_digest.h" +#include "rtc_base/rtc_certificate.h" +#include "rtc_base/ssl_certificate.h" +#include "rtc_base/ssl_identity.h" +#include "rtc_base/string_encode.h" + +namespace rtc { + +SSLFingerprint* SSLFingerprint::Create(absl::string_view algorithm, + const rtc::SSLIdentity* identity) { + return CreateUnique(algorithm, *identity).release(); +} + +std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUnique( + absl::string_view algorithm, + const rtc::SSLIdentity& identity) { + return Create(algorithm, identity.certificate()); +} + +std::unique_ptr<SSLFingerprint> SSLFingerprint::Create( + absl::string_view algorithm, + const rtc::SSLCertificate& cert) { + uint8_t digest_val[64]; + size_t digest_len; + bool ret = cert.ComputeDigest(algorithm, digest_val, sizeof(digest_val), + &digest_len); + if (!ret) { + return nullptr; + } + return std::make_unique<SSLFingerprint>( + algorithm, ArrayView<const uint8_t>(digest_val, digest_len)); +} + +SSLFingerprint* SSLFingerprint::CreateFromRfc4572( + absl::string_view algorithm, + absl::string_view fingerprint) { + return CreateUniqueFromRfc4572(algorithm, fingerprint).release(); +} + +std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateUniqueFromRfc4572( + absl::string_view algorithm, + absl::string_view fingerprint) { + if (algorithm.empty() || !rtc::IsFips180DigestAlgorithm(algorithm)) + return nullptr; + + if (fingerprint.empty()) + return nullptr; + + char value[rtc::MessageDigest::kMaxSize]; + size_t value_len = + rtc::hex_decode_with_delimiter(ArrayView<char>(value), fingerprint, ':'); + if (!value_len) + return nullptr; + + return std::make_unique<SSLFingerprint>( + algorithm, + ArrayView<const uint8_t>(reinterpret_cast<uint8_t*>(value), value_len)); +} + +std::unique_ptr<SSLFingerprint> SSLFingerprint::CreateFromCertificate( + const RTCCertificate& cert) { + std::string digest_alg; + if (!cert.GetSSLCertificate().GetSignatureDigestAlgorithm(&digest_alg)) { + RTC_LOG(LS_ERROR) + << "Failed to retrieve the certificate's digest algorithm"; + return nullptr; + } + + std::unique_ptr<SSLFingerprint> fingerprint = + CreateUnique(digest_alg, *cert.identity()); + if (!fingerprint) { + RTC_LOG(LS_ERROR) << "Failed to create identity fingerprint, alg=" + << digest_alg; + } + return fingerprint; +} + +SSLFingerprint::SSLFingerprint(absl::string_view algorithm, + ArrayView<const uint8_t> digest_view) + : algorithm(algorithm), digest(digest_view.data(), digest_view.size()) {} + +SSLFingerprint::SSLFingerprint(absl::string_view algorithm, + const uint8_t* digest_in, + size_t digest_len) + : SSLFingerprint(algorithm, MakeArrayView(digest_in, digest_len)) {} + +bool SSLFingerprint::operator==(const SSLFingerprint& other) const { + return algorithm == other.algorithm && digest == other.digest; +} + +std::string SSLFingerprint::GetRfc4572Fingerprint() const { + std::string fingerprint = rtc::hex_encode_with_delimiter( + absl::string_view(digest.data<char>(), digest.size()), ':'); + absl::c_transform(fingerprint, fingerprint.begin(), ::toupper); + return fingerprint; +} + +std::string SSLFingerprint::ToString() const { + std::string fp_str = algorithm; + fp_str.append(" "); + fp_str.append(GetRfc4572Fingerprint()); + return fp_str; +} + +} // namespace rtc |