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

Unified Diff: components/cast_channel/cast_auth_util.cc

Issue 2926313002: Revert of [cast_channel] Move cast_channel related files from //extensions to //components (Closed)
Patch Set: Created 3 years, 6 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 | « components/cast_channel/cast_auth_util.h ('k') | components/cast_channel/cast_auth_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/cast_channel/cast_auth_util.cc
diff --git a/components/cast_channel/cast_auth_util.cc b/components/cast_channel/cast_auth_util.cc
deleted file mode 100644
index 82caae579a2d33537b3e8537b2e4427f27f48342..0000000000000000000000000000000000000000
--- a/components/cast_channel/cast_auth_util.cc
+++ /dev/null
@@ -1,394 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/cast_channel/cast_auth_util.h"
-
-#include <vector>
-
-#include "base/feature_list.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/memory/singleton.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_util.h"
-#include "base/strings/stringprintf.h"
-#include "components/cast_certificate/cast_cert_validator.h"
-#include "components/cast_certificate/cast_crl.h"
-#include "components/cast_channel/cast_message_util.h"
-#include "components/cast_channel/proto/cast_channel.pb.h"
-#include "crypto/random.h"
-#include "net/cert/x509_certificate.h"
-#include "net/der/parse_values.h"
-
-namespace cast_channel {
-namespace {
-
-const char kParseErrorPrefix[] = "Failed to parse auth message: ";
-
-// The maximum number of days a cert can live for.
-const int kMaxSelfSignedCertLifetimeInDays = 4;
-
-// The size of the nonce challenge in bytes.
-const int kNonceSizeInBytes = 16;
-
-// The number of hours after which a nonce is regenerated.
-long kNonceExpirationTimeInHours = 24;
-
-// Enforce certificate revocation when enabled.
-// If disabled, any revocation failures are ignored.
-//
-// This flags only controls the enforcement. Revocation is checked regardless.
-//
-// This flag tracks the changes necessary to fully enforce revocation.
-const base::Feature kEnforceRevocationChecking{
- "CastCertificateRevocation", base::FEATURE_DISABLED_BY_DEFAULT};
-
-// Enforce nonce checking when enabled.
-// If disabled, the nonce value returned from the device is not checked against
-// the one sent to the device. As a result, the nonce can be empty and omitted
-// from the signature. This allows backwards compatibility with legacy Cast
-// receivers.
-
-const base::Feature kEnforceNonceChecking{"CastNonceEnforced",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
-namespace cast_crypto = ::cast_certificate;
-
-// Extracts an embedded DeviceAuthMessage payload from an auth challenge reply
-// message.
-AuthResult ParseAuthMessage(const CastMessage& challenge_reply,
- DeviceAuthMessage* auth_message) {
- if (challenge_reply.payload_type() != CastMessage_PayloadType_BINARY) {
- return AuthResult::CreateWithParseError(
- "Wrong payload type in challenge reply",
- AuthResult::ERROR_WRONG_PAYLOAD_TYPE);
- }
- if (!challenge_reply.has_payload_binary()) {
- return AuthResult::CreateWithParseError(
- "Payload type is binary but payload_binary field not set",
- AuthResult::ERROR_NO_PAYLOAD);
- }
- if (!auth_message->ParseFromString(challenge_reply.payload_binary())) {
- return AuthResult::CreateWithParseError(
- "Cannot parse binary payload into DeviceAuthMessage",
- AuthResult::ERROR_PAYLOAD_PARSING_FAILED);
- }
-
- VLOG(1) << "Auth message: " << AuthMessageToString(*auth_message);
-
- if (auth_message->has_error()) {
- return AuthResult::CreateWithParseError(
- "Auth message error: " +
- base::IntToString(auth_message->error().error_type()),
- AuthResult::ERROR_MESSAGE_ERROR);
- }
- if (!auth_message->has_response()) {
- return AuthResult::CreateWithParseError(
- "Auth message has no response field", AuthResult::ERROR_NO_RESPONSE);
- }
- return AuthResult();
-}
-
-class CastNonce {
- public:
- static CastNonce* GetInstance() {
- return base::Singleton<CastNonce,
- base::LeakySingletonTraits<CastNonce>>::get();
- }
-
- static const std::string& Get() {
- GetInstance()->EnsureNonceTimely();
- return GetInstance()->nonce_;
- }
-
- private:
- friend struct base::DefaultSingletonTraits<CastNonce>;
-
- CastNonce() { GenerateNonce(); }
- void GenerateNonce() {
- // Create a cryptographically secure nonce.
- crypto::RandBytes(base::WriteInto(&nonce_, kNonceSizeInBytes + 1),
- kNonceSizeInBytes);
- nonce_generation_time_ = base::Time::Now();
- }
-
- void EnsureNonceTimely() {
- if (base::Time::Now() >
- (nonce_generation_time_ +
- base::TimeDelta::FromHours(kNonceExpirationTimeInHours))) {
- GenerateNonce();
- }
- }
-
- // The nonce challenge to send to the Cast receiver.
- // The nonce is updated daily.
- std::string nonce_;
- base::Time nonce_generation_time_;
-};
-
-// Must match with histogram enum CastCertificateStatus.
-// This should never be reordered.
-enum CertVerificationStatus {
- CERT_STATUS_OK,
- CERT_STATUS_INVALID_CRL,
- CERT_STATUS_VERIFICATION_FAILED,
- CERT_STATUS_REVOKED,
- CERT_STATUS_COUNT,
-};
-
-// Must match with histogram enum CastNonce.
-// This should never be reordered.
-enum NonceVerificationStatus {
- NONCE_MATCH,
- NONCE_MISMATCH,
- NONCE_MISSING,
- NONCE_COUNT,
-};
-
-// Record certificate verification histogram events.
-void RecordCertificateEvent(CertVerificationStatus event) {
- UMA_HISTOGRAM_ENUMERATION("Cast.Channel.Certificate", event,
- CERT_STATUS_COUNT);
-}
-
-// Record nonce verification histogram events.
-void RecordNonceEvent(NonceVerificationStatus event) {
- UMA_HISTOGRAM_ENUMERATION("Cast.Channel.Nonce", event, NONCE_COUNT);
-}
-
-} // namespace
-
-AuthResult::AuthResult()
- : error_type(ERROR_NONE), channel_policies(POLICY_NONE) {}
-
-AuthResult::AuthResult(const std::string& error_message, ErrorType error_type)
- : error_message(error_message), error_type(error_type) {}
-
-AuthResult::~AuthResult() {}
-
-// static
-AuthResult AuthResult::CreateWithParseError(const std::string& error_message,
- ErrorType error_type) {
- return AuthResult(kParseErrorPrefix + error_message, error_type);
-}
-
-// static
-AuthContext AuthContext::Create() {
- return AuthContext(CastNonce::Get());
-}
-
-AuthContext::AuthContext(const std::string& nonce) : nonce_(nonce) {}
-
-AuthContext::~AuthContext() {}
-
-AuthResult AuthContext::VerifySenderNonce(
- const std::string& nonce_response) const {
- if (nonce_ != nonce_response) {
- if (nonce_response.empty()) {
- RecordNonceEvent(NONCE_MISSING);
- } else {
- RecordNonceEvent(NONCE_MISMATCH);
- }
- if (base::FeatureList::IsEnabled(kEnforceNonceChecking)) {
- return AuthResult("Sender nonce mismatched.",
- AuthResult::ERROR_SENDER_NONCE_MISMATCH);
- }
- } else {
- RecordNonceEvent(NONCE_MATCH);
- }
- return AuthResult();
-}
-
-// Verifies the peer certificate and populates |peer_cert_der| with the DER
-// encoded certificate.
-AuthResult VerifyTLSCertificate(const net::X509Certificate& peer_cert,
- std::string* peer_cert_der,
- const base::Time& verification_time) {
- // Get the DER-encoded form of the certificate.
- if (!net::X509Certificate::GetDEREncoded(peer_cert.os_cert_handle(),
- peer_cert_der) ||
- peer_cert_der->empty()) {
- return AuthResult::CreateWithParseError(
- "Could not create DER-encoded peer cert.",
- AuthResult::ERROR_CERT_PARSING_FAILED);
- }
-
- // Ensure the peer cert is valid and doesn't have an excessive remaining
- // lifetime. Although it is not verified as an X.509 certificate, the entire
- // structure is signed by the AuthResponse, so the validity field from X.509
- // is repurposed as this signature's expiration.
- base::Time expiry = peer_cert.valid_expiry();
- base::Time lifetime_limit =
- verification_time +
- base::TimeDelta::FromDays(kMaxSelfSignedCertLifetimeInDays);
- if (peer_cert.valid_start().is_null() ||
- peer_cert.valid_start() > verification_time) {
- return AuthResult::CreateWithParseError(
- "Certificate's valid start date is in the future.",
- AuthResult::ERROR_TLS_CERT_VALID_START_DATE_IN_FUTURE);
- }
- if (expiry.is_null() || peer_cert.valid_expiry() < verification_time) {
- return AuthResult::CreateWithParseError("Certificate has expired.",
- AuthResult::ERROR_TLS_CERT_EXPIRED);
- }
- if (expiry > lifetime_limit) {
- return AuthResult::CreateWithParseError(
- "Peer cert lifetime is too long.",
- AuthResult::ERROR_TLS_CERT_VALIDITY_PERIOD_TOO_LONG);
- }
- return AuthResult();
-}
-
-AuthResult AuthenticateChallengeReply(const CastMessage& challenge_reply,
- const net::X509Certificate& peer_cert,
- const AuthContext& auth_context) {
- DeviceAuthMessage auth_message;
- AuthResult result = ParseAuthMessage(challenge_reply, &auth_message);
- if (!result.success()) {
- return result;
- }
-
- std::string peer_cert_der;
- result = VerifyTLSCertificate(peer_cert, &peer_cert_der, base::Time::Now());
- if (!result.success()) {
- return result;
- }
-
- const AuthResponse& response = auth_message.response();
- const std::string& nonce_response = response.sender_nonce();
-
- result = auth_context.VerifySenderNonce(nonce_response);
- if (!result.success()) {
- return result;
- }
-
- return VerifyCredentials(response, nonce_response + peer_cert_der);
-}
-
-// This function does the following
-//
-// * Verifies that the certificate chain |response.client_auth_certificate| +
-// |response.intermediate_certificate| is valid and chains to a trusted
-// Cast root. The list of trusted Cast roots can be overrided by providing a
-// non-nullptr |cast_trust_store|. The certificate is verified at
-// |verification_time|.
-//
-// * Verifies that none of the certificates in the chain are revoked based on
-// the CRL provided in the response |response.crl|. The CRL is verified to be
-// valid and its issuer certificate chains to a trusted Cast CRL root. The
-// list of trusted Cast CRL roots can be overrided by providing a non-nullptr
-// |crl_trust_store|. If |crl_policy| is CRL_OPTIONAL then the result of
-// revocation checking is ignored. The CRL is verified at
-// |verification_time|.
-//
-// * Verifies that |response.signature| matches the signature
-// of |signature_input| by |response.client_auth_certificate|'s public
-// key.
-AuthResult VerifyCredentialsImpl(const AuthResponse& response,
- const std::string& signature_input,
- const cast_crypto::CRLPolicy& crl_policy,
- net::TrustStore* cast_trust_store,
- net::TrustStore* crl_trust_store,
- const base::Time& verification_time) {
- // Verify the certificate
- std::unique_ptr<cast_crypto::CertVerificationContext> verification_context;
-
- // Build a single vector containing the certificate chain.
- std::vector<std::string> cert_chain;
- cert_chain.push_back(response.client_auth_certificate());
- cert_chain.insert(cert_chain.end(),
- response.intermediate_certificate().begin(),
- response.intermediate_certificate().end());
-
- // Parse the CRL.
- std::unique_ptr<cast_crypto::CastCRL> crl =
- cast_crypto::ParseAndVerifyCRLUsingCustomTrustStore(
- response.crl(), verification_time, crl_trust_store);
- if (!crl) {
- // CRL is invalid.
- RecordCertificateEvent(CERT_STATUS_INVALID_CRL);
- if (crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
- return AuthResult("Failed verifying Cast CRL.",
- AuthResult::ERROR_CRL_INVALID);
- }
- }
-
- cast_crypto::CastDeviceCertPolicy device_policy;
- bool verification_success =
- cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
- cert_chain, verification_time, &verification_context, &device_policy,
- crl.get(), crl_policy, cast_trust_store);
- if (!verification_success) {
- // TODO(ryanchung): Once this feature is completely rolled-out, remove the
- // reverification step and use error reporting to get verification errors
- // for metrics.
- bool verification_no_crl_success =
- cast_crypto::VerifyDeviceCertUsingCustomTrustStore(
- cert_chain, verification_time, &verification_context,
- &device_policy, nullptr, cast_crypto::CRLPolicy::CRL_OPTIONAL,
- cast_trust_store);
- if (!verification_no_crl_success) {
- // TODO(eroman): The error information was lost; this error is ambiguous.
- RecordCertificateEvent(CERT_STATUS_VERIFICATION_FAILED);
- return AuthResult("Failed verifying cast device certificate",
- AuthResult::ERROR_CERT_NOT_SIGNED_BY_TRUSTED_CA);
- }
- if (crl) {
- // If CRL was not present, it should've been recorded as such.
- RecordCertificateEvent(CERT_STATUS_REVOKED);
- }
- if (crl_policy == cast_crypto::CRLPolicy::CRL_REQUIRED) {
- // Device is revoked.
- return AuthResult("Failed certificate revocation check.",
- AuthResult::ERROR_CERT_REVOKED);
- }
- }
- // The certificate is verified at this point.
- RecordCertificateEvent(CERT_STATUS_OK);
- if (!verification_context->VerifySignatureOverData(response.signature(),
- signature_input)) {
- return AuthResult("Failed verifying signature over data",
- AuthResult::ERROR_SIGNED_BLOBS_MISMATCH);
- }
-
- AuthResult success;
-
- // Set the policy into the result.
- switch (device_policy) {
- case cast_crypto::CastDeviceCertPolicy::AUDIO_ONLY:
- success.channel_policies = AuthResult::POLICY_AUDIO_ONLY;
- break;
- case cast_crypto::CastDeviceCertPolicy::NONE:
- success.channel_policies = AuthResult::POLICY_NONE;
- break;
- }
-
- return success;
-}
-
-AuthResult VerifyCredentials(const AuthResponse& response,
- const std::string& signature_input) {
- base::Time now = base::Time::Now();
- cast_crypto::CRLPolicy policy = cast_crypto::CRLPolicy::CRL_REQUIRED;
- if (!base::FeatureList::IsEnabled(kEnforceRevocationChecking)) {
- policy = cast_crypto::CRLPolicy::CRL_OPTIONAL;
- }
- return VerifyCredentialsImpl(response, signature_input, policy, nullptr,
- nullptr, now);
-}
-
-AuthResult VerifyCredentialsForTest(const AuthResponse& response,
- const std::string& signature_input,
- const cast_crypto::CRLPolicy& crl_policy,
- net::TrustStore* cast_trust_store,
- net::TrustStore* crl_trust_store,
- const base::Time& verification_time) {
- return VerifyCredentialsImpl(response, signature_input, crl_policy,
- cast_trust_store, crl_trust_store,
- verification_time);
-}
-
-} // namespace cast_channel
« no previous file with comments | « components/cast_channel/cast_auth_util.h ('k') | components/cast_channel/cast_auth_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698