blob: c1f05a4b2e26b0a9143f21d7958aafee332fe9ad [file] [log] [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_SUBRESOURCE_INTEGRITY_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_SUBRESOURCE_INTEGRITY_H_
#include <string_view>
#include "base/gtest_prod_util.h"
#include "base/types/expected.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "services/network/public/mojom/integrity_algorithm.mojom-blink.h"
#include "third_party/blink/renderer/platform/crypto.h"
#include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
class FeatureContext;
class IntegrityReport;
class KURL;
class Resource;
using network::mojom::blink::FetchResponseType;
class PLATFORM_EXPORT SubresourceIntegrity final {
STATIC_ONLY(SubresourceIntegrity);
public:
// Check the integrity of a given |buffer|'s content against the metadata in
// the `IntegrityMetadataSet` provided.
//
// Either a `Resource` or `FetchResponseType` will be used to validate the
// response's eligibility for client-initiated integrity checks. Ineligible
// resources will fail the check.
//
// Note: If a resource's body is empty, then these methods are called with a
// null `buffer`.
static bool CheckSubresourceIntegrity(
const IntegrityMetadataSet&,
const SegmentedBuffer* buffer,
const KURL& resource_url,
const Resource&,
const FeatureContext*,
IntegrityReport&,
HashMap<HashAlgorithm, String>* computed_hashes);
static bool CheckSubresourceIntegrity(const IntegrityMetadataSet&,
const SegmentedBuffer* buffer,
const KURL& resource_url,
const FetchResponseType,
const String& raw_headers,
const FeatureContext*,
IntegrityReport&);
static String GetSubresourceIntegrityHash(const SegmentedBuffer*,
HashAlgorithm);
// The caller is responsible for ensuring that `Unencoded-Digests` are enabled
// by checking against `RuntimeEnabledFeatures::UnencodedDigestEnabled()`.
static bool CheckUnencodedDigests(const Vector<IntegrityMetadata>& digests,
const SegmentedBuffer* data);
static HashAlgorithm IntegrityAlgorithmToHashAlgorithm(IntegrityAlgorithm);
// The IntegrityMetadataSet argument is an out parameters which contains the
// set of all valid, parsed metadata from |attribute|.
static void ParseIntegrityAttribute(const String& attribute,
IntegrityMetadataSet&,
const FeatureContext*);
static void ParseIntegrityAttribute(const String& attribute,
IntegrityMetadataSet&,
const FeatureContext*,
IntegrityReport*);
// Returns true if the element's `integrity` and `signature` attributes
// produce a verifiable signature for the element's content.
//
// https://mikewest.github.io/inline-integrity/
static bool VerifyInlineIntegrity(const String& integrity,
const String& signatures,
const String& source_code,
const FeatureContext*);
private:
friend class SubresourceIntegrityTest;
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegrityTest, Parsing);
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegrityTest, ParseAlgorithm);
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegrityTest, ParseSignatureAlgorithm);
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegrityTest,
AlgorithmEnumPrioritization);
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegrityTest, FindBestAlgorithm);
FRIEND_TEST_ALL_PREFIXES(SubresourceIntegritySignatureTest,
ParseSignatureAlgorithm);
// The core implementation for all CheckSubresourceIntegrity functions.
static bool CheckSubresourceIntegrityImpl(
const IntegrityMetadataSet&,
const SegmentedBuffer* buffer,
const KURL& resource_url,
const String& raw_headers,
const FeatureContext*,
IntegrityReport&,
HashMap<HashAlgorithm, String>* computed_hashes);
// Handles hash validation during SRI checks.
static bool CheckHashesImpl(const Vector<IntegrityMetadata>&,
const SegmentedBuffer*,
const KURL&,
const FeatureContext*,
IntegrityReport&,
HashMap<HashAlgorithm, String>* computed_hashes);
// Handles signature-based matching during SRI checks
static bool CheckSignaturesImpl(const Vector<IntegrityMetadata>&,
const KURL& resource_url,
const String& raw_headers,
IntegrityReport&);
enum AlgorithmParseError { kAlgorithmUnparsable, kAlgorithmUnknown };
using AlgorithmParseResult = base::expected<size_t, AlgorithmParseError>;
static IntegrityAlgorithm FindBestAlgorithm(const Vector<IntegrityMetadata>&);
static AlgorithmParseResult ParseAttributeAlgorithm(std::string_view token,
const FeatureContext*,
IntegrityAlgorithm&);
typedef std::pair<const char*, IntegrityAlgorithm> AlgorithmPrefixPair;
static bool ParseDigest(std::string_view maybe_digest, String& digest);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_SUBRESOURCE_INTEGRITY_H_