rippled
Loading...
Searching...
No Matches
PayChanClaim.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2014 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/app/main/Application.h>
21#include <xrpld/rpc/Context.h>
22#include <xrpld/rpc/detail/RPCHelpers.h>
23
24#include <xrpl/basics/StringUtilities.h>
25#include <xrpl/ledger/ReadView.h>
26#include <xrpl/protocol/ErrorCodes.h>
27#include <xrpl/protocol/PayChan.h>
28#include <xrpl/protocol/RPCErr.h>
29#include <xrpl/protocol/jss.h>
30
31#include <optional>
32
33namespace ripple {
34
35// {
36// secret_key: <signing_secret_key>
37// key_type: optional; either ed25519 or secp256k1 (default to secp256k1)
38// channel_id: 256-bit channel id
39// drops: 64-bit uint (as string)
40// }
43{
44 if (context.role != Role::ADMIN && !context.app.config().canSign())
45 {
46 return RPC::make_error(
47 rpcNOT_SUPPORTED, "Signing is not supported by this server.");
48 }
49
50 auto const& params(context.params);
51 for (auto const& p : {jss::channel_id, jss::amount})
52 if (!params.isMember(p))
54
55 // Compatibility if a key type isn't specified. If it is, the
56 // keypairForSignature code will validate parameters and return
57 // the appropriate error.
58 if (!params.isMember(jss::key_type) && !params.isMember(jss::secret))
59 return RPC::missing_field_error(jss::secret);
60
61 Json::Value result;
63 RPC::keypairForSignature(params, result, context.apiVersion);
64
65 XRPL_ASSERT(
66 keyPair || RPC::contains_error(result),
67 "ripple::doChannelAuthorize : valid keyPair or an error");
68 if (!keyPair || RPC::contains_error(result))
69 return result;
70
71 PublicKey const& pk = keyPair->first;
72 SecretKey const& sk = keyPair->second;
73
74 uint256 channelId;
75 if (!channelId.parseHex(params[jss::channel_id].asString()))
77
78 std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
79 ? to_uint64(params[jss::amount].asString())
81
82 if (!optDrops)
84
85 std::uint64_t const drops = *optDrops;
86
87 Serializer msg;
88 serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
89
90 try
91 {
92 auto const buf = sign(pk, sk, msg.slice());
93 result[jss::signature] = strHex(buf);
94 }
95 catch (std::exception const& ex)
96 {
97 // LCOV_EXCL_START
98 result = RPC::make_error(
100 "Exception occurred during signing: " + std::string(ex.what()));
101 // LCOV_EXCL_STOP
102 }
103 return result;
104}
105
106// {
107// public_key: <public_key>
108// channel_id: 256-bit channel id
109// drops: 64-bit uint (as string)
110// signature: signature to verify
111// }
114{
115 auto const& params(context.params);
116 for (auto const& p :
117 {jss::public_key, jss::channel_id, jss::amount, jss::signature})
118 if (!params.isMember(p))
119 return RPC::missing_field_error(p);
120
122 {
123 std::string const strPk = params[jss::public_key].asString();
124 pk = parseBase58<PublicKey>(TokenType::AccountPublic, strPk);
125
126 if (!pk)
127 {
128 auto pkHex = strUnHex(strPk);
129 if (!pkHex)
131 auto const pkType = publicKeyType(makeSlice(*pkHex));
132 if (!pkType)
134 pk.emplace(makeSlice(*pkHex));
135 }
136 }
137
138 uint256 channelId;
139 if (!channelId.parseHex(params[jss::channel_id].asString()))
141
142 std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
143 ? to_uint64(params[jss::amount].asString())
144 : std::nullopt;
145
146 if (!optDrops)
148
149 std::uint64_t const drops = *optDrops;
150
151 auto sig = strUnHex(params[jss::signature].asString());
152 if (!sig || !sig->size())
154
155 Serializer msg;
156 serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
157
158 Json::Value result;
159 result[jss::signature_verified] =
160 verify(*pk, msg.slice(), makeSlice(*sig), /*canonical*/ true);
161 return result;
162}
163
164} // namespace ripple
Represents a JSON value.
Definition json_value.h:149
virtual Config & config()=0
bool canSign() const
Definition Config.h:348
A public key.
Definition PublicKey.h:62
A secret key.
Definition SecretKey.h:38
Slice slice() const noexcept
Definition Serializer.h:66
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:503
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:283
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:25
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:132
@ rpcCHANNEL_AMT_MALFORMED
Definition ErrorCodes.h:101
@ rpcPUBLIC_MALFORMED
Definition ErrorCodes.h:117
@ rpcINVALID_PARAMS
Definition ErrorCodes.h:84
@ rpcINTERNAL
Definition ErrorCodes.h:130
@ rpcCHANNEL_MALFORMED
Definition ErrorCodes.h:100
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:31
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:30
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:244
unsigned int apiVersion
Definition Context.h:49
Application & app
Definition Context.h:41
T what(T... args)