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#include <xrpl/basics/Buffer.h>
25#include <xrpl/basics/Slice.h>
26
27#include <boost/dynamic_bitset.hpp>
28
29#include <limits>
30
31namespace ripple {
32namespace cryptoconditions {
33
34// A collection of functions to decode binary blobs
35// encoded with X.690 Distinguished Encoding Rules.
36//
37// This is a very trivial decoder and only implements
38// the bare minimum needed to support PreimageSha256.
39namespace der {
40
41// The preamble encapsulates the DER identifier and
42// length octets:
44{
45 explicit Preamble() = default;
49};
50
51inline bool
53{
54 return (p.type & 0x20) == 0;
55}
56
57inline bool
59{
60 return !isPrimitive(p);
61}
62
63inline bool
65{
66 return (p.type & 0xC0) == 0;
67}
68
69inline bool
71{
72 return (p.type & 0xC0) == 0x40;
73}
74
75inline bool
77{
78 return (p.type & 0xC0) == 0x80;
79}
80
81inline bool
83{
84 return (p.type & 0xC0) == 0xC0;
85}
86
87inline Preamble
89{
90 Preamble p;
91
92 if (s.size() < 2)
93 {
95 return p;
96 }
97
98 p.type = s[0] & 0xE0;
99 p.tag = s[0] & 0x1F;
100
101 s += 1;
102
103 if (p.tag == 0x1F)
104 { // Long tag form, which we do not support:
105 ec = error::long_tag;
106 return p;
107 }
108
109 p.length = s[0];
110 s += 1;
111
112 if (p.length & 0x80)
113 { // Long form length:
114 std::size_t const cnt = p.length & 0x7F;
115
116 if (cnt == 0)
117 {
119 return p;
120 }
121
122 if (cnt > sizeof(std::size_t))
123 {
125 return p;
126 }
127
128 if (cnt > s.size())
129 {
131 return p;
132 }
133
134 p.length = 0;
135
136 for (std::size_t i = 0; i != cnt; ++i)
137 p.length = (p.length << 8) + s[i];
138
139 s += cnt;
140
141 if (p.length == 0)
142 {
144 return p;
145 }
146 }
147
148 return p;
149}
150
151inline Buffer
153{
154 if (count > s.size())
155 {
157 return {};
158 }
159
160 if (count > 65535)
161 {
163 return {};
164 }
165
166 Buffer b(s.data(), count);
167 s += count;
168 return b;
169}
170
171template <class Integer>
172Integer
174{
175 Integer v{0};
176
177 if (s.empty())
178 {
179 // can never have zero sized integers
181 return v;
182 }
183
184 if (count > s.size())
185 {
187 return v;
188 }
189
190 const bool isSigned = std::numeric_limits<Integer>::is_signed;
191 // unsigned types may have a leading zero octet
192 const size_t maxLength = isSigned ? sizeof(Integer) : sizeof(Integer) + 1;
193 if (count > maxLength)
194 {
196 return v;
197 }
198
199 if (!isSigned && (s[0] & (1 << 7)))
200 {
201 // trying to decode a negative number into a positive value
203 return v;
204 }
205
206 if (!isSigned && count == sizeof(Integer) + 1 && s[0])
207 {
208 // since integers are coded as two's complement, the first byte may
209 // be zero for unsigned reps
211 return v;
212 }
213
214 v = 0;
215 for (size_t i = 0; i < count; ++i)
216 v = (v << 8) | (s[i] & 0xff);
217
218 if (isSigned && (s[0] & (1 << 7)))
219 {
220 for (int i = count; i < sizeof(Integer); ++i)
221 v |= (Integer(0xff) << (8 * i));
222 }
223 s += count;
224 return v;
225}
226
227} // namespace der
228} // namespace cryptoconditions
229} // namespace ripple
230
231#endif
Like std::vector<char> but better.
Definition: Buffer.h:35
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:58
bool isPrivate(Preamble const &p)
Definition: utils.h:82
bool isContextSpecific(Preamble const &p)
Definition: utils.h:76
Buffer parseOctetString(Slice &s, std::uint32_t count, std::error_code &ec)
Definition: utils.h:152
Integer parseInteger(Slice &s, std::size_t count, std::error_code &ec)
Definition: utils.h:173
bool isPrimitive(Preamble const &p)
Definition: utils.h:52
bool isApplication(Preamble const &p)
Definition: utils.h:70
bool isUniversal(Preamble const &p)
Definition: utils.h:64
Preamble parsePreamble(Slice &s, std::error_code &ec)
Definition: utils.h:88
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26