xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
libxrpl
conditions
Condition.cpp
1
#include <xrpl/conditions/Condition.h>
2
3
#include <xrpl/basics/Buffer.h>
4
#include <xrpl/basics/Slice.h>
5
#include <xrpl/conditions/detail/PreimageSha256.h>
6
#include <xrpl/conditions/detail/error.h>
7
#include <xrpl/conditions/detail/utils.h>
8
9
#include <
cstddef
>
10
#include <
cstdint
>
11
#include <
memory
>
12
#include <
system_error
>
13
#include <
utility
>
14
15
namespace
xrpl::cryptoconditions
{
16
17
namespace
detail
{
18
// The binary encoding of conditions differs based on their
19
// type. All types define at least a fingerprint and cost
20
// sub-field. Some types, such as the compound condition
21
// types, define additional sub-fields that are required to
22
// convey essential properties of the cryptocondition (such
23
// as the sub-types used by sub-conditions in the case of
24
// the compound types).
25
//
26
// Conditions are encoded as follows:
27
//
28
// Condition ::= CHOICE {
29
// preimageSha256 [0] SimpleSha256Condition,
30
// prefixSha256 [1] CompoundSha256Condition,
31
// thresholdSha256 [2] CompoundSha256Condition,
32
// rsaSha256 [3] SimpleSha256Condition,
33
// ed25519Sha256 [4] SimpleSha256Condition
34
// }
35
//
36
// SimpleSha256Condition ::= SEQUENCE {
37
// fingerprint OCTET STRING (SIZE(32)),
38
// cost INTEGER (0..4294967295)
39
// }
40
//
41
// CompoundSha256Condition ::= SEQUENCE {
42
// fingerprint OCTET STRING (SIZE(32)),
43
// cost INTEGER (0..4294967295),
44
// subtypes ConditionTypes
45
// }
46
//
47
// ConditionTypes ::= BIT STRING {
48
// preImageSha256 (0),
49
// prefixSha256 (1),
50
// thresholdSha256 (2),
51
// rsaSha256 (3),
52
// ed25519Sha256 (4)
53
// }
54
55
constexpr
std::size_t
kFingerprintSize
= 32;
56
57
std::unique_ptr<Condition>
58
loadSimpleSha256
(
Type
type,
Slice
s,
std::error_code
& ec)
59
{
60
using namespace
der
;
61
62
auto
p = parsePreamble(s, ec);
63
64
if
(ec)
65
return
{};
66
67
if
(!isPrimitive(p) || !isContextSpecific(p))
68
{
69
ec =
Error::IncorrectEncoding
;
70
return
{};
71
}
72
73
if
(p.tag != 0)
74
{
75
ec =
Error::UnexpectedTag
;
76
return
{};
77
}
78
79
if
(p.length !=
kFingerprintSize
)
80
{
81
ec =
Error::FingerprintSize
;
82
return
{};
83
}
84
85
Buffer
b = parseOctetString(s, p.
length
, ec);
86
87
if
(ec)
88
return
{};
89
90
p = parsePreamble(s, ec);
91
92
if
(ec)
93
return
{};
94
95
if
(!isPrimitive(p) || !isContextSpecific(p))
96
{
97
ec =
Error::MalformedEncoding
;
98
return
{};
99
}
100
101
if
(p.tag != 1)
102
{
103
ec =
Error::UnexpectedTag
;
104
return
{};
105
}
106
107
auto
cost = parseInteger<std::uint32_t>(s, p.
length
, ec);
108
109
if
(ec)
110
return
{};
111
112
if
(!s.
empty
())
113
{
114
ec =
Error::TrailingGarbage
;
115
return
{};
116
}
117
118
switch
(type)
119
{
120
case
Type::PreimageSha256
:
121
if
(cost >
PreimageSha256::kMaxPreimageLength
)
122
{
123
ec =
Error::PreimageTooLong
;
124
return
{};
125
}
126
break
;
127
128
default
:
129
break
;
130
}
131
132
return
std::make_unique<Condition>
(type, cost, std::move(b));
133
}
134
135
}
// namespace detail
136
137
std::unique_ptr<Condition>
138
Condition::deserialize
(
Slice
s,
std::error_code
& ec)
139
{
140
// Per the RFC, in a condition we choose a type based
141
// on the tag of the item we contain:
142
//
143
// Condition ::= CHOICE {
144
// preimageSha256 [0] SimpleSha256Condition,
145
// prefixSha256 [1] CompoundSha256Condition,
146
// thresholdSha256 [2] CompoundSha256Condition,
147
// rsaSha256 [3] SimpleSha256Condition,
148
// ed25519Sha256 [4] SimpleSha256Condition
149
// }
150
if
(s.
empty
())
151
{
152
ec =
Error::BufferEmpty
;
153
return
{};
154
}
155
156
using namespace
der
;
157
158
auto
const
p = parsePreamble(s, ec);
159
if
(ec)
160
return
{};
161
162
// All fulfillments are context-specific, constructed
163
// types
164
if
(!isConstructed(p) || !isContextSpecific(p))
165
{
166
ec =
Error::MalformedEncoding
;
167
return
{};
168
}
169
170
if
(p.length > s.
size
())
171
{
172
ec =
Error::BufferUnderfull
;
173
return
{};
174
}
175
176
if
(s.
size
() >
kMaxSerializedCondition
)
177
{
178
ec =
Error::LargeSize
;
179
return
{};
180
}
181
182
std::unique_ptr<Condition>
c;
183
184
switch
(p.tag)
185
{
186
case
0:
// PreimageSha256
187
c =
detail::loadSimpleSha256
(
Type::PreimageSha256
,
Slice
(s.
data
(), p.length), ec);
188
if
(!ec)
189
s += p.
length
;
190
break
;
191
192
case
1:
// PrefixSha256
193
case
2:
// ThresholdSha256
194
case
3:
// RsaSha256
195
case
4:
// Ed25519Sha256
196
ec =
Error::UnsupportedType
;
197
return
{};
198
199
default
:
200
ec =
Error::UnknownType
;
201
return
{};
202
}
203
204
if
(!s.
empty
())
205
{
206
ec =
Error::TrailingGarbage
;
207
return
{};
208
}
209
210
return
c;
211
}
212
213
}
// namespace xrpl::cryptoconditions
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::length
std::size_t length() const noexcept
Definition
Slice.h:76
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
xrpl::cryptoconditions::Condition::kMaxSerializedCondition
static constexpr std::size_t kMaxSerializedCondition
The largest binary condition we support.
Definition
Condition.h:35
xrpl::cryptoconditions::Condition::deserialize
static std::unique_ptr< Condition > deserialize(Slice s, std::error_code &ec)
Load a condition from its binary form.
Definition
Condition.cpp:138
xrpl::cryptoconditions::PreimageSha256::kMaxPreimageLength
static constexpr std::size_t kMaxPreimageLength
The maximum allowed length of a preimage.
Definition
PreimageSha256.h:31
cstddef
cstdint
std::error_code
std::make_unique
T make_unique(T... args)
memory
xrpl::cryptoconditions::der
Definition
include/xrpl/conditions/detail/utils.h:19
xrpl::cryptoconditions::detail
Definition
Condition.cpp:17
xrpl::cryptoconditions::detail::loadSimpleSha256
std::unique_ptr< Condition > loadSimpleSha256(Type type, Slice s, std::error_code &ec)
Definition
Condition.cpp:58
xrpl::cryptoconditions::detail::kFingerprintSize
constexpr std::size_t kFingerprintSize
Definition
Condition.cpp:55
xrpl::cryptoconditions
Definition
Condition.h:14
xrpl::cryptoconditions::Type
Type
Definition
Condition.h:16
xrpl::cryptoconditions::Type::PreimageSha256
@ PreimageSha256
Definition
Condition.h:17
xrpl::cryptoconditions::Error::UnexpectedTag
@ UnexpectedTag
Definition
error.h:21
xrpl::cryptoconditions::Error::FingerprintSize
@ FingerprintSize
Definition
error.h:13
xrpl::cryptoconditions::Error::IncorrectEncoding
@ IncorrectEncoding
Definition
error.h:14
xrpl::cryptoconditions::Error::BufferUnderfull
@ BufferUnderfull
Definition
error.h:18
xrpl::cryptoconditions::Error::LargeSize
@ LargeSize
Definition
error.h:23
xrpl::cryptoconditions::Error::UnsupportedType
@ UnsupportedType
Definition
error.h:9
xrpl::cryptoconditions::Error::MalformedEncoding
@ MalformedEncoding
Definition
error.h:19
xrpl::cryptoconditions::Error::UnknownType
@ UnknownType
Definition
error.h:11
xrpl::cryptoconditions::Error::BufferEmpty
@ BufferEmpty
Definition
error.h:16
xrpl::cryptoconditions::Error::PreimageTooLong
@ PreimageTooLong
Definition
error.h:24
xrpl::cryptoconditions::Error::TrailingGarbage
@ TrailingGarbage
Definition
error.h:15
std::size_t
system_error
std::unique_ptr
utility
Generated by
1.17.0