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