rippled
Loading...
Searching...
No Matches
Fulfillment.cpp
1#include <xrpl/basics/safe_cast.h>
2#include <xrpl/conditions/Condition.h>
3#include <xrpl/conditions/Fulfillment.h>
4#include <xrpl/conditions/detail/PreimageSha256.h>
5#include <xrpl/conditions/detail/utils.h>
6
7namespace xrpl {
8namespace cryptoconditions {
9
10bool
11match(Fulfillment const& f, Condition const& c)
12{
13 // Fast check: the fulfillment's type must match the
14 // conditions's type:
15 if (f.type() != c.type)
16 return false;
17
18 // Derive the condition from the given fulfillment
19 // and ensure that it matches the given condition.
20 return c == f.condition();
21}
22
23bool
24validate(Fulfillment const& f, Condition const& c, Slice m)
25{
26 return match(f, c) && f.validate(m);
27}
28
29bool
30validate(Fulfillment const& f, Condition const& c)
31{
32 return validate(f, c, {});
33}
34
37{
38 // Per the RFC, in a fulfillment we choose a type based
39 // on the tag of the item we contain:
40 //
41 // Fulfillment ::= CHOICE {
42 // preimageSha256 [0] PreimageFulfillment ,
43 // prefixSha256 [1] PrefixFulfillment,
44 // thresholdSha256 [2] ThresholdFulfillment,
45 // rsaSha256 [3] RsaSha256Fulfillment,
46 // ed25519Sha256 [4] Ed25519Sha512Fulfillment
47 // }
48
49 if (s.empty())
50 {
52 return nullptr;
53 }
54
55 using namespace der;
56
57 auto const p = parsePreamble(s, ec);
58 if (ec)
59 return nullptr;
60
61 // All fulfillments are context-specific, constructed types
62 if (!isConstructed(p) || !isContextSpecific(p))
63 {
65 return nullptr;
66 }
67
68 if (p.length > s.size())
69 {
71 return {};
72 }
73
74 if (p.length < s.size())
75 {
77 return {};
78 }
79
80 if (p.length > maxSerializedFulfillment)
81 {
83 return {};
84 }
85
87
88 using TagType = decltype(p.tag);
89 switch (p.tag)
90 {
91 case safe_cast<TagType>(Type::preimageSha256):
92 f = PreimageSha256::deserialize(Slice(s.data(), p.length), ec);
93 if (ec)
94 return {};
95 s += p.length;
96 break;
97
98 case safe_cast<TagType>(Type::prefixSha256):
100 return {};
101 break;
102
103 case safe_cast<TagType>(Type::thresholdSha256):
105 return {};
106 break;
107
108 case safe_cast<TagType>(Type::rsaSha256):
110 return {};
111 break;
112
113 case safe_cast<TagType>(Type::ed25519Sha256):
115 return {};
116
117 default:
119 return {};
120 }
121
122 if (!s.empty())
123 {
125 return {};
126 }
127
128 return f;
129}
130
131} // namespace cryptoconditions
132} // namespace xrpl
An immutable linear range of bytes.
Definition Slice.h:26
std::size_t length() const noexcept
Definition Slice.h:66
bool empty() const noexcept
Return true if the byte range is empty.
Definition Slice.h:49
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:77
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:60
static std::unique_ptr< Fulfillment > deserialize(Slice s, std::error_code &ec)
Parse the payload for a PreimageSha256 condition.
bool validate(Fulfillment const &f, Condition const &c, Slice m)
Verify if the given message satisfies the fulfillment.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static constexpr std::size_t maxSerializedFulfillment
The largest binary fulfillment we support.
Definition Fulfillment.h:20
static std::unique_ptr< Fulfillment > deserialize(Slice s, std::error_code &ec)
Load a fulfillment from its binary form.
virtual Condition condition() const =0
Returns the condition associated with the given fulfillment.
virtual Type type() const =0
Returns the type of this condition.
virtual bool validate(Slice data) const =0
Validates a fulfillment.