rippled
Loading...
Searching...
No Matches
PayChanClaim.cpp
1#include <xrpld/app/main/Application.h>
2#include <xrpld/rpc/Context.h>
3#include <xrpld/rpc/detail/RPCHelpers.h>
4
5#include <xrpl/basics/StringUtilities.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/protocol/ErrorCodes.h>
8#include <xrpl/protocol/PayChan.h>
9#include <xrpl/protocol/RPCErr.h>
10#include <xrpl/protocol/jss.h>
11
12#include <optional>
13
14namespace ripple {
15
16// {
17// secret_key: <signing_secret_key>
18// key_type: optional; either ed25519 or secp256k1 (default to secp256k1)
19// channel_id: 256-bit channel id
20// drops: 64-bit uint (as string)
21// }
24{
25 if (context.role != Role::ADMIN && !context.app.config().canSign())
26 {
27 return RPC::make_error(
28 rpcNOT_SUPPORTED, "Signing is not supported by this server.");
29 }
30
31 auto const& params(context.params);
32 for (auto const& p : {jss::channel_id, jss::amount})
33 if (!params.isMember(p))
35
36 // Compatibility if a key type isn't specified. If it is, the
37 // keypairForSignature code will validate parameters and return
38 // the appropriate error.
39 if (!params.isMember(jss::key_type) && !params.isMember(jss::secret))
40 return RPC::missing_field_error(jss::secret);
41
42 Json::Value result;
44 RPC::keypairForSignature(params, result, context.apiVersion);
45
46 XRPL_ASSERT(
47 keyPair || RPC::contains_error(result),
48 "ripple::doChannelAuthorize : valid keyPair or an error");
49 if (!keyPair || RPC::contains_error(result))
50 return result;
51
52 PublicKey const& pk = keyPair->first;
53 SecretKey const& sk = keyPair->second;
54
55 uint256 channelId;
56 if (!channelId.parseHex(params[jss::channel_id].asString()))
58
59 std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
60 ? to_uint64(params[jss::amount].asString())
62
63 if (!optDrops)
65
66 std::uint64_t const drops = *optDrops;
67
68 Serializer msg;
69 serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
70
71 try
72 {
73 auto const buf = sign(pk, sk, msg.slice());
74 result[jss::signature] = strHex(buf);
75 }
76 catch (std::exception const& ex)
77 {
78 // LCOV_EXCL_START
79 result = RPC::make_error(
81 "Exception occurred during signing: " + std::string(ex.what()));
82 // LCOV_EXCL_STOP
83 }
84 return result;
85}
86
87// {
88// public_key: <public_key>
89// channel_id: 256-bit channel id
90// drops: 64-bit uint (as string)
91// signature: signature to verify
92// }
95{
96 auto const& params(context.params);
97 for (auto const& p :
98 {jss::public_key, jss::channel_id, jss::amount, jss::signature})
99 if (!params.isMember(p))
100 return RPC::missing_field_error(p);
101
103 {
104 std::string const strPk = params[jss::public_key].asString();
105 pk = parseBase58<PublicKey>(TokenType::AccountPublic, strPk);
106
107 if (!pk)
108 {
109 auto pkHex = strUnHex(strPk);
110 if (!pkHex)
112 auto const pkType = publicKeyType(makeSlice(*pkHex));
113 if (!pkType)
115 pk.emplace(makeSlice(*pkHex));
116 }
117 }
118
119 uint256 channelId;
120 if (!channelId.parseHex(params[jss::channel_id].asString()))
122
123 std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
124 ? to_uint64(params[jss::amount].asString())
125 : std::nullopt;
126
127 if (!optDrops)
129
130 std::uint64_t const drops = *optDrops;
131
132 auto sig = strUnHex(params[jss::signature].asString());
133 if (!sig || !sig->size())
135
136 Serializer msg;
137 serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
138
139 Json::Value result;
140 result[jss::signature_verified] =
141 verify(*pk, msg.slice(), makeSlice(*sig), /*canonical*/ true);
142 return result;
143}
144
145} // namespace ripple
Represents a JSON value.
Definition json_value.h:131
virtual Config & config()=0
bool canSign() const
Definition Config.h:329
A public key.
Definition PublicKey.h:43
A secret key.
Definition SecretKey.h:19
Slice slice() const noexcept
Definition Serializer.h:47
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:484
T emplace(T... args)
T is_same_v
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Json::Value missing_field_error(std::string const &name)
Definition ErrorCodes.h:264
std::optional< std::pair< PublicKey, SecretKey > > keypairForSignature(Json::Value const &params, Json::Value &error, unsigned int apiVersion)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
Json::Value doChannelVerify(RPC::JsonContext &)
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Json::Value doChannelAuthorize(RPC::JsonContext &)
@ rpcNOT_SUPPORTED
Definition ErrorCodes.h:113
@ rpcCHANNEL_AMT_MALFORMED
Definition ErrorCodes.h:82
@ rpcPUBLIC_MALFORMED
Definition ErrorCodes.h:98
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:65
@ rpcINTERNAL
Definition ErrorCodes.h:111
@ rpcCHANNEL_MALFORMED
Definition ErrorCodes.h:81
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
std::optional< std::uint64_t > to_uint64(std::string const &s)
Json::Value rpcError(int iError)
Definition RPCErr.cpp:12
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:11
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:225
unsigned int apiVersion
Definition Context.h:30
Application & app
Definition Context.h:22
T what(T... args)