rippled
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 <ripple/app/main/Application.h>
21 #include <ripple/basics/StringUtilities.h>
22 #include <ripple/ledger/ReadView.h>
23 #include <ripple/net/RPCErr.h>
24 #include <ripple/protocol/ErrorCodes.h>
25 #include <ripple/protocol/PayChan.h>
26 #include <ripple/protocol/STAccount.h>
27 #include <ripple/protocol/jss.h>
28 #include <ripple/resource/Fees.h>
29 #include <ripple/rpc/Context.h>
30 #include <ripple/rpc/impl/RPCHelpers.h>
31 #include <ripple/rpc/impl/Tuning.h>
32 
33 #include <optional>
34 
35 namespace ripple {
36 
37 // {
38 // secret_key: <signing_secret_key>
39 // key_type: optional; either ed25519 or secp256k1 (default to secp256k1)
40 // channel_id: 256-bit channel id
41 // drops: 64-bit uint (as string)
42 // }
45 {
46  auto const& params(context.params);
47  for (auto const& p : {jss::channel_id, jss::amount})
48  if (!params.isMember(p))
49  return RPC::missing_field_error(p);
50 
51  // Compatibility if a key type isn't specified. If it is, the
52  // keypairForSignature code will validate parameters and return
53  // the appropriate error.
54  if (!params.isMember(jss::key_type) && !params.isMember(jss::secret))
55  return RPC::missing_field_error(jss::secret);
56 
57  Json::Value result;
58  auto const [pk, sk] = RPC::keypairForSignature(params, result);
59  if (RPC::contains_error(result))
60  return result;
61 
62  uint256 channelId;
63  if (!channelId.parseHex(params[jss::channel_id].asString()))
65 
66  std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
67  ? to_uint64(params[jss::amount].asString())
68  : std::nullopt;
69 
70  if (!optDrops)
72 
73  std::uint64_t const drops = *optDrops;
74 
75  Serializer msg;
76  serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
77 
78  try
79  {
80  auto const buf = sign(pk, sk, msg.slice());
81  result[jss::signature] = strHex(buf);
82  }
83  catch (std::exception const& ex)
84  {
85  result = RPC::make_error(
87  "Exception occurred during signing: " + std::string(ex.what()));
88  }
89  return result;
90 }
91 
92 // {
93 // public_key: <public_key>
94 // channel_id: 256-bit channel id
95 // drops: 64-bit uint (as string)
96 // signature: signature to verify
97 // }
100 {
101  auto const& params(context.params);
102  for (auto const& p :
103  {jss::public_key, jss::channel_id, jss::amount, jss::signature})
104  if (!params.isMember(p))
105  return RPC::missing_field_error(p);
106 
108  {
109  std::string const strPk = params[jss::public_key].asString();
110  pk = parseBase58<PublicKey>(TokenType::AccountPublic, strPk);
111 
112  if (!pk)
113  {
114  auto pkHex = strUnHex(strPk);
115  if (!pkHex)
117  auto const pkType = publicKeyType(makeSlice(*pkHex));
118  if (!pkType)
120  pk.emplace(makeSlice(*pkHex));
121  }
122  }
123 
124  uint256 channelId;
125  if (!channelId.parseHex(params[jss::channel_id].asString()))
127 
128  std::optional<std::uint64_t> const optDrops = params[jss::amount].isString()
129  ? to_uint64(params[jss::amount].asString())
130  : std::nullopt;
131 
132  if (!optDrops)
134 
135  std::uint64_t const drops = *optDrops;
136 
137  auto sig = strUnHex(params[jss::signature].asString());
138  if (!sig || !sig->size())
139  return rpcError(rpcINVALID_PARAMS);
140 
141  Serializer msg;
142  serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
143 
144  Json::Value result;
145  result[jss::signature_verified] =
146  verify(*pk, msg.slice(), makeSlice(*sig), /*canonical*/ true);
147  return result;
148 }
149 
150 } // namespace ripple
ripple::RPC::JsonContext
Definition: Context.h:53
ripple::makeSlice
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:241
std::string
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
std::exception
STL class.
ripple::verify
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical) noexcept
Verify a signature on a message.
Definition: PublicKey.cpp:272
std::optional::emplace
T emplace(T... args)
ripple::doChannelVerify
Json::Value doChannelVerify(RPC::JsonContext &)
Definition: PayChanClaim.cpp:99
ripple::serializePayChanAuthorization
void serializePayChanAuthorization(Serializer &msg, uint256 const &key, XRPAmount const &amt)
Definition: protocol/PayChan.h:31
ripple::RPC::missing_field_error
Json::Value missing_field_error(std::string const &name)
Definition: ErrorCodes.h:262
ripple::publicKeyType
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
ripple::base_uint< 256 >
ripple::RPC::contains_error
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
Definition: ErrorCodes.cpp:194
ripple::doChannelAuthorize
Json::Value doChannelAuthorize(RPC::JsonContext &)
Definition: PayChanClaim.cpp:44
ripple::to_uint64
std::optional< std::uint64_t > to_uint64(std::string const &s)
ripple::rpcPUBLIC_MALFORMED
@ rpcPUBLIC_MALFORMED
Definition: ErrorCodes.h:117
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
std::uint64_t
ripple::rpcINTERNAL
@ rpcINTERNAL
Definition: ErrorCodes.h:130
ripple::rpcCHANNEL_AMT_MALFORMED
@ rpcCHANNEL_AMT_MALFORMED
Definition: ErrorCodes.h:101
ripple::Serializer
Definition: Serializer.h:39
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:238
ripple::RPC::keypairForSignature
std::pair< PublicKey, SecretKey > keypairForSignature(Json::Value const &params, Json::Value &error)
Definition: RPCHelpers.cpp:849
ripple::TokenType::AccountPublic
@ AccountPublic
ripple::rpcCHANNEL_MALFORMED
@ rpcCHANNEL_MALFORMED
Definition: ErrorCodes.h:100
optional
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:30
ripple::base_uint::parseHex
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition: base_uint.h:496
ripple::strUnHex
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition: StringUtilities.h:50
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::RPC::make_error
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
Definition: ErrorCodes.cpp:178
std::exception::what
T what(T... args)
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::XRPAmount
Definition: XRPAmount.h:46