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