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 <boost/optional.hpp>
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.SetHexExact(params[jss::channel_id].asString()))
65 
66  boost::optional<std::uint64_t> const optDrops =
67  params[jss::amount].isString()
68  ? to_uint64(params[jss::amount].asString())
69  : boost::none;
70 
71  if (!optDrops)
73 
74  std::uint64_t const drops = *optDrops;
75 
76  Serializer msg;
77  serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
78 
79  try
80  {
81  auto const buf = sign(pk, sk, msg.slice());
82  result[jss::signature] = strHex(buf);
83  }
84  catch (std::exception&)
85  {
86  result =
87  RPC::make_error(rpcINTERNAL, "Exception occurred during signing.");
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 
107  boost::optional<PublicKey> pk;
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.SetHexExact(params[jss::channel_id].asString()))
127 
128  boost::optional<std::uint64_t> const optDrops =
129  params[jss::amount].isString()
130  ? to_uint64(params[jss::amount].asString())
131  : boost::none;
132 
133  if (!optDrops)
135 
136  std::uint64_t const drops = *optDrops;
137 
138  auto sig = strUnHex(params[jss::signature].asString());
139  if (!sig || !sig->size())
140  return rpcError(rpcINVALID_PARAMS);
141 
142  Serializer msg;
143  serializePayChanAuthorization(msg, channelId, XRPAmount(drops));
144 
145  Json::Value result;
146  result[jss::signature_verified] =
147  verify(*pk, msg.slice(), makeSlice(*sig), /*canonical*/ true);
148  return result;
149 }
150 
151 } // 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:240
std::string
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
std::exception
STL class.
ripple::publicKeyType
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:203
ripple::to_uint64
boost::optional< std::uint64_t > to_uint64(std::string const &s)
ripple::strUnHex
boost::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Definition: StringUtilities.h:72
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:236
ripple::verify
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical)
Verify a signature on a message.
Definition: PublicKey.cpp:268
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:218
ripple::doChannelAuthorize
Json::Value doChannelAuthorize(RPC::JsonContext &)
Definition: PayChanClaim.cpp:44
ripple::rpcPUBLIC_MALFORMED
@ rpcPUBLIC_MALFORMED
Definition: ErrorCodes.h:117
ripple::Serializer::slice
Slice slice() const noexcept
Definition: Serializer.h:63
std::uint64_t
ripple::rpcError
Json::Value rpcError(int iError, Json::Value jvResult)
Definition: RPCErr.cpp:29
ripple::base_uint::SetHexExact
bool SetHexExact(const char *psz)
Parse a hex string into a base_uint The string must contain exactly bytes * 2 hex characters and must...
Definition: base_uint.h:370
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:124
ripple::RPC::keypairForSignature
std::pair< PublicKey, SecretKey > keypairForSignature(Json::Value const &params, Json::Value &error)
Definition: RPCHelpers.cpp:660
ripple::TokenType::AccountPublic
@ AccountPublic
ripple::rpcCHANNEL_MALFORMED
@ rpcCHANNEL_MALFORMED
Definition: ErrorCodes.h:100
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:67
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:202
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::XRPAmount
Definition: XRPAmount.h:46