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