rippled
Loading...
Searching...
No Matches
Condition.cpp
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#include <xrpld/conditions/Condition.h>
21#include <xrpld/conditions/Fulfillment.h>
22#include <xrpld/conditions/detail/PreimageSha256.h>
23#include <xrpld/conditions/detail/utils.h>
24#include <xrpl/basics/contract.h>
25#include <iostream>
26#include <vector>
27
28namespace ripple {
29namespace cryptoconditions {
30
31namespace detail {
32// The binary encoding of conditions differs based on their
33// type. All types define at least a fingerprint and cost
34// sub-field. Some types, such as the compound condition
35// types, define additional sub-fields that are required to
36// convey essential properties of the cryptocondition (such
37// as the sub-types used by sub-conditions in the case of
38// the compound types).
39//
40// Conditions are encoded as follows:
41//
42// Condition ::= CHOICE {
43// preimageSha256 [0] SimpleSha256Condition,
44// prefixSha256 [1] CompoundSha256Condition,
45// thresholdSha256 [2] CompoundSha256Condition,
46// rsaSha256 [3] SimpleSha256Condition,
47// ed25519Sha256 [4] SimpleSha256Condition
48// }
49//
50// SimpleSha256Condition ::= SEQUENCE {
51// fingerprint OCTET STRING (SIZE(32)),
52// cost INTEGER (0..4294967295)
53// }
54//
55// CompoundSha256Condition ::= SEQUENCE {
56// fingerprint OCTET STRING (SIZE(32)),
57// cost INTEGER (0..4294967295),
58// subtypes ConditionTypes
59// }
60//
61// ConditionTypes ::= BIT STRING {
62// preImageSha256 (0),
63// prefixSha256 (1),
64// thresholdSha256 (2),
65// rsaSha256 (3),
66// ed25519Sha256 (4)
67// }
68
70
73{
74 using namespace der;
75
76 auto p = parsePreamble(s, ec);
77
78 if (ec)
79 return {};
80
81 if (!isPrimitive(p) || !isContextSpecific(p))
82 {
84 return {};
85 }
86
87 if (p.tag != 0)
88 {
90 return {};
91 }
92
93 if (p.length != fingerprintSize)
94 {
96 return {};
97 }
98
99 Buffer b = parseOctetString(s, p.length, ec);
100
101 if (ec)
102 return {};
103
104 p = parsePreamble(s, ec);
105
106 if (ec)
107 return {};
108
109 if (!isPrimitive(p) || !isContextSpecific(p))
110 {
112 return {};
113 }
114
115 if (p.tag != 1)
116 {
118 return {};
119 }
120
121 auto cost = parseInteger<std::uint32_t>(s, p.length, ec);
122
123 if (ec)
124 return {};
125
126 if (!s.empty())
127 {
129 return {};
130 }
131
132 switch (type)
133 {
136 {
138 return {};
139 }
140 break;
141
142 default:
143 break;
144 }
145
146 return std::make_unique<Condition>(type, cost, std::move(b));
147}
148
149} // namespace detail
150
153{
154 // Per the RFC, in a condition we choose a type based
155 // on the tag of the item we contain:
156 //
157 // Condition ::= CHOICE {
158 // preimageSha256 [0] SimpleSha256Condition,
159 // prefixSha256 [1] CompoundSha256Condition,
160 // thresholdSha256 [2] CompoundSha256Condition,
161 // rsaSha256 [3] SimpleSha256Condition,
162 // ed25519Sha256 [4] SimpleSha256Condition
163 // }
164 if (s.empty())
165 {
167 return {};
168 }
169
170 using namespace der;
171
172 auto const p = parsePreamble(s, ec);
173 if (ec)
174 return {};
175
176 // All fulfillments are context-specific, constructed
177 // types
178 if (!isConstructed(p) || !isContextSpecific(p))
179 {
181 return {};
182 }
183
184 if (p.length > s.size())
185 {
187 return {};
188 }
189
191 {
193 return {};
194 }
195
197
198 switch (p.tag)
199 {
200 case 0: // PreimageSha256
202 Type::preimageSha256, Slice(s.data(), p.length), ec);
203 if (!ec)
204 s += p.length;
205 break;
206
207 case 1: // PrefixSha256
209 return {};
210
211 case 2: // ThresholdSha256
213 return {};
214
215 case 3: // RsaSha256
217 return {};
218
219 case 4: // Ed25519Sha256
221 return {};
222
223 default:
225 return {};
226 }
227
228 if (!s.empty())
229 {
231 return {};
232 }
233
234 return c;
235}
236
237} // namespace cryptoconditions
238} // namespace ripple
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
std::size_t length() const noexcept
Definition: Slice.h:86
static std::unique_ptr< Condition > deserialize(Slice s, std::error_code &ec)
Load a condition from its binary form.
Definition: Condition.cpp:152
static constexpr std::size_t maxSerializedCondition
The largest binary condition we support.
Definition: Condition.h:54
static constexpr std::size_t maxPreimageLength
The maximum allowed length of a preimage.
constexpr std::size_t fingerprintSize
Definition: Condition.cpp:69
std::unique_ptr< Condition > loadSimpleSha256(Type type, Slice s, std::error_code &ec)
Definition: Condition.cpp:72
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26