Bug 1839316: part 5) Guard the "fetchpriority" attribute behind a pref. r=kershaw...
[gecko.git] / security / ct / CTUtils.h
blob68ddd927f0efc11993caa9706b2d28100619488c
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef CTUtils_h
8 #define CTUtils_h
10 #include <memory>
12 #include "cryptohi.h"
13 #include "keyhi.h"
14 #include "keythi.h"
15 #include "pk11pub.h"
16 #include "mozpkix/Input.h"
17 #include "mozpkix/Result.h"
19 #define MOZILLA_CT_ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0]))
21 struct DeleteHelper {
22 void operator()(CERTSubjectPublicKeyInfo* value) {
23 SECKEY_DestroySubjectPublicKeyInfo(value);
25 void operator()(PK11Context* value) { PK11_DestroyContext(value, true); }
26 void operator()(PK11SlotInfo* value) { PK11_FreeSlot(value); }
27 void operator()(SECKEYPublicKey* value) { SECKEY_DestroyPublicKey(value); }
28 void operator()(SECItem* value) { SECITEM_FreeItem(value, true); }
31 template <class T>
32 struct MaybeDeleteHelper {
33 void operator()(T* ptr) {
34 if (ptr) {
35 DeleteHelper del;
36 del(ptr);
41 typedef std::unique_ptr<CERTSubjectPublicKeyInfo,
42 MaybeDeleteHelper<CERTSubjectPublicKeyInfo>>
43 UniqueCERTSubjectPublicKeyInfo;
44 typedef std::unique_ptr<PK11Context, MaybeDeleteHelper<PK11Context>>
45 UniquePK11Context;
46 typedef std::unique_ptr<PK11SlotInfo, MaybeDeleteHelper<PK11SlotInfo>>
47 UniquePK11SlotInfo;
48 typedef std::unique_ptr<SECKEYPublicKey, MaybeDeleteHelper<SECKEYPublicKey>>
49 UniqueSECKEYPublicKey;
50 typedef std::unique_ptr<SECItem, MaybeDeleteHelper<SECItem>> UniqueSECItem;
52 namespace mozilla {
53 namespace ct {
55 // Reads a TLS-encoded variable length unsigned integer from |in|.
56 // The integer is expected to be in big-endian order, which is used by TLS.
57 // Note: does not check if the output parameter overflows while reading.
58 // |length| indicates the size (in bytes) of the serialized integer.
59 inline static pkix::Result UncheckedReadUint(size_t length, pkix::Reader& in,
60 uint64_t& out) {
61 uint64_t result = 0;
62 for (size_t i = 0; i < length; ++i) {
63 uint8_t value;
64 pkix::Result rv = in.Read(value);
65 if (rv != pkix::Success) {
66 return rv;
68 result = (result << 8) | value;
70 out = result;
71 return pkix::Success;
74 // Performs overflow sanity checks and calls UncheckedReadUint.
75 template <size_t length, typename T>
76 pkix::Result ReadUint(pkix::Reader& in, T& out) {
77 uint64_t value;
78 static_assert(std::is_unsigned<T>::value, "T must be unsigned");
79 static_assert(length <= 8, "At most 8 byte integers can be read");
80 static_assert(sizeof(T) >= length, "T must be able to hold <length> bytes");
81 pkix::Result rv = UncheckedReadUint(length, in, value);
82 if (rv != pkix::Success) {
83 return rv;
85 out = static_cast<T>(value);
86 return pkix::Success;
89 // Reads |length| bytes from |in|.
90 static inline pkix::Result ReadFixedBytes(size_t length, pkix::Reader& in,
91 pkix::Input& out) {
92 return in.Skip(length, out);
95 // Reads a length-prefixed variable amount of bytes from |in|, updating |out|
96 // on success. |prefixLength| indicates the number of bytes needed to represent
97 // the length.
98 template <size_t prefixLength>
99 pkix::Result ReadVariableBytes(pkix::Reader& in, pkix::Input& out) {
100 size_t length;
101 pkix::Result rv = ReadUint<prefixLength>(in, length);
102 if (rv != pkix::Success) {
103 return rv;
105 return ReadFixedBytes(length, in, out);
108 } // namespace ct
109 } // namespace mozilla
111 #endif // CTUtils_h