rippled
Loading...
Searching...
No Matches
utils.h
1#pragma once
2
3#include <xrpl/basics/Buffer.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/conditions/detail/error.h>
6
7#include <boost/dynamic_bitset.hpp>
8
9#include <limits>
10
11namespace xrpl {
12namespace cryptoconditions {
13
14// A collection of functions to decode binary blobs
15// encoded with X.690 Distinguished Encoding Rules.
16//
17// This is a very trivial decoder and only implements
18// the bare minimum needed to support PreimageSha256.
19namespace der {
20
21// The preamble encapsulates the DER identifier and
22// length octets:
24{
25 explicit Preamble() = default;
29};
30
31inline bool
33{
34 return (p.type & 0x20) == 0;
35}
36
37inline bool
39{
40 return !isPrimitive(p);
41}
42
43inline bool
45{
46 return (p.type & 0xC0) == 0;
47}
48
49inline bool
51{
52 return (p.type & 0xC0) == 0x40;
53}
54
55inline bool
57{
58 return (p.type & 0xC0) == 0x80;
59}
60
61inline bool
63{
64 return (p.type & 0xC0) == 0xC0;
65}
66
67inline Preamble
69{
70 Preamble p;
71
72 if (s.size() < 2)
73 {
75 return p;
76 }
77
78 p.type = s[0] & 0xE0;
79 p.tag = s[0] & 0x1F;
80
81 s += 1;
82
83 if (p.tag == 0x1F)
84 { // Long tag form, which we do not support:
85 ec = error::long_tag;
86 return p;
87 }
88
89 p.length = s[0];
90 s += 1;
91
92 if (p.length & 0x80)
93 { // Long form length:
94 std::size_t const cnt = p.length & 0x7F;
95
96 if (cnt == 0)
97 {
99 return p;
100 }
101
102 if (cnt > sizeof(std::size_t))
103 {
105 return p;
106 }
107
108 if (cnt > s.size())
109 {
111 return p;
112 }
113
114 p.length = 0;
115
116 for (std::size_t i = 0; i != cnt; ++i)
117 p.length = (p.length << 8) + s[i];
118
119 s += cnt;
120
121 if (p.length == 0)
122 {
124 return p;
125 }
126 }
127
128 return p;
129}
130
131inline Buffer
133{
134 if (count > s.size())
135 {
137 return {};
138 }
139
140 if (count > 65535)
141 {
143 return {};
144 }
145
146 Buffer b(s.data(), count);
147 s += count;
148 return b;
149}
150
151template <class Integer>
152Integer
154{
155 Integer v{0};
156
157 if (s.empty())
158 {
159 // can never have zero sized integers
161 return v;
162 }
163
164 if (count > s.size())
165 {
167 return v;
168 }
169
170 bool const isSigned = std::numeric_limits<Integer>::is_signed;
171 // unsigned types may have a leading zero octet
172 size_t const maxLength = isSigned ? sizeof(Integer) : sizeof(Integer) + 1;
173 if (count > maxLength)
174 {
176 return v;
177 }
178
179 if (!isSigned && (s[0] & (1 << 7)))
180 {
181 // trying to decode a negative number into a positive value
183 return v;
184 }
185
186 if (!isSigned && count == sizeof(Integer) + 1 && s[0])
187 {
188 // since integers are coded as two's complement, the first byte may
189 // be zero for unsigned reps
191 return v;
192 }
193
194 v = 0;
195 for (size_t i = 0; i < count; ++i)
196 v = (v << 8) | (s[i] & 0xff);
197
198 if (isSigned && (s[0] & (1 << 7)))
199 {
200 for (int i = count; i < sizeof(Integer); ++i)
201 v |= (Integer(0xff) << (8 * i));
202 }
203 s += count;
204 return v;
205}
206
207} // namespace der
208} // namespace cryptoconditions
209} // namespace xrpl
Like std::vector<char> but better.
Definition Buffer.h:16
An immutable linear range of bytes.
Definition Slice.h:26
bool empty() const noexcept
Return true if the byte range is empty.
Definition Slice.h:49
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:77
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:60
bool isPrimitive(Preamble const &p)
Definition utils.h:32
Integer parseInteger(Slice &s, std::size_t count, std::error_code &ec)
Definition utils.h:153
bool isApplication(Preamble const &p)
Definition utils.h:50
bool isContextSpecific(Preamble const &p)
Definition utils.h:56
Buffer parseOctetString(Slice &s, std::uint32_t count, std::error_code &ec)
Definition utils.h:132
bool isConstructed(Preamble const &p)
Definition utils.h:38
bool isPrivate(Preamble const &p)
Definition utils.h:62
Preamble parsePreamble(Slice &s, std::error_code &ec)
Definition utils.h:68
bool isUniversal(Preamble const &p)
Definition utils.h:44
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5