1 // Copyright 2012 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_HASH_VALUE_H_ 6 #define NET_BASE_HASH_VALUE_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 #include <string.h> 11 12 #include <string> 13 #include <string_view> 14 #include <vector> 15 16 #include "base/compiler_specific.h" 17 #include "base/containers/checked_iterators.h" 18 #include "base/containers/span.h" 19 #include "build/build_config.h" 20 #include "net/base/net_export.h" 21 22 namespace net { 23 24 struct NET_EXPORT SHA256HashValue { 25 unsigned char data[32]; 26 }; 27 28 inline bool operator==(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 29 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) == 0; 30 } 31 32 inline bool operator!=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 33 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) != 0; 34 } 35 36 inline bool operator<(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 37 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) < 0; 38 } 39 40 inline bool operator>(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 41 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) > 0; 42 } 43 44 inline bool operator<=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 45 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) <= 0; 46 } 47 48 inline bool operator>=(const SHA256HashValue& lhs, const SHA256HashValue& rhs) { 49 return memcmp(lhs.data, rhs.data, sizeof(lhs.data)) >= 0; 50 } 51 52 enum HashValueTag { 53 HASH_VALUE_SHA256, 54 }; 55 56 class NET_EXPORT HashValue { 57 public: 58 using iterator = base::CheckedContiguousIterator<unsigned char>; 59 using const_iterator = base::CheckedContiguousIterator<const unsigned char>; 60 61 explicit HashValue(const SHA256HashValue& hash); HashValue(HashValueTag tag)62 explicit HashValue(HashValueTag tag) : tag_(tag) {} HashValue()63 HashValue() : tag_(HASH_VALUE_SHA256) {} 64 65 // Serializes/Deserializes hashes in the form of 66 // <hash-name>"/"<base64-hash-value> 67 // (eg: "sha256/...") 68 // This format may be persisted to permanent storage, so 69 // care should be taken before changing the serialization. 70 // 71 // This format is used for: 72 // - net_internals display/setting public-key pins 73 // - logging public-key pins 74 // - serializing public-key pins 75 76 // Deserializes a HashValue from a string. Returns false if the input is not 77 // valid. 78 bool FromString(std::string_view input); 79 80 // Serializes the HashValue to a string. 81 std::string ToString() const; 82 83 size_t size() const; 84 unsigned char* data(); 85 const unsigned char* data() const; 86 87 // Iterate memory as bytes up to the end of its logical size. begin()88 iterator begin() { 89 // SAFETY: `data()` points to at least `size()` contiguous elements, so this 90 // value must be no further than just-past-the-end of the allocation. 91 return UNSAFE_BUFFERS(iterator(data(), data() + size())); 92 } begin()93 const_iterator begin() const { 94 // SAFETY: As in the non-const version above. 95 return UNSAFE_BUFFERS(const_iterator(data(), data() + size())); 96 } end()97 iterator end() { 98 // SAFETY: As in `begin()` above. 99 return UNSAFE_BUFFERS(iterator(data(), data() + size(), data() + size())); 100 } end()101 const_iterator end() const { 102 // SAFETY: As in `begin()` above. 103 return UNSAFE_BUFFERS( 104 const_iterator(data(), data() + size(), data() + size())); 105 } 106 tag()107 HashValueTag tag() const { return tag_; } 108 109 NET_EXPORT friend bool operator==(const HashValue& lhs, const HashValue& rhs); 110 NET_EXPORT friend bool operator!=(const HashValue& lhs, const HashValue& rhs); 111 NET_EXPORT friend bool operator<(const HashValue& lhs, const HashValue& rhs); 112 NET_EXPORT friend bool operator>(const HashValue& lhs, const HashValue& rhs); 113 NET_EXPORT friend bool operator<=(const HashValue& lhs, const HashValue& rhs); 114 NET_EXPORT friend bool operator>=(const HashValue& lhs, const HashValue& rhs); 115 116 private: 117 HashValueTag tag_; 118 119 union { 120 SHA256HashValue sha256; 121 } fingerprint; 122 }; 123 124 typedef std::vector<HashValue> HashValueVector; 125 126 127 // IsSHA256HashInSortedArray returns true iff |hash| is in |array|, a sorted 128 // array of SHA256 hashes. 129 bool IsSHA256HashInSortedArray(const HashValue& hash, 130 base::span<const SHA256HashValue> array); 131 132 // IsAnySHA256HashInSortedArray returns true iff any value in |hashes| is in 133 // |array|, a sorted array of SHA256 hashes. 134 bool IsAnySHA256HashInSortedArray(base::span<const HashValue> hashes, 135 base::span<const SHA256HashValue> array); 136 137 } // namespace net 138 139 #endif // NET_BASE_HASH_VALUE_H_ 140