mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Allow channel_verify to specify public key in hex (RIPD-1467)
This commit is contained in:
committed by
Nikolaos D. Bougalis
parent
ad4ba44394
commit
a307d2d03f
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/app/main/Application.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/net/RPCCall.h>
|
||||
#include <ripple/net/RPCErr.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
@@ -37,6 +38,7 @@
|
||||
#include <ripple/beast/core/LexicalCast.h>
|
||||
#include <beast/core/string.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
@@ -82,6 +84,33 @@ std::string createHTTPPost (
|
||||
return s.str ();
|
||||
}
|
||||
|
||||
static
|
||||
boost::optional<std::uint64_t>
|
||||
to_uint64(std::string const& s)
|
||||
{
|
||||
if (s.empty())
|
||||
return boost::none;
|
||||
|
||||
for (auto c : s)
|
||||
{
|
||||
if (!isdigit(c))
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::size_t pos{};
|
||||
auto const drops = std::stoul(s, &pos);
|
||||
if (s.size() != pos)
|
||||
return boost::none;
|
||||
return drops;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
class RPCParser
|
||||
{
|
||||
private:
|
||||
@@ -680,16 +709,9 @@ private:
|
||||
}
|
||||
jvRequest[jss::channel_id] = jvParams[1u].asString ();
|
||||
|
||||
try
|
||||
{
|
||||
auto const drops = std::stoul (jvParams[2u].asString ());
|
||||
(void)drops; // just used for error checking
|
||||
jvRequest[jss::amount] = jvParams[2u];
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
return rpcError (rpcCHANNEL_AMT_MALFORMED);
|
||||
}
|
||||
if (!jvParams[2u].isString() || !to_uint64(jvParams[2u].asString()))
|
||||
return rpcError(rpcCHANNEL_AMT_MALFORMED);
|
||||
jvRequest[jss::amount] = jvParams[2u];
|
||||
|
||||
return jvRequest;
|
||||
}
|
||||
@@ -699,7 +721,21 @@ private:
|
||||
{
|
||||
std::string const strPk = jvParams[0u].asString ();
|
||||
|
||||
if (!parseBase58<PublicKey> (TokenType::TOKEN_ACCOUNT_PUBLIC, strPk))
|
||||
bool const validPublicKey = [&strPk]{
|
||||
if (parseBase58<PublicKey> (TokenType::TOKEN_ACCOUNT_PUBLIC, strPk))
|
||||
return true;
|
||||
|
||||
std::pair<Blob, bool> pkHex(strUnHex (strPk));
|
||||
if (!pkHex.second)
|
||||
return false;
|
||||
|
||||
if (!publicKeyType(makeSlice(pkHex.first)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}();
|
||||
|
||||
if (!validPublicKey)
|
||||
return rpcError (rpcPUBLIC_MALFORMED);
|
||||
|
||||
Json::Value jvRequest (Json::objectValue);
|
||||
@@ -712,16 +748,11 @@ private:
|
||||
return rpcError (rpcCHANNEL_MALFORMED);
|
||||
}
|
||||
jvRequest[jss::channel_id] = jvParams[1u].asString ();
|
||||
try
|
||||
{
|
||||
auto const drops = std::stoul (jvParams[2u].asString ());
|
||||
(void)drops; // just used for error checking
|
||||
jvRequest[jss::amount] = jvParams[2u];
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
return rpcError (rpcCHANNEL_AMT_MALFORMED);
|
||||
}
|
||||
|
||||
if (!jvParams[2u].isString() || !to_uint64(jvParams[2u].asString()))
|
||||
return rpcError(rpcCHANNEL_AMT_MALFORMED);
|
||||
jvRequest[jss::amount] = jvParams[2u];
|
||||
|
||||
jvRequest[jss::signature] = jvParams[3u].asString ();
|
||||
|
||||
return jvRequest;
|
||||
|
||||
@@ -31,8 +31,37 @@
|
||||
#include <ripple/rpc/impl/RPCHelpers.h>
|
||||
#include <ripple/rpc/impl/Tuning.h>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
static
|
||||
boost::optional<std::uint64_t>
|
||||
to_uint64(std::string const& s)
|
||||
{
|
||||
if (s.empty())
|
||||
return boost::none;
|
||||
|
||||
for (auto c : s)
|
||||
{
|
||||
if (!isdigit(c))
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::size_t pos{};
|
||||
auto const drops = std::stoul(s, &pos);
|
||||
if (s.size() != pos)
|
||||
return boost::none;
|
||||
return drops;
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
|
||||
// {
|
||||
// secret_key: <signing_secret_key>
|
||||
// channel_id: 256-bit channel id
|
||||
@@ -54,15 +83,15 @@ Json::Value doChannelAuthorize (RPC::Context& context)
|
||||
if (!channelId.SetHexExact (params[jss::channel_id].asString ()))
|
||||
return rpcError (rpcCHANNEL_MALFORMED);
|
||||
|
||||
std::uint64_t drops = 0;
|
||||
try
|
||||
{
|
||||
drops = std::stoul (params[jss::amount].asString ());
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
boost::optional<std::uint64_t> const optDrops =
|
||||
params[jss::amount].isString()
|
||||
? to_uint64(params[jss::amount].asString())
|
||||
: boost::none;
|
||||
|
||||
if (!optDrops)
|
||||
return rpcError (rpcCHANNEL_AMT_MALFORMED);
|
||||
}
|
||||
|
||||
std::uint64_t const drops = *optDrops;
|
||||
|
||||
Serializer msg;
|
||||
serializePayChanAuthorization (msg, channelId, XRPAmount (drops));
|
||||
@@ -90,29 +119,40 @@ Json::Value doChannelVerify (RPC::Context& context)
|
||||
{
|
||||
auto const& params (context.params);
|
||||
for (auto const& p :
|
||||
{jss::public_key, jss::channel_id, jss::amount, jss::signature})
|
||||
{jss::public_key, jss::channel_id, jss::amount, jss::signature})
|
||||
if (!params.isMember (p))
|
||||
return RPC::missing_field_error (p);
|
||||
|
||||
std::string const strPk = params[jss::public_key].asString ();
|
||||
auto const pk =
|
||||
parseBase58<PublicKey> (TokenType::TOKEN_ACCOUNT_PUBLIC, strPk);
|
||||
if (!pk)
|
||||
return rpcError (rpcPUBLIC_MALFORMED);
|
||||
boost::optional<PublicKey> pk;
|
||||
{
|
||||
std::string const strPk = params[jss::public_key].asString();
|
||||
pk = parseBase58<PublicKey>(TokenType::TOKEN_ACCOUNT_PUBLIC, strPk);
|
||||
|
||||
if (!pk)
|
||||
{
|
||||
std::pair<Blob, bool> pkHex(strUnHex (strPk));
|
||||
if (!pkHex.second)
|
||||
return rpcError(rpcPUBLIC_MALFORMED);
|
||||
auto const pkType = publicKeyType(makeSlice(pkHex.first));
|
||||
if (!pkType)
|
||||
return rpcError(rpcPUBLIC_MALFORMED);
|
||||
pk.emplace(makeSlice(pkHex.first));
|
||||
}
|
||||
}
|
||||
|
||||
uint256 channelId;
|
||||
if (!channelId.SetHexExact (params[jss::channel_id].asString ()))
|
||||
return rpcError (rpcCHANNEL_MALFORMED);
|
||||
|
||||
std::uint64_t drops = 0;
|
||||
try
|
||||
{
|
||||
drops = std::stoul (params[jss::amount].asString ());
|
||||
}
|
||||
catch (std::exception const&)
|
||||
{
|
||||
boost::optional<std::uint64_t> const optDrops =
|
||||
params[jss::amount].isString()
|
||||
? to_uint64(params[jss::amount].asString())
|
||||
: boost::none;
|
||||
|
||||
if (!optDrops)
|
||||
return rpcError (rpcCHANNEL_AMT_MALFORMED);
|
||||
}
|
||||
|
||||
std::uint64_t const drops = *optDrops;
|
||||
|
||||
std::pair<Blob, bool> sig(strUnHex (params[jss::signature].asString ()));
|
||||
if (!sig.second || !sig.first.size ())
|
||||
|
||||
Reference in New Issue
Block a user