rippled
Loading...
Searching...
No Matches
utils.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2016 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_CONDITIONS_UTILS_H
21#define RIPPLE_CONDITIONS_UTILS_H
22
23#include <xrpld/conditions/detail/error.h>
24
25#include <xrpl/basics/Buffer.h>
26#include <xrpl/basics/Slice.h>
27
28#include <boost/dynamic_bitset.hpp>
29
30#include <limits>
31
32namespace ripple {
33namespace cryptoconditions {
34
35// A collection of functions to decode binary blobs
36// encoded with X.690 Distinguished Encoding Rules.
37//
38// This is a very trivial decoder and only implements
39// the bare minimum needed to support PreimageSha256.
40namespace der {
41
42// The preamble encapsulates the DER identifier and
43// length octets:
45{
46 explicit Preamble() = default;
50};
51
52inline bool
54{
55 return (p.type & 0x20) == 0;
56}
57
58inline bool
60{
61 return !isPrimitive(p);
62}
63
64inline bool
66{
67 return (p.type & 0xC0) == 0;
68}
69
70inline bool
72{
73 return (p.type & 0xC0) == 0x40;
74}
75
76inline bool
78{
79 return (p.type & 0xC0) == 0x80;
80}
81
82inline bool
84{
85 return (p.type & 0xC0) == 0xC0;
86}
87
88inline Preamble
90{
91 Preamble p;
92
93 if (s.size() < 2)
94 {
96 return p;
97 }
98
99 p.type = s[0] & 0xE0;
100 p.tag = s[0] & 0x1F;
101
102 s += 1;
103
104 if (p.tag == 0x1F)
105 { // Long tag form, which we do not support:
106 ec = error::long_tag;
107 return p;
108 }
109
110 p.length = s[0];
111 s += 1;
112
113 if (p.length & 0x80)
114 { // Long form length:
115 std::size_t const cnt = p.length & 0x7F;
116
117 if (cnt == 0)
118 {
120 return p;
121 }
122
123 if (cnt > sizeof(std::size_t))
124 {
126 return p;
127 }
128
129 if (cnt > s.size())
130 {
132 return p;
133 }
134
135 p.length = 0;
136
137 for (std::size_t i = 0; i != cnt; ++i)
138 p.length = (p.length << 8) + s[i];
139
140 s += cnt;
141
142 if (p.length == 0)
143 {
145 return p;
146 }
147 }
148
149 return p;
150}
151
152inline Buffer
154{
155 if (count > s.size())
156 {
158 return {};
159 }
160
161 if (count > 65535)
162 {
164 return {};
165 }
166
167 Buffer b(s.data(), count);
168 s += count;
169 return b;
170}
171
172template <class Integer>
173Integer
175{
176 Integer v{0};
177
178 if (s.empty())
179 {
180 // can never have zero sized integers
182 return v;
183 }
184
185 if (count > s.size())
186 {
188 return v;
189 }
190
191 bool const isSigned = std::numeric_limits<Integer>::is_signed;
192 // unsigned types may have a leading zero octet
193 size_t const maxLength = isSigned ? sizeof(Integer) : sizeof(Integer) + 1;
194 if (count > maxLength)
195 {
197 return v;
198 }
199
200 if (!isSigned && (s[0] & (1 << 7)))
201 {
202 // trying to decode a negative number into a positive value
204 return v;
205 }
206
207 if (!isSigned && count == sizeof(Integer) + 1 && s[0])
208 {
209 // since integers are coded as two's complement, the first byte may
210 // be zero for unsigned reps
212 return v;
213 }
214
215 v = 0;
216 for (size_t i = 0; i < count; ++i)
217 v = (v << 8) | (s[i] & 0xff);
218
219 if (isSigned && (s[0] & (1 << 7)))
220 {
221 for (int i = count; i < sizeof(Integer); ++i)
222 v |= (Integer(0xff) << (8 * i));
223 }
224 s += count;
225 return v;
226}
227
228} // namespace der
229} // namespace cryptoconditions
230} // namespace ripple
231
232#endif
Like std::vector<char> but better.
Definition Buffer.h:36
An immutable linear range of bytes.
Definition Slice.h:46
bool empty() const noexcept
Return true if the byte range is empty.
Definition Slice.h:70
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:98
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:81
bool isConstructed(Preamble const &p)
Definition utils.h:59
bool isPrivate(Preamble const &p)
Definition utils.h:83
bool isContextSpecific(Preamble const &p)
Definition utils.h:77
Buffer parseOctetString(Slice &s, std::uint32_t count, std::error_code &ec)
Definition utils.h:153
Integer parseInteger(Slice &s, std::size_t count, std::error_code &ec)
Definition utils.h:174
bool isPrimitive(Preamble const &p)
Definition utils.h:53
bool isApplication(Preamble const &p)
Definition utils.h:71
bool isUniversal(Preamble const &p)
Definition utils.h:65
Preamble parsePreamble(Slice &s, std::error_code &ec)
Definition utils.h:89
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25