xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
include
xrpl
conditions
detail
include/xrpl/conditions/detail/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 <
cstddef
>
10
#include <
cstdint
>
11
#include <
limits
>
12
#include <
system_error
>
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.
19
namespace
xrpl::cryptoconditions::der
{
20
21
// The preamble encapsulates the DER identifier and
22
// length octets:
23
struct
Preamble
24
{
25
explicit
Preamble
() =
default
;
26
std::uint8_t
type
= 0;
27
std::size_t
tag
= 0;
28
std::size_t
length
= 0;
29
};
30
31
inline
bool
32
isPrimitive
(
Preamble
const
& p)
33
{
34
return
(p.
type
& 0x20) == 0;
35
}
36
37
inline
bool
38
isConstructed
(
Preamble
const
& p)
39
{
40
return
!
isPrimitive
(p);
41
}
42
43
inline
bool
44
isUniversal
(
Preamble
const
& p)
45
{
46
return
(p.
type
& 0xC0) == 0;
47
}
48
49
inline
bool
50
isApplication
(
Preamble
const
& p)
51
{
52
return
(p.
type
& 0xC0) == 0x40;
53
}
54
55
inline
bool
56
isContextSpecific
(
Preamble
const
& p)
57
{
58
return
(p.
type
& 0xC0) == 0x80;
59
}
60
61
inline
bool
62
isPrivate
(
Preamble
const
& p)
63
{
64
return
(p.
type
& 0xC0) == 0xC0;
65
}
66
67
inline
Preamble
68
parsePreamble
(
Slice
& s,
std::error_code
& ec)
69
{
70
Preamble
p;
71
72
if
(s.
size
() < 2)
73
{
74
ec =
Error::ShortPreamble
;
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::LongTag
;
86
return
p;
87
}
88
89
p.
length
= s[0];
90
s += 1;
91
92
if
((p.
length
& 0x80) != 0u)
93
{
// Long form length:
94
std::size_t
const
cnt = p.
length
& 0x7F;
95
96
if
(cnt == 0)
97
{
98
ec =
Error::MalformedEncoding
;
99
return
p;
100
}
101
102
if
(cnt >
sizeof
(
std::size_t
))
103
{
104
ec =
Error::LargeSize
;
105
return
p;
106
}
107
108
if
(cnt > s.
size
())
109
{
110
ec =
Error::ShortPreamble
;
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
{
123
ec =
Error::MalformedEncoding
;
124
return
p;
125
}
126
}
127
128
return
p;
129
}
130
131
inline
Buffer
132
parseOctetString
(
Slice
& s,
std::uint32_t
count,
std::error_code
& ec)
133
{
134
if
(count > s.
size
())
135
{
136
ec =
Error::BufferUnderfull
;
137
return
{};
138
}
139
140
if
(count > 65535)
141
{
142
ec =
Error::LargeSize
;
143
return
{};
144
}
145
146
Buffer
b(s.
data
(), count);
147
s += count;
148
return
b;
149
}
150
151
template
<
class
Integer>
152
Integer
153
parseInteger
(
Slice
& s,
std::size_t
count,
std::error_code
& ec)
154
{
155
Integer v{0};
156
157
if
(s.
empty
())
158
{
159
// can never have zero sized integers
160
ec =
Error::MalformedEncoding
;
161
return
v;
162
}
163
164
if
(count > s.
size
())
165
{
166
ec =
Error::BufferUnderfull
;
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
{
175
ec =
Error::LargeSize
;
176
return
v;
177
}
178
179
if
(!isSigned && (s[0] & (1 << 7)))
180
{
181
// trying to decode a negative number into a positive value
182
ec =
Error::MalformedEncoding
;
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
190
ec =
Error::MalformedEncoding
;
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 xrpl::cryptoconditions::der
xrpl::Buffer
Like std::vector<char> but better.
Definition
Buffer.h:19
xrpl::Slice
An immutable linear range of bytes.
Definition
Slice.h:28
xrpl::Slice::empty
bool empty() const noexcept
Return true if the byte range is empty.
Definition
Slice.h:58
xrpl::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition
Slice.h:88
xrpl::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition
Slice.h:70
cstddef
cstdint
std::error_code
std::uint8_t
limits
xrpl::cryptoconditions::der
Definition
include/xrpl/conditions/detail/utils.h:19
xrpl::cryptoconditions::der::isPrimitive
bool isPrimitive(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:32
xrpl::cryptoconditions::der::parseInteger
Integer parseInteger(Slice &s, std::size_t count, std::error_code &ec)
Definition
include/xrpl/conditions/detail/utils.h:153
xrpl::cryptoconditions::der::isApplication
bool isApplication(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:50
xrpl::cryptoconditions::der::isContextSpecific
bool isContextSpecific(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:56
xrpl::cryptoconditions::der::parseOctetString
Buffer parseOctetString(Slice &s, std::uint32_t count, std::error_code &ec)
Definition
include/xrpl/conditions/detail/utils.h:132
xrpl::cryptoconditions::der::isConstructed
bool isConstructed(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:38
xrpl::cryptoconditions::der::isPrivate
bool isPrivate(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:62
xrpl::cryptoconditions::der::parsePreamble
Preamble parsePreamble(Slice &s, std::error_code &ec)
Definition
include/xrpl/conditions/detail/utils.h:68
xrpl::cryptoconditions::der::isUniversal
bool isUniversal(Preamble const &p)
Definition
include/xrpl/conditions/detail/utils.h:44
xrpl::cryptoconditions::Error::BufferUnderfull
@ BufferUnderfull
Definition
error.h:18
xrpl::cryptoconditions::Error::LargeSize
@ LargeSize
Definition
error.h:23
xrpl::cryptoconditions::Error::MalformedEncoding
@ MalformedEncoding
Definition
error.h:19
xrpl::cryptoconditions::Error::ShortPreamble
@ ShortPreamble
Definition
error.h:20
xrpl::cryptoconditions::Error::LongTag
@ LongTag
Definition
error.h:22
std::numeric_limits
std::size_t
xrpl::cryptoconditions::der::Preamble
Definition
include/xrpl/conditions/detail/utils.h:24
xrpl::cryptoconditions::der::Preamble::type
std::uint8_t type
Definition
include/xrpl/conditions/detail/utils.h:26
xrpl::cryptoconditions::der::Preamble::length
std::size_t length
Definition
include/xrpl/conditions/detail/utils.h:28
xrpl::cryptoconditions::der::Preamble::tag
std::size_t tag
Definition
include/xrpl/conditions/detail/utils.h:27
xrpl::cryptoconditions::der::Preamble::Preamble
Preamble()=default
system_error
Generated by
1.17.0