1/*
2 * Copyright (C) 2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include <type_traits>
29#include <wtf/HashTraits.h>
30#include <wtf/Hasher.h>
31#include <wtf/Vector.h>
32#include <wtf/text/WTFString.h>
33
34namespace WebCore {
35
36class CachedResource;
37
38struct ResourceCryptographicDigest {
39 enum class Algorithm {
40 SHA256 = 1 << 0,
41 SHA384 = 1 << 1,
42 SHA512 = 1 << 2,
43 };
44
45 // Number of bytes to hold SHA-512 digest
46 static constexpr size_t maximumDigestLength = 64;
47
48 Algorithm algorithm;
49 Vector<uint8_t> value;
50
51 bool operator==(const ResourceCryptographicDigest& other) const
52 {
53 return algorithm == other.algorithm && value == other.value;
54 }
55
56 bool operator!=(const ResourceCryptographicDigest& other) const
57 {
58 return !(*this == other);
59 }
60};
61
62struct EncodedResourceCryptographicDigest {
63 using Algorithm = ResourceCryptographicDigest::Algorithm;
64
65 Algorithm algorithm;
66 String digest;
67};
68
69Optional<ResourceCryptographicDigest> parseCryptographicDigest(const UChar*& begin, const UChar* end);
70Optional<ResourceCryptographicDigest> parseCryptographicDigest(const LChar*& begin, const LChar* end);
71
72Optional<EncodedResourceCryptographicDigest> parseEncodedCryptographicDigest(const UChar*& begin, const UChar* end);
73Optional<EncodedResourceCryptographicDigest> parseEncodedCryptographicDigest(const LChar*& begin, const LChar* end);
74
75Optional<ResourceCryptographicDigest> decodeEncodedResourceCryptographicDigest(const EncodedResourceCryptographicDigest&);
76
77ResourceCryptographicDigest cryptographicDigestForBytes(ResourceCryptographicDigest::Algorithm, const void* bytes, size_t length);
78
79}
80
81namespace WTF {
82
83template<> struct DefaultHash<WebCore::ResourceCryptographicDigest> {
84 struct Hash {
85 static unsigned hash(const WebCore::ResourceCryptographicDigest& digest)
86 {
87 return pairIntHash(intHash(static_cast<unsigned>(digest.algorithm)), StringHasher::computeHash(digest.value.data(), digest.value.size()));
88 }
89 static bool equal(const WebCore::ResourceCryptographicDigest& a, const WebCore::ResourceCryptographicDigest& b)
90 {
91 return a == b;
92 }
93 static const bool safeToCompareToEmptyOrDeleted = true;
94 };
95};
96
97template<> struct HashTraits<WebCore::ResourceCryptographicDigest> : GenericHashTraits<WebCore::ResourceCryptographicDigest> {
98 using Algorithm = WebCore::ResourceCryptographicDigest::Algorithm;
99 using AlgorithmUnderlyingType = typename std::underlying_type<Algorithm>::type;
100 static constexpr auto emptyAlgorithmValue = static_cast<Algorithm>(std::numeric_limits<AlgorithmUnderlyingType>::max());
101 static constexpr auto deletedAlgorithmValue = static_cast<Algorithm>(std::numeric_limits<AlgorithmUnderlyingType>::max() - 1);
102
103 static const bool emptyValueIsZero = false;
104
105 static WebCore::ResourceCryptographicDigest emptyValue()
106 {
107 return { emptyAlgorithmValue, { } };
108 }
109
110 static void constructDeletedValue(WebCore::ResourceCryptographicDigest& slot)
111 {
112 slot.algorithm = deletedAlgorithmValue;
113 }
114
115 static bool isDeletedValue(const WebCore::ResourceCryptographicDigest& slot)
116 {
117 return slot.algorithm == deletedAlgorithmValue;
118 }
119};
120
121}
122