Address issues identified by external review:

* RIPD-1617, RIPD-1619, RIPD-1621:
  Verify serialized public keys more strictly before
  using them.

* RIPD-1618:
    * Simplify the base58 decoder logic.
    * Reduce the complexity of the base58 encoder and
      eliminate a potential out-of-bounds memory access.
    * Improve type safety by using an `enum class` to
      enforce strict type checking for token types.

* RIPD-1616:
  Avoid calling `memcpy` with a null pointer even if the
  size is specified as zero, since it results in undefined
  behavior.

Acknowledgements:
Ripple thanks Guido Vranken for responsibly disclosing these
issues.

Bug Bounties and Responsible Disclosures:
We welcome reviews of the rippled code and urge researchers
to responsibly disclose any issues that they may find. For
more on Ripple's Bug Bounty program, please visit:
https://ripple.com/bug-bounty
This commit is contained in:
Nikolaos D. Bougalis
2018-03-15 20:58:05 -07:00
parent 25de6b0a5f
commit d5f981f5fc
47 changed files with 393 additions and 264 deletions

View File

@@ -66,7 +66,7 @@ RCLCxPeerPos::getJson() const
auto ret = proposal().getJson(); auto ret = proposal().getJson();
if (publicKey().size()) if (publicKey().size())
ret[jss::peer_id] = toBase58(TokenType::TOKEN_NODE_PUBLIC, publicKey()); ret[jss::peer_id] = toBase58(TokenType::NodePublic, publicKey());
return ret; return ret;
} }

View File

@@ -251,7 +251,7 @@ RCLValidationsAdaptor::doStaleWrite(ScopedLockType&)
auto const initialSeq = ledgerSeq.value_or( auto const initialSeq = ledgerSeq.value_or(
app_.getLedgerMaster().getCurrentLedgerIndex()); app_.getLedgerMaster().getCurrentLedgerIndex());
auto const nodePubKey = toBase58( auto const nodePubKey = toBase58(
TokenType::TOKEN_NODE_PUBLIC, val->getSignerPublic()); TokenType::NodePublic, val->getSignerPublic());
auto const signTime = auto const signTime =
val->getSignTime().time_since_epoch().count(); val->getSignTime().time_since_epoch().count();
@@ -300,10 +300,10 @@ handleNewValidation(Application& app,
s << "Val for " << hash s << "Val for " << hash
<< (val->isTrusted() ? " trusted/" : " UNtrusted/") << (val->isTrusted() ? " trusted/" : " UNtrusted/")
<< (val->isFull() ? "full" : "partial") << " from " << (val->isFull() ? "full" : "partial") << " from "
<< (masterKey ? toBase58(TokenType::TOKEN_NODE_PUBLIC, *masterKey) << (masterKey ? toBase58(TokenType::NodePublic, *masterKey)
: "unknown") : "unknown")
<< " signing key " << " signing key "
<< toBase58(TokenType::TOKEN_NODE_PUBLIC, signingKey) << " " << msg << toBase58(TokenType::NodePublic, signingKey) << " " << msg
<< " src=" << source; << " src=" << source;
}; };
@@ -346,7 +346,7 @@ handleNewValidation(Application& app,
else else
{ {
JLOG(j.debug()) << "Val for " << hash << " from " JLOG(j.debug()) << "Val for " << hash << " from "
<< toBase58(TokenType::TOKEN_NODE_PUBLIC, signingKey) << toBase58(TokenType::NodePublic, signingKey)
<< " not added UNlisted"; << " not added UNlisted";
} }

View File

@@ -66,9 +66,9 @@ loadNodeIdentity (Application& app)
while (st.fetch ()) while (st.fetch ())
{ {
auto const sk = parseBase58<SecretKey>( auto const sk = parseBase58<SecretKey>(
TOKEN_NODE_PRIVATE, priKO.value_or("")); TokenType::NodePrivate, priKO.value_or(""));
auto const pk = parseBase58<PublicKey>( auto const pk = parseBase58<PublicKey>(
TOKEN_NODE_PUBLIC, pubKO.value_or("")); TokenType::NodePublic, pubKO.value_or(""));
// Only use if the public and secret keys are a pair // Only use if the public and secret keys are a pair
if (sk && pk && (*pk == derivePublicKey (KeyType::secp256k1, *sk))) if (sk && pk && (*pk == derivePublicKey (KeyType::secp256k1, *sk)))
@@ -86,8 +86,8 @@ loadNodeIdentity (Application& app)
*db << str (boost::format ( *db << str (boost::format (
"INSERT INTO NodeIdentity (PublicKey,PrivateKey) VALUES ('%s','%s');") "INSERT INTO NodeIdentity (PublicKey,PrivateKey) VALUES ('%s','%s');")
% toBase58 (TokenType::TOKEN_NODE_PUBLIC, *publicKey) % toBase58 (TokenType::NodePublic, *publicKey)
% toBase58 (TokenType::TOKEN_NODE_PRIVATE, *secretKey)); % toBase58 (TokenType::NodePrivate, *secretKey));
} }
return { *publicKey, *secretKey }; return { *publicKey, *secretKey };

View File

@@ -784,7 +784,7 @@ void NetworkOPsImp::processClusterTimer ()
{ {
protocol::TMClusterNode& n = *cluster.add_clusternodes(); protocol::TMClusterNode& n = *cluster.add_clusternodes();
n.set_publickey(toBase58 ( n.set_publickey(toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
node.identity())); node.identity()));
n.set_reporttime( n.set_reporttime(
node.getReportTime().time_since_epoch().count()); node.getReportTime().time_since_epoch().count());
@@ -1556,9 +1556,9 @@ void NetworkOPsImp::pubManifest (Manifest const& mo)
jvObj [jss::type] = "manifestReceived"; jvObj [jss::type] = "manifestReceived";
jvObj [jss::master_key] = toBase58( jvObj [jss::master_key] = toBase58(
TokenType::TOKEN_NODE_PUBLIC, mo.masterKey); TokenType::NodePublic, mo.masterKey);
jvObj [jss::signing_key] = toBase58( jvObj [jss::signing_key] = toBase58(
TokenType::TOKEN_NODE_PUBLIC, mo.signingKey); TokenType::NodePublic, mo.signingKey);
jvObj [jss::seq] = Json::UInt (mo.sequence); jvObj [jss::seq] = Json::UInt (mo.sequence);
jvObj [jss::signature] = strHex (mo.getSignature ()); jvObj [jss::signature] = strHex (mo.getSignature ());
jvObj [jss::master_signature] = strHex (mo.getMasterSignature ()); jvObj [jss::master_signature] = strHex (mo.getMasterSignature ());
@@ -1695,7 +1695,7 @@ void NetworkOPsImp::pubValidation (STValidation::ref val)
jvObj [jss::type] = "validationReceived"; jvObj [jss::type] = "validationReceived";
jvObj [jss::validation_public_key] = toBase58( jvObj [jss::validation_public_key] = toBase58(
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
val->getSignerPublic()); val->getSignerPublic());
jvObj [jss::ledger_hash] = to_string (val->getLedgerHash ()); jvObj [jss::ledger_hash] = to_string (val->getLedgerHash ());
jvObj [jss::signature] = strHex (val->getSignature ()); jvObj [jss::signature] = strHex (val->getSignature ());
@@ -2122,7 +2122,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
if (!app_.getValidationPublicKey().empty()) if (!app_.getValidationPublicKey().empty())
{ {
info[jss::pubkey_validator] = toBase58 ( info[jss::pubkey_validator] = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
app_.validators().localPublicKey()); app_.validators().localPublicKey());
} }
else else
@@ -2132,7 +2132,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin)
} }
info[jss::pubkey_node] = toBase58 ( info[jss::pubkey_node] = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
app_.nodeIdentity().first); app_.nodeIdentity().first);
info[jss::complete_ledgers] = info[jss::complete_ledgers] =
@@ -2820,7 +2820,7 @@ bool NetworkOPsImp::subServer (InfoSub::ref isrListener, Json::Value& jvResult,
jvResult[jss::load_factor] = feeTrack.getLoadFactor (); jvResult[jss::load_factor] = feeTrack.getLoadFactor ();
jvResult [jss::hostid] = getHostId (admin); jvResult [jss::hostid] = getHostId (admin);
jvResult[jss::pubkey_node] = toBase58 ( jvResult[jss::pubkey_node] = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
app_.nodeIdentity().first); app_.nodeIdentity().first);
ScopedLockType sl (mSubLock); ScopedLockType sl (mSubLock);

View File

@@ -57,10 +57,8 @@ Manifest::make_Manifest (std::string s)
auto const spk = st.getFieldVL (sfSigningPubKey); auto const spk = st.getFieldVL (sfSigningPubKey);
if (! publicKeyType (makeSlice(spk))) if (! publicKeyType (makeSlice(spk)))
return boost::none; return boost::none;
auto const opt_sig = get (st, sfSignature); if (! get (st, sfSignature))
if (! opt_sig)
return boost::none; return boost::none;
return Manifest (std::move (s), PublicKey (makeSlice(pk)), return Manifest (std::move (s), PublicKey (makeSlice(pk)),
PublicKey (makeSlice(spk)), *opt_seq); PublicKey (makeSlice(spk)), *opt_seq);
} }
@@ -83,7 +81,7 @@ logMftAct (
std::uint32_t seq) std::uint32_t seq)
{ {
s << "Manifest: " << action << s << "Manifest: " << action <<
";Pk: " << toBase58 (TokenType::TOKEN_NODE_PUBLIC, pk) << ";Pk: " << toBase58 (TokenType::NodePublic, pk) <<
";Seq: " << seq << ";"; ";Seq: " << seq << ";";
return s; return s;
} }
@@ -97,7 +95,7 @@ Stream& logMftAct (
std::uint32_t oldSeq) std::uint32_t oldSeq)
{ {
s << "Manifest: " << action << s << "Manifest: " << action <<
";Pk: " << toBase58 (TokenType::TOKEN_NODE_PUBLIC, pk) << ";Pk: " << toBase58 (TokenType::NodePublic, pk) <<
";Seq: " << seq << ";Seq: " << seq <<
";OldSeq: " << oldSeq << ";"; ";OldSeq: " << oldSeq << ";";
return s; return s;

View File

@@ -98,14 +98,14 @@ ValidatorList::load (
auto const ret = strUnHex (key); auto const ret = strUnHex (key);
if (! ret.second || ! ret.first.size ()) if (! ret.second || ! publicKeyType(makeSlice(ret.first)))
{ {
JLOG (j_.error()) << JLOG (j_.error()) <<
"Invalid validator list publisher key: " << key; "Invalid validator list publisher key: " << key;
return false; return false;
} }
auto id = PublicKey(Slice{ ret.first.data (), ret.first.size() }); auto id = PublicKey(makeSlice(ret.first));
if (validatorManifests_.revoked (id)) if (validatorManifests_.revoked (id))
{ {
@@ -154,7 +154,7 @@ ValidatorList::load (
} }
auto const id = parseBase58<PublicKey>( auto const id = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, match[1]); TokenType::NodePublic, match[1]);
if (!id) if (!id)
{ {
@@ -230,7 +230,7 @@ ValidatorList::applyList (
std::pair<Blob, bool> ret (strUnHex ( std::pair<Blob, bool> ret (strUnHex (
val["validation_public_key"].asString ())); val["validation_public_key"].asString ()));
if (! ret.second || ! ret.first.size ()) if (! ret.second || ! publicKeyType(makeSlice(ret.first)))
{ {
JLOG (j_.error()) << JLOG (j_.error()) <<
"Invalid node identity: " << "Invalid node identity: " <<
@@ -440,7 +440,7 @@ ValidatorList::removePublisherList (PublicKey const& publisherKey)
JLOG (j_.debug()) << JLOG (j_.debug()) <<
"Removing validator list for revoked publisher " << "Removing validator list for revoked publisher " <<
toBase58(TokenType::TOKEN_NODE_PUBLIC, publisherKey); toBase58(TokenType::NodePublic, publisherKey);
for (auto const& val : iList->second.list) for (auto const& val : iList->second.list)
{ {
@@ -506,7 +506,7 @@ ValidatorList::getJson() const
{ {
for (auto const& key : it->second.list) for (auto const& key : it->second.list)
jLocalStaticKeys.append( jLocalStaticKeys.append(
toBase58(TokenType::TOKEN_NODE_PUBLIC, key)); toBase58(TokenType::NodePublic, key));
} }
// Publisher lists // Publisher lists
@@ -528,7 +528,7 @@ ValidatorList::getJson() const
Json::Value& keys = (curr[jss::list] = Json::arrayValue); Json::Value& keys = (curr[jss::list] = Json::arrayValue);
for (auto const& key : p.second.list) for (auto const& key : p.second.list)
{ {
keys.append(toBase58(TokenType::TOKEN_NODE_PUBLIC, key)); keys.append(toBase58(TokenType::NodePublic, key));
} }
} }
@@ -537,7 +537,7 @@ ValidatorList::getJson() const
(res[jss::trusted_validator_keys] = Json::arrayValue); (res[jss::trusted_validator_keys] = Json::arrayValue);
for (auto const& k : trustedKeys_) for (auto const& k : trustedKeys_)
{ {
jValidatorKeys.append(toBase58(TokenType::TOKEN_NODE_PUBLIC, k)); jValidatorKeys.append(toBase58(TokenType::NodePublic, k));
} }
// signing keys // signing keys
@@ -549,8 +549,8 @@ ValidatorList::getJson() const
if (it != keyListings_.end()) if (it != keyListings_.end())
{ {
jSigningKeys[toBase58( jSigningKeys[toBase58(
TokenType::TOKEN_NODE_PUBLIC, manifest.masterKey)] = TokenType::NodePublic, manifest.masterKey)] =
toBase58(TokenType::TOKEN_NODE_PUBLIC, manifest.signingKey); toBase58(TokenType::NodePublic, manifest.signingKey);
} }
}); });

View File

@@ -348,7 +348,6 @@ PayChanClaim::preflight (PreflightContext const& ctx)
if (! ctx.rules.enabled(featurePayChan)) if (! ctx.rules.enabled(featurePayChan))
return temDISABLED; return temDISABLED;
bool const noTecs = ctx.rules.enabled(fix1512); bool const noTecs = ctx.rules.enabled(fix1512);
auto const ret = preflight1 (ctx); auto const ret = preflight1 (ctx);

View File

@@ -722,7 +722,7 @@ private:
std::string const strPk = jvParams[0u].asString (); std::string const strPk = jvParams[0u].asString ();
bool const validPublicKey = [&strPk]{ bool const validPublicKey = [&strPk]{
if (parseBase58<PublicKey> (TokenType::TOKEN_ACCOUNT_PUBLIC, strPk)) if (parseBase58<PublicKey> (TokenType::AccountPublic, strPk))
return true; return true;
std::pair<Blob, bool> pkHex(strUnHex (strPk)); std::pair<Blob, bool> pkHex(strUnHex (strPk));
@@ -775,7 +775,7 @@ private:
if (i < 2) if (i < 2)
{ {
if (parseBase58<PublicKey> ( if (parseBase58<PublicKey> (
TokenType::TOKEN_ACCOUNT_PUBLIC, strParam) || TokenType::AccountPublic, strParam) ||
parseBase58<AccountID> (strParam) || parseBase58<AccountID> (strParam) ||
parseGenericSeed (strParam)) parseGenericSeed (strParam))
{ {
@@ -810,7 +810,7 @@ private:
--iCursor; --iCursor;
} }
if (! parseBase58<PublicKey>(TokenType::TOKEN_ACCOUNT_PUBLIC, strIdent) && if (! parseBase58<PublicKey>(TokenType::AccountPublic, strIdent) &&
! parseBase58<AccountID>(strIdent) && ! parseBase58<AccountID>(strIdent) &&
! parseGenericSeed(strIdent)) ! parseGenericSeed(strIdent))
return rpcError (rpcACT_MALFORMED); return rpcError (rpcACT_MALFORMED);

View File

@@ -121,7 +121,7 @@ Cluster::load (Section const& nodes)
} }
auto const id = parseBase58<PublicKey>( auto const id = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, match[1]); TokenType::NodePublic, match[1]);
if (!id) if (!id)
{ {

View File

@@ -363,7 +363,7 @@ ConnectAttempt::processResponse()
return close(); // verifyHello logs return close(); // verifyHello logs
JLOG(journal_.info()) << JLOG(journal_.info()) <<
"Public Key: " << toBase58 ( "Public Key: " << toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
*publicKey); *publicKey);
auto const protocol = auto const protocol =

View File

@@ -424,7 +424,7 @@ OverlayImpl::add_active (std::shared_ptr<PeerImp> const& peer)
"activated " << peer->getRemoteAddress() << "activated " << peer->getRemoteAddress() <<
" (" << peer->id() << ":" << " (" << peer->id() << ":" <<
toBase58 ( toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
peer->getNodePublic()) << ")"; peer->getNodePublic()) << ")";
// As we are not on the strand, run() must be called // As we are not on the strand, run() must be called
@@ -610,7 +610,7 @@ OverlayImpl::activate (std::shared_ptr<PeerImp> const& peer)
"activated " << peer->getRemoteAddress() << "activated " << peer->getRemoteAddress() <<
" (" << peer->id() << " (" << peer->id() <<
":" << toBase58 ( ":" << toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
peer->getNodePublic()) << ")"; peer->getNodePublic()) << ")";
// We just accepted this peer so we have non-zero active peers // We just accepted this peer so we have non-zero active peers

View File

@@ -256,7 +256,7 @@ PeerImp::json()
Json::Value ret (Json::objectValue); Json::Value ret (Json::objectValue);
ret[jss::public_key] = toBase58 ( ret[jss::public_key] = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, publicKey_); TokenType::NodePublic, publicKey_);
ret[jss::address] = remote_address_.to_string(); ret[jss::address] = remote_address_.to_string();
if (m_inbound) if (m_inbound)
@@ -629,7 +629,7 @@ void PeerImp::doAccept()
JLOG(journal_.info()) << "Protocol: " << to_string(protocol); JLOG(journal_.info()) << "Protocol: " << to_string(protocol);
JLOG(journal_.info()) << JLOG(journal_.info()) <<
"Public Key: " << toBase58 ( "Public Key: " << toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
publicKey_); publicKey_);
if (auto member = app_.cluster().member(publicKey_)) if (auto member = app_.cluster().member(publicKey_))
{ {
@@ -932,7 +932,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMCluster> const& m)
name = node.nodename(); name = node.nodename();
auto const publicKey = parseBase58<PublicKey>( auto const publicKey = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, node.publickey()); TokenType::NodePublic, node.publickey());
// NIKB NOTE We should drop the peer immediately if // NIKB NOTE We should drop the peer immediately if
// they send us a public key we can't parse // they send us a public key we can't parse
@@ -1610,8 +1610,7 @@ PeerImp::onMessage (std::shared_ptr <protocol::TMValidation> const& m)
STValidation::pointer val; STValidation::pointer val;
{ {
SerialIter sit (makeSlice(m->validation())); SerialIter sit (makeSlice(m->validation()));
val = std::make_shared < val = std::make_shared <STValidation> (std::ref (sit), false);
STValidation> (std::ref (sit), false);
val->setSeen (closeTime); val->setSeen (closeTime);
} }

View File

@@ -112,7 +112,7 @@ buildHello (
h.set_nettime (app.timeKeeper().now().time_since_epoch().count()); h.set_nettime (app.timeKeeper().now().time_since_epoch().count());
h.set_nodepublic ( h.set_nodepublic (
toBase58 ( toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
app.nodeIdentity().first)); app.nodeIdentity().first));
h.set_nodeproof (sig.data(), sig.size()); h.set_nodeproof (sig.data(), sig.size());
// h.set_ipv4port (portNumber); // ignored now // h.set_ipv4port (portNumber); // ignored now
@@ -247,7 +247,7 @@ parseHello (bool request, beast::http::fields const& h, beast::Journal journal)
if (iter == h.end()) if (iter == h.end())
return boost::none; return boost::none;
auto const pk = parseBase58<PublicKey>( auto const pk = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, iter->value().to_string()); TokenType::NodePublic, iter->value().to_string());
if (!pk) if (!pk)
return boost::none; return boost::none;
hello.set_nodepublic (iter->value().to_string()); hello.set_nodepublic (iter->value().to_string());
@@ -381,7 +381,7 @@ verifyHello (protocol::TMHello const& h,
} }
auto const publicKey = parseBase58<PublicKey>( auto const publicKey = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, h.nodepublic()); TokenType::NodePublic, h.nodepublic());
if (! publicKey) if (! publicKey)
{ {
@@ -390,6 +390,13 @@ verifyHello (protocol::TMHello const& h,
return boost::none; return boost::none;
} }
if (publicKeyType(*publicKey) != KeyType::secp256k1)
{
JLOG(journal.info()) <<
"Hello: Disconnect: Unsupported public key type.";
return boost::none;
}
if (*publicKey == app.nodeIdentity().first) if (*publicKey == app.nodeIdentity().first)
{ {
JLOG(journal.info()) << JLOG(journal.info()) <<

View File

@@ -70,7 +70,7 @@ public:
/** Create a public key. /** Create a public key.
Preconditions: Preconditions:
publicKeyType(Slice(data, size)) != boost::none publicKeyType(slice) != boost::none
*/ */
explicit explicit
PublicKey (Slice const& slice); PublicKey (Slice const& slice);

View File

@@ -102,8 +102,7 @@ inline
std::string std::string
toBase58 (Seed const& seed) toBase58 (Seed const& seed)
{ {
return base58EncodeToken( return base58EncodeToken(TokenType::FamilySeed, seed.data(), seed.size());
TOKEN_FAMILY_SEED, seed.data(), seed.size());
} }
} }

View File

@@ -29,18 +29,14 @@ namespace ripple {
std::string std::string
toBase58 (AccountID const& v) toBase58 (AccountID const& v)
{ {
return base58EncodeToken( return base58EncodeToken(TokenType::AccountID, v.data(), v.size());
TOKEN_ACCOUNT_ID,
v.data(), v.size());
} }
template<> template<>
boost::optional<AccountID> boost::optional<AccountID>
parseBase58 (std::string const& s) parseBase58 (std::string const& s)
{ {
auto const result = auto const result = decodeBase58Token(s, TokenType::AccountID);
decodeBase58Token(
s, TOKEN_ACCOUNT_ID);
if (result.empty()) if (result.empty())
return boost::none; return boost::none;
AccountID id; AccountID id;
@@ -54,9 +50,7 @@ parseBase58 (std::string const& s)
boost::optional<AccountID> boost::optional<AccountID>
deprecatedParseBitcoinAccountID (std::string const& s) deprecatedParseBitcoinAccountID (std::string const& s)
{ {
auto const result = auto const result = decodeBase58TokenBitcoin(s, TokenType::AccountID);
decodeBase58TokenBitcoin(
s, TOKEN_ACCOUNT_ID);
if (result.empty()) if (result.empty())
return boost::none; return boost::none;
AccountID id; AccountID id;

View File

@@ -37,22 +37,15 @@ operator<<(std::ostream& os, PublicKey const& pk)
return os; return os;
} }
using uint264 = boost::multiprecision::number<
boost::multiprecision::cpp_int_backend<
264, 264, boost::multiprecision::signed_magnitude,
boost::multiprecision::unchecked, void>>;
template<> template<>
boost::optional<PublicKey> boost::optional<PublicKey>
parseBase58 (TokenType type, std::string const& s) parseBase58 (TokenType type, std::string const& s)
{ {
auto const result = auto const result = decodeBase58Token(s, type);
decodeBase58Token(s, type); auto const pks = makeSlice(result);
if (result.empty()) if (!publicKeyType(pks))
return boost::none; return boost::none;
if (result.size() != 33) return PublicKey(pks);
return boost::none;
return PublicKey(makeSlice(result));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -81,8 +74,7 @@ sigPart (Slice& buf)
if ((buf[1] & 0x80) == 0) if ((buf[1] & 0x80) == 0)
return boost::none; return boost::none;
} }
boost::optional<Slice> number = boost::optional<Slice> number = Slice(buf.data(), len);
Slice(buf.data(), len);
buf += len; buf += len;
return number; return number;
} }
@@ -125,6 +117,11 @@ sliceToHex (Slice const& slice)
boost::optional<ECDSACanonicality> boost::optional<ECDSACanonicality>
ecdsaCanonicality (Slice const& sig) ecdsaCanonicality (Slice const& sig)
{ {
using uint264 = boost::multiprecision::number<
boost::multiprecision::cpp_int_backend<
264, 264, boost::multiprecision::signed_magnitude,
boost::multiprecision::unchecked, void>>;
static uint264 const G( static uint264 const G(
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
@@ -141,12 +138,13 @@ ecdsaCanonicality (Slice const& sig)
return boost::none; return boost::none;
uint264 R(sliceToHex(*r)); uint264 R(sliceToHex(*r));
uint264 S(sliceToHex(*s));
if (R >= G) if (R >= G)
return boost::none; return boost::none;
uint264 S(sliceToHex(*s));
if (S >= G) if (S >= G)
return boost::none; return boost::none;
// (R,S) and (R,G-S) are canonical, // (R,S) and (R,G-S) are canonical,
// but is fully canonical when S <= G-S // but is fully canonical when S <= G-S
auto const Sp = G - S; auto const Sp = G - S;
@@ -186,7 +184,7 @@ PublicKey::PublicKey (Slice const& slice)
if(! publicKeyType(slice)) if(! publicKeyType(slice))
LogicError("PublicKey::PublicKey invalid type"); LogicError("PublicKey::PublicKey invalid type");
size_ = slice.size(); size_ = slice.size();
std::memcpy(buf_, slice.data(), slice.size()); std::memcpy(buf_, slice.data(), size_);
} }
PublicKey::PublicKey (PublicKey const& other) PublicKey::PublicKey (PublicKey const& other)
@@ -196,8 +194,7 @@ PublicKey::PublicKey (PublicKey const& other)
}; };
PublicKey& PublicKey&
PublicKey::operator=( PublicKey::operator=(PublicKey const& other)
PublicKey const& other)
{ {
size_ = other.size_; size_ = other.size_;
std::memcpy(buf_, other.buf_, size_); std::memcpy(buf_, other.buf_, size_);
@@ -209,13 +206,15 @@ PublicKey::operator=(
boost::optional<KeyType> boost::optional<KeyType>
publicKeyType (Slice const& slice) publicKeyType (Slice const& slice)
{ {
if (slice.size() == 33 && if (slice.size() == 33)
slice[0] == 0xED) {
if (slice[0] == 0xED)
return KeyType::ed25519; return KeyType::ed25519;
if (slice.size() == 33 &&
(slice[0] == 0x02 || if (slice[0] == 0x02 || slice[0] == 0x03)
slice[0] == 0x03))
return KeyType::secp256k1; return KeyType::secp256k1;
}
return boost::none; return boost::none;
} }

View File

@@ -29,15 +29,23 @@ namespace ripple {
STValidation::STValidation (SerialIter& sit, bool checkSignature) STValidation::STValidation (SerialIter& sit, bool checkSignature)
: STObject (getFormat (), sit, sfValidation) : STObject (getFormat (), sit, sfValidation)
{ {
mNodeID = calcNodeID( auto const spk = getFieldVL(sfSigningPubKey);
PublicKey(makeSlice (getFieldVL (sfSigningPubKey))));
if (publicKeyType(makeSlice(spk)) != KeyType::secp256k1)
{
JLOG (debugLog().error())
<< "Invalid public key in validation" << getJson (0);
Throw<std::runtime_error> ("Invalid public key in validation");
}
mNodeID = calcNodeID(PublicKey(makeSlice(spk)));
assert (mNodeID.isNonZero ()); assert (mNodeID.isNonZero ());
if (checkSignature && !isValid ()) if (checkSignature && !isValid ())
{ {
JLOG (debugLog().error()) JLOG (debugLog().error())
<< "Invalid validation" << getJson (0); << "Invalid signature in validation" << getJson (0);
Throw<std::runtime_error> ("Invalid validation"); Throw<std::runtime_error> ("Invalid signature in validation");
} }
} }
@@ -49,11 +57,15 @@ STValidation::STValidation (
: STObject (getFormat (), sfValidation) : STObject (getFormat (), sfValidation)
, mSeen (signTime) , mSeen (signTime)
{ {
// This is our own public key and it should always be valid.
if (!publicKeyType(publicKey))
LogicError ("Invalid validation public key");
// Does not sign // Does not sign
setFieldH256 (sfLedgerHash, ledgerHash); setFieldH256 (sfLedgerHash, ledgerHash);
setFieldU32 (sfSigningTime, signTime.time_since_epoch().count()); setFieldU32 (sfSigningTime, signTime.time_since_epoch().count());
setFieldVL (sfSigningPubKey, publicKey.slice()); setFieldVL (sfSigningPubKey, publicKey.slice());
mNodeID = calcNodeID(publicKey); mNodeID = calcNodeID(publicKey);
assert (mNodeID.isNonZero ()); assert (mNodeID.isNonZero ());
@@ -101,6 +113,9 @@ bool STValidation::isValid (uint256 const& signingHash) const
{ {
try try
{ {
if (publicKeyType(getSignerPublic()) != KeyType::secp256k1)
return false;
return verifyDigest (getSignerPublic(), return verifyDigest (getSignerPublic(),
signingHash, signingHash,
makeSlice(getFieldVL (sfSignature)), makeSlice(getFieldVL (sfSignature)),

View File

@@ -87,10 +87,8 @@ public:
std::memcpy(ui.data(), seed.data(), seed.size()); std::memcpy(ui.data(), seed.data(), seed.size());
auto gsk = generatePrivateDeterministicKey(gen_, ui, ordinal); auto gsk = generatePrivateDeterministicKey(gen_, ui, ordinal);
auto gpk = generatePublicDeterministicKey(gen_, ordinal); auto gpk = generatePublicDeterministicKey(gen_, ordinal);
SecretKey const sk(Slice SecretKey const sk(Slice{ gsk.data(), gsk.size() });
{ gsk.data(), gsk.size() }); PublicKey const pk(Slice{ gpk.data(), gpk.size() });
PublicKey const pk(Slice
{ gpk.data(), gpk.size() });
beast::secure_erase(ui.data(), ui.size()); beast::secure_erase(ui.data(), ui.size());
beast::secure_erase(gsk.data(), gsk.size()); beast::secure_erase(gsk.data(), gsk.size());
return {pk, sk}; return {pk, sk};
@@ -243,7 +241,7 @@ derivePublicKey (KeyType type, SecretKey const& sk)
LogicError("derivePublicKey: secp256k1_ec_pubkey_create failed"); LogicError("derivePublicKey: secp256k1_ec_pubkey_create failed");
unsigned char pubkey[33]; unsigned char pubkey[33];
size_t len = sizeof(pubkey); std::size_t len = sizeof(pubkey);
if(secp256k1_ec_pubkey_serialize( if(secp256k1_ec_pubkey_serialize(
secp256k1Context(), secp256k1Context(),
pubkey, pubkey,
@@ -252,8 +250,7 @@ derivePublicKey (KeyType type, SecretKey const& sk)
SECP256K1_EC_COMPRESSED) != 1) SECP256K1_EC_COMPRESSED) != 1)
LogicError("derivePublicKey: secp256k1_ec_pubkey_serialize failed"); LogicError("derivePublicKey: secp256k1_ec_pubkey_serialize failed");
return PublicKey{Slice{pubkey, return PublicKey{Slice{ pubkey, len }};
static_cast<std::size_t>(len)}};
} }
case KeyType::ed25519: case KeyType::ed25519:
{ {

View File

@@ -85,8 +85,7 @@ template <>
boost::optional<Seed> boost::optional<Seed>
parseBase58 (std::string const& s) parseBase58 (std::string const& s)
{ {
auto const result = decodeBase58Token( auto const result = decodeBase58Token(s, TokenType::FamilySeed);
s, TokenType::TOKEN_FAMILY_SEED);
if (result.empty()) if (result.empty())
return boost::none; return boost::none;
if (result.size() != 16) if (result.size() != 16)
@@ -101,10 +100,10 @@ parseGenericSeed (std::string const& str)
return boost::none; return boost::none;
if (parseBase58<AccountID>(str) || if (parseBase58<AccountID>(str) ||
parseBase58<PublicKey>(TokenType::TOKEN_NODE_PUBLIC, str) || parseBase58<PublicKey>(TokenType::NodePublic, str) ||
parseBase58<PublicKey>(TokenType::TOKEN_ACCOUNT_PUBLIC, str) || parseBase58<PublicKey>(TokenType::AccountPublic, str) ||
parseBase58<SecretKey>(TokenType::TOKEN_NODE_PRIVATE, str) || parseBase58<SecretKey>(TokenType::NodePrivate, str) ||
parseBase58<SecretKey>(TokenType::TOKEN_ACCOUNT_SECRET, str)) parseBase58<SecretKey>(TokenType::AccountSecret, str))
{ {
return boost::none; return boost::none;
} }

View File

@@ -519,10 +519,16 @@ T SerialIter::getRawHelper (int size)
Throw<std::runtime_error> ( Throw<std::runtime_error> (
"invalid SerialIter getRaw"); "invalid SerialIter getRaw");
T result (size); T result (size);
memcpy(result.data (), p_, size); if (size != 0)
{
// It's normally safe to call memcpy with size set to 0 (see the
// C99 standard 7.21.1/2). However, here this could mean that
// result.data would be null, which would trigger undefined behavior.
std::memcpy(result.data(), p_, size);
p_ += size; p_ += size;
used_ += size; used_ += size;
remain_ -= size; remain_ -= size;
}
return result; return result;
} }

View File

@@ -20,6 +20,7 @@
#include <BeastConfig.h> #include <BeastConfig.h>
#include <ripple/protocol/tokens.h> #include <ripple/protocol/tokens.h>
#include <ripple/protocol/digest.h> #include <ripple/protocol/digest.h>
#include <boost/container/small_vector.hpp>
#include <cassert> #include <cassert>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
@@ -102,11 +103,12 @@ static
std::string std::string
encodeBase58( encodeBase58(
void const* message, std::size_t size, void const* message, std::size_t size,
void *temp, char const* const alphabet) void *temp, std::size_t temp_size,
char const* const alphabet)
{ {
auto pbegin = reinterpret_cast< auto pbegin = reinterpret_cast<unsigned char const*>(message);
unsigned char const*>(message);
auto const pend = pbegin + size; auto const pend = pbegin + size;
// Skip & count leading zeroes. // Skip & count leading zeroes.
int zeroes = 0; int zeroes = 0;
while (pbegin != pend && *pbegin == 0) while (pbegin != pend && *pbegin == 0)
@@ -114,12 +116,12 @@ encodeBase58(
pbegin++; pbegin++;
zeroes++; zeroes++;
} }
auto const b58begin = reinterpret_cast<
unsigned char*>(temp); auto const b58begin = reinterpret_cast<unsigned char*>(temp);
// log(256) / log(58), rounded up. auto const b58end = b58begin + temp_size;
auto const b58end = b58begin +
size * (138 / 100 + 1);
std::fill(b58begin, b58end, 0); std::fill(b58begin, b58end, 0);
while (pbegin != pend) while (pbegin != pend)
{ {
int carry = *pbegin; int carry = *pbegin;
@@ -133,10 +135,12 @@ encodeBase58(
assert(carry == 0); assert(carry == 0);
pbegin++; pbegin++;
} }
// Skip leading zeroes in base58 result. // Skip leading zeroes in base58 result.
auto iter = b58begin; auto iter = b58begin;
while (iter != b58end && *iter == 0) while (iter != b58end && *iter == 0)
++iter; ++iter;
// Translate the result into a string. // Translate the result into a string.
std::string str; std::string str;
str.reserve(zeroes + (b58end - iter)); str.reserve(zeroes + (b58end - iter));
@@ -148,48 +152,44 @@ encodeBase58(
static static
std::string std::string
encodeToken (std::uint8_t type, encodeToken (TokenType type,
void const* token, std::size_t size, bool btc) void const* token, std::size_t size, char const* const alphabet)
{ {
char buf[1024]; // expanded token includes type + 4 byte checksum
// expanded token includes type + checksum
auto const expanded = 1 + size + 4; auto const expanded = 1 + size + 4;
// add scratch, log(256) / log(58), rounded up.
auto const needed = expanded + // We need expanded + expanded * (log(256) / log(58)) which is
size * (138 / 100 + 1); // bounded by expanded + expanded * (138 / 100 + 1) which works
std::unique_ptr< // out to expanded * 3:
char[]> pbuf; auto const bufsize = expanded * 3;
char* temp;
if (needed > sizeof(buf)) boost::container::small_vector<std::uint8_t, 1024> buf (bufsize);
{
pbuf.reset(new char[needed]);
temp = pbuf.get();
}
else
{
temp = buf;
}
// Lay the data out as // Lay the data out as
// <type><token><checksum> // <type><token><checksum>
temp[0] = type; buf[0] = static_cast<std::underlying_type_t <TokenType>>(type);
std::memcpy(temp + 1, token, size); if (size)
checksum(temp + 1 + size, temp, 1 + size); std::memcpy(buf.data() + 1, token, size);
return encodeBase58(temp, expanded, checksum(buf.data() + 1 + size, buf.data(), 1 + size);
temp + expanded, btc ? bitcoinAlphabet : rippleAlphabet);
return encodeBase58(
buf.data(), expanded,
buf.data() + expanded, bufsize - expanded,
alphabet);
} }
std::string std::string
base58EncodeToken (std::uint8_t type, base58EncodeToken (TokenType type,
void const* token, std::size_t size) void const* token, std::size_t size)
{ {
return encodeToken(type, token, size, false); return encodeToken(type, token, size, rippleAlphabet);
} }
std::string std::string
base58EncodeTokenBitcoin (std::uint8_t type, base58EncodeTokenBitcoin (TokenType type,
void const* token, std::size_t size) void const* token, std::size_t size)
{ {
return encodeToken(type, token, size, true); return encodeToken(type, token, size, bitcoinAlphabet);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -258,28 +258,26 @@ template <class InverseArray>
static static
std::string std::string
decodeBase58Token (std::string const& s, decodeBase58Token (std::string const& s,
int type, InverseArray const& inv) TokenType type, InverseArray const& inv)
{ {
auto result = decodeBase58(s, inv); auto ret = decodeBase58(s, inv);
if (result.empty())
return result;
// Reject zero length tokens // Reject zero length tokens
if (result.size() < 6) if (ret.size() < 6)
return {}; return {};
if (result[0] != type)
// The type must match.
if (type != static_cast<TokenType>(ret[0]))
return {}; return {};
// And the checksum must as well.
std::array<char, 4> guard; std::array<char, 4> guard;
checksum(guard.data(), checksum(guard.data(), ret.data(), ret.size() - guard.size());
result.data(), result.size() - 4); if (!std::equal (guard.rbegin(), guard.rend(), ret.rbegin()))
if (std::memcmp(guard.data(),
result.data() +
result.size() - 4, 4) != 0)
return {}; return {};
result.resize(result.size() - 4);
// Erase the type byte // Skip the leading type byte and the trailing checksum.
// VFALCO This might cause problems later return ret.substr(1, ret.size() - 1 - guard.size());
result.erase(result.begin());
return result;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -315,18 +313,16 @@ static InverseAlphabet bitcoinInverse(bitcoinAlphabet);
std::string std::string
decodeBase58Token( decodeBase58Token(
std::string const& s, int type) std::string const& s, TokenType type)
{ {
return decodeBase58Token( return decodeBase58Token(s, type, rippleInverse);
s, type, rippleInverse);
} }
std::string std::string
decodeBase58TokenBitcoin( decodeBase58TokenBitcoin(
std::string const& s, int type) std::string const& s, TokenType type)
{ {
return decodeBase58Token( return decodeBase58Token(s, type, bitcoinInverse);
s, type, bitcoinInverse);
} }
} // ripple } // ripple

View File

@@ -26,16 +26,16 @@
namespace ripple { namespace ripple {
enum TokenType enum class TokenType : std::uint8_t
{ {
TOKEN_NONE = 1, None = 1, // unused
TOKEN_NODE_PUBLIC = 28, NodePublic = 28,
TOKEN_NODE_PRIVATE = 32, NodePrivate = 32,
TOKEN_ACCOUNT_ID = 0, AccountID = 0,
TOKEN_ACCOUNT_PUBLIC = 35, AccountPublic = 35,
TOKEN_ACCOUNT_SECRET = 34, AccountSecret = 34,
TOKEN_FAMILY_GENERATOR = 41, FamilyGenerator = 41, // unused
TOKEN_FAMILY_SEED = 33 FamilySeed = 33
}; };
template <class T> template <class T>
@@ -75,8 +75,7 @@ parseHexOrBase58 (std::string const& s);
@param size the size of the token buffer in bytes @param size the size of the token buffer in bytes
*/ */
std::string std::string
base58EncodeToken (std::uint8_t type, base58EncodeToken (TokenType type, void const* token, std::size_t size);
void const* token, std::size_t size);
/* Base-58 encode a Bitcoin Token /* Base-58 encode a Bitcoin Token
* *
@@ -87,8 +86,7 @@ base58EncodeToken (std::uint8_t type,
* *
*/ */
std::string std::string
base58EncodeTokenBitcoin (std::uint8_t type, base58EncodeTokenBitcoin (TokenType type, void const* token, std::size_t size);
void const* token, std::size_t size);
/** Decode a Base58 token /** Decode a Base58 token
@@ -96,8 +94,7 @@ base58EncodeTokenBitcoin (std::uint8_t type,
empty string is returned. empty string is returned.
*/ */
std::string std::string
decodeBase58Token( decodeBase58Token(std::string const& s, TokenType type);
std::string const& s, int type);
/** Decode a Base58 token using Bitcoin alphabet /** Decode a Base58 token using Bitcoin alphabet
@@ -110,8 +107,7 @@ decodeBase58Token(
may be returned. may be returned.
*/ */
std::string std::string
decodeBase58TokenBitcoin( decodeBase58TokenBitcoin(std::string const& s, TokenType type);
std::string const& s, int type);
} // ripple } // ripple

View File

@@ -43,7 +43,7 @@ void addChannel (Json::Value& jsonLines, SLE const& line)
if (publicKeyType(line[sfPublicKey])) if (publicKeyType(line[sfPublicKey]))
{ {
PublicKey const pk (line[sfPublicKey]); PublicKey const pk (line[sfPublicKey]);
jDst[jss::public_key] = toBase58 (TokenType::TOKEN_ACCOUNT_PUBLIC, pk); jDst[jss::public_key] = toBase58 (TokenType::AccountPublic, pk);
jDst[jss::public_key_hex] = strHex (pk); jDst[jss::public_key_hex] = strHex (pk);
} }
jDst[jss::settle_delay] = line[sfSettleDelay]; jDst[jss::settle_delay] = line[sfSettleDelay];

View File

@@ -93,7 +93,7 @@ Json::Value doGatewayBalances (RPC::Context& context)
if (j.isString()) if (j.isString())
{ {
auto const pk = parseBase58<PublicKey>( auto const pk = parseBase58<PublicKey>(
TokenType::TOKEN_ACCOUNT_PUBLIC, TokenType::AccountPublic,
j.asString ()); j.asString ());
if (pk) if (pk)
{ {

View File

@@ -126,7 +126,7 @@ Json::Value doChannelVerify (RPC::Context& context)
boost::optional<PublicKey> pk; boost::optional<PublicKey> pk;
{ {
std::string const strPk = params[jss::public_key].asString(); std::string const strPk = params[jss::public_key].asString();
pk = parseBase58<PublicKey>(TokenType::TOKEN_ACCOUNT_PUBLIC, strPk); pk = parseBase58<PublicKey>(TokenType::AccountPublic, strPk);
if (!pk) if (!pk)
{ {

View File

@@ -52,7 +52,7 @@ Json::Value doPeers (RPC::Context& context)
Json::Value& json = cluster[ Json::Value& json = cluster[
toBase58( toBase58(
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
node.identity())]; node.identity())];
if (!node.name().empty()) if (!node.name().empty())

View File

@@ -39,7 +39,7 @@ Json::Value doUnlList (RPC::Context& context)
Json::Value node (Json::objectValue); Json::Value node (Json::objectValue);
node[jss::pubkey_validator] = toBase58( node[jss::pubkey_validator] = toBase58(
TokenType::TOKEN_NODE_PUBLIC, publicKey); TokenType::NodePublic, publicKey);
node[jss::trusted] = trusted; node[jss::trusted] = trusted;
unl.append (node); unl.append (node);

View File

@@ -55,11 +55,11 @@ Json::Value doValidationCreate (RPC::Context& context)
auto const private_key = generateSecretKey (KeyType::secp256k1, *seed); auto const private_key = generateSecretKey (KeyType::secp256k1, *seed);
obj[jss::validation_public_key] = toBase58 ( obj[jss::validation_public_key] = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
derivePublicKey (KeyType::secp256k1, private_key)); derivePublicKey (KeyType::secp256k1, private_key));
obj[jss::validation_private_key] = toBase58 ( obj[jss::validation_private_key] = toBase58 (
TokenType::TOKEN_NODE_PRIVATE, private_key); TokenType::NodePrivate, private_key);
obj[jss::validation_seed] = toBase58 (*seed); obj[jss::validation_seed] = toBase58 (*seed);
obj[jss::validation_key] = seedAs1751 (*seed); obj[jss::validation_key] = seedAs1751 (*seed);

View File

@@ -116,7 +116,7 @@ Json::Value walletPropose (Json::Value const& params)
obj[jss::master_seed_hex] = seedHex; obj[jss::master_seed_hex] = seedHex;
obj[jss::master_key] = seed1751; obj[jss::master_key] = seed1751;
obj[jss::account_id] = toBase58(calcAccountID(publicKey)); obj[jss::account_id] = toBase58(calcAccountID(publicKey));
obj[jss::public_key] = toBase58(TOKEN_ACCOUNT_PUBLIC, publicKey); obj[jss::public_key] = toBase58(TokenType::AccountPublic, publicKey);
obj[jss::key_type] = to_string (keyType); obj[jss::key_type] = to_string (keyType);
obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size()); obj[jss::public_key_hex] = strHex (publicKey.data(), publicKey.size());

View File

@@ -36,7 +36,7 @@ accountFromStringStrict(std::string const& account)
boost::optional <AccountID> result; boost::optional <AccountID> result;
auto const publicKey = parseBase58<PublicKey> ( auto const publicKey = parseBase58<PublicKey> (
TokenType::TOKEN_ACCOUNT_PUBLIC, TokenType::AccountPublic,
account); account);
if (publicKey) if (publicKey)

View File

@@ -251,7 +251,7 @@ public:
std::string cfgManifest; std::string cfgManifest;
for (auto const& man : inManifests) for (auto const& man : inManifests)
s1.push_back (toBase58( s1.push_back (toBase58(
TokenType::TOKEN_NODE_PUBLIC, man->masterKey)); TokenType::NodePublic, man->masterKey));
unl->load (emptyLocalKey, s1, keys); unl->load (emptyLocalKey, s1, keys);
m.save (dbCon, "ValidatorManifests", m.save (dbCon, "ValidatorManifests",
@@ -428,7 +428,7 @@ public:
{ {
auto const valSecret = parseBase58<SecretKey>( auto const valSecret = parseBase58<SecretKey>(
TokenType::TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
"paQmjZ37pKKPMrgadBLsuf9ab7Y7EUNzh27LQrZqoexpAs31nJi"); "paQmjZ37pKKPMrgadBLsuf9ab7Y7EUNzh27LQrZqoexpAs31nJi");
// Format token string to test trim() // Format token string to test trim()

View File

@@ -1065,8 +1065,21 @@ struct PayChan_test : public beast::unit_test::suite
jv.removeMember("PublicKey"); jv.removeMember("PublicKey");
env (jv, ter(temMALFORMED)); env (jv, ter(temMALFORMED));
jv["PublicKey"] = pkHex; {
env (jv); auto const txn = R"*(
{
"channel_id":"5DB01B7FFED6B67E6B0414DED11E051D2EE2B7619CE0EAA6286D67A3A4D5BDB3",
"signature":
"304402204EF0AFB78AC23ED1C472E74F4299C0C21F1B21D07EFC0A3838A420F76D783A400220154FB11B6F54320666E4C36CA7F686C16A3A0456800BBC43746F34AF50290064",
"public_key":
"aKijDDiC2q2gXjMpM7i4BUS6cmixgsEe18e7CjsUxwihKfuoFgS5",
"amount": "1000000"
}
)*";
auto const r = env.rpc("json", "channel_verify", txn);
BEAST_EXPECT(r["result"]["error"] == "publicMalformed");
}
} }
void void

View File

@@ -82,7 +82,7 @@ public:
// Keys when using [validation_token] // Keys when using [validation_token]
auto const tokenSecretKey = *parseBase58<SecretKey>( auto const tokenSecretKey = *parseBase58<SecretKey>(
TokenType::TOKEN_NODE_PRIVATE, tokenSecretStr); TokenType::NodePrivate, tokenSecretStr);
auto const tokenPublicKey = auto const tokenPublicKey =
derivePublicKey(KeyType::secp256k1, tokenSecretKey); derivePublicKey(KeyType::secp256k1, tokenSecretKey);

View File

@@ -172,7 +172,7 @@ private:
PublicKey const &publicKey, PublicKey const &publicKey,
char const* comment = nullptr) char const* comment = nullptr)
{ {
auto ret = toBase58 (TokenType::TOKEN_NODE_PUBLIC, publicKey); auto ret = toBase58 (TokenType::NodePublic, publicKey);
if (comment) if (comment)
ret += comment; ret += comment;
@@ -271,7 +271,7 @@ private:
manifests, manifests, env.timeKeeper(), journal); manifests, manifests, env.timeKeeper(), journal);
auto const localSigningPublic = parseBase58<PublicKey> ( auto const localSigningPublic = parseBase58<PublicKey> (
TokenType::TOKEN_NODE_PUBLIC, cfgKeys.front()); TokenType::NodePublic, cfgKeys.front());
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
*localSigningPublic, cfgKeys, emptyCfgPublishers)); *localSigningPublic, cfgKeys, emptyCfgPublishers));
@@ -330,7 +330,7 @@ private:
badPublishers.clear(); badPublishers.clear();
for (auto const& key : keys) for (auto const& key : keys)
badPublishers.push_back ( badPublishers.push_back (
toBase58 (TokenType::TOKEN_NODE_PUBLIC, key)); toBase58 (TokenType::NodePublic, key));
BEAST_EXPECT(! trustedKeys->load ( BEAST_EXPECT(! trustedKeys->load (
emptyLocalKey, emptyCfgKeys, badPublishers)); emptyLocalKey, emptyCfgKeys, badPublishers));
@@ -533,7 +533,7 @@ private:
{ {
auto const valKey = randomNode(); auto const valKey = randomNode();
cfgKeys.push_back (toBase58( cfgKeys.push_back (toBase58(
TokenType::TOKEN_NODE_PUBLIC, valKey)); TokenType::NodePublic, valKey));
if (cfgKeys.size () <= n - 5) if (cfgKeys.size () <= n - 5)
activeValidators.emplace (valKey); activeValidators.emplace (valKey);
} }
@@ -550,7 +550,7 @@ private:
for (auto const& val : cfgKeys) for (auto const& val : cfgKeys)
{ {
if (auto const valKey = parseBase58<PublicKey>( if (auto const valKey = parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, val)) TokenType::NodePublic, val))
{ {
BEAST_EXPECT(trustedKeys->listed (*valKey)); BEAST_EXPECT(trustedKeys->listed (*valKey));
if (i++ < activeValidators.size ()) if (i++ < activeValidators.size ())
@@ -567,7 +567,7 @@ private:
hash_set<PublicKey> activeValidators; hash_set<PublicKey> activeValidators;
for (auto const valKey : cfgKeys) for (auto const valKey : cfgKeys)
activeValidators.emplace (*parseBase58<PublicKey>( activeValidators.emplace (*parseBase58<PublicKey>(
TokenType::TOKEN_NODE_PUBLIC, valKey)); TokenType::NodePublic, valKey));
trustedKeys->onConsensusStart (activeValidators); trustedKeys->onConsensusStart (activeValidators);
BEAST_EXPECT(trustedKeys->quorum () == cfgKeys.size() * 4/5); BEAST_EXPECT(trustedKeys->quorum () == cfgKeys.size() * 4/5);
} }
@@ -579,7 +579,7 @@ private:
derivePublicKey(KeyType::ed25519, masterPrivate); derivePublicKey(KeyType::ed25519, masterPrivate);
std::vector<std::string> cfgKeys ({ std::vector<std::string> cfgKeys ({
toBase58 (TokenType::TOKEN_NODE_PUBLIC, masterPublic)}); toBase58 (TokenType::NodePublic, masterPublic)});
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
emptyLocalKey, cfgKeys, cfgPublishers)); emptyLocalKey, cfgKeys, cfgPublishers));
@@ -682,8 +682,8 @@ private:
std::vector<PublicKey> keys ({ randomNode (), randomNode () }); std::vector<PublicKey> keys ({ randomNode (), randomNode () });
hash_set<PublicKey> activeValidators; hash_set<PublicKey> activeValidators;
std::vector<std::string> cfgKeys ({ std::vector<std::string> cfgKeys ({
toBase58 (TokenType::TOKEN_NODE_PUBLIC, keys[0]), toBase58 (TokenType::NodePublic, keys[0]),
toBase58 (TokenType::TOKEN_NODE_PUBLIC, keys[1])}); toBase58 (TokenType::NodePublic, keys[1])});
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
emptyLocalKey, cfgKeys, cfgPublishers)); emptyLocalKey, cfgKeys, cfgPublishers));
@@ -703,7 +703,7 @@ private:
auto const node = randomNode (); auto const node = randomNode ();
std::vector<std::string> cfgKeys ({ std::vector<std::string> cfgKeys ({
toBase58 (TokenType::TOKEN_NODE_PUBLIC, node)}); toBase58 (TokenType::NodePublic, node)});
hash_set<PublicKey> activeValidators; hash_set<PublicKey> activeValidators;
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
@@ -724,8 +724,8 @@ private:
std::vector<PublicKey> keys ({ randomNode (), randomNode () }); std::vector<PublicKey> keys ({ randomNode (), randomNode () });
hash_set<PublicKey> activeValidators ({ keys[0] }); hash_set<PublicKey> activeValidators ({ keys[0] });
std::vector<std::string> cfgKeys ({ std::vector<std::string> cfgKeys ({
toBase58 (TokenType::TOKEN_NODE_PUBLIC, keys[0]), toBase58 (TokenType::NodePublic, keys[0]),
toBase58 (TokenType::TOKEN_NODE_PUBLIC, keys[1])}); toBase58 (TokenType::NodePublic, keys[1])});
auto const localKey = randomNode (); auto const localKey = randomNode ();
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
@@ -827,7 +827,7 @@ private:
{ {
auto const valKey = randomNode(); auto const valKey = randomNode();
cfgKeys.push_back (toBase58( cfgKeys.push_back (toBase58(
TokenType::TOKEN_NODE_PUBLIC, valKey)); TokenType::NodePublic, valKey));
activeValidators.emplace (valKey); activeValidators.emplace (valKey);
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
@@ -850,14 +850,14 @@ private:
hash_set<PublicKey> activeValidators; hash_set<PublicKey> activeValidators;
std::vector<std::string> cfgKeys { std::vector<std::string> cfgKeys {
toBase58(TokenType::TOKEN_NODE_PUBLIC, localKey)}; toBase58(TokenType::NodePublic, localKey)};
cfgKeys.reserve(9); cfgKeys.reserve(9);
while (cfgKeys.size() < cfgKeys.capacity()) while (cfgKeys.size() < cfgKeys.capacity())
{ {
auto const valKey = randomNode(); auto const valKey = randomNode();
cfgKeys.push_back (toBase58( cfgKeys.push_back (toBase58(
TokenType::TOKEN_NODE_PUBLIC, valKey)); TokenType::NodePublic, valKey));
activeValidators.emplace (valKey); activeValidators.emplace (valKey);
BEAST_EXPECT(trustedKeys->load ( BEAST_EXPECT(trustedKeys->load (
@@ -950,7 +950,7 @@ private:
jtx::Env env(*this); jtx::Env env(*this);
auto toStr = [](PublicKey const& publicKey) { auto toStr = [](PublicKey const& publicKey) {
return toBase58(TokenType::TOKEN_NODE_PUBLIC, publicKey); return toBase58(TokenType::NodePublic, publicKey);
}; };
// Config listed keys // Config listed keys

View File

@@ -133,7 +133,7 @@ public:
auto const node = randomNode (); auto const node = randomNode ();
auto const name = toBase58( auto const name = toBase58(
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
node); node);
std::uint32_t load = 0; std::uint32_t load = 0;
NetClock::time_point tick = {}; NetClock::time_point tick = {};
@@ -202,7 +202,7 @@ public:
char const* comment = nullptr) char const* comment = nullptr)
{ {
auto ret = toBase58( auto ret = toBase58(
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
publicKey); publicKey);
if (comment) if (comment)

View File

@@ -231,12 +231,12 @@ public:
void testBase58 (KeyType keyType) void testBase58 (KeyType keyType)
{ {
// Try converting short, long and malformed data // Try converting short, long and malformed data
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, "")); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, ""));
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, " ")); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, " "));
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, "!ty89234gh45")); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, "!ty89234gh45"));
auto const good = toBase58 ( auto const good = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
derivePublicKey ( derivePublicKey (
keyType, keyType,
randomSecretKey())); randomSecretKey()));
@@ -251,7 +251,7 @@ public:
while (!s.empty()) while (!s.empty())
{ {
s.erase (r(s) % s.size(), 1); s.erase (r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, s)); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
} }
} }
@@ -260,7 +260,7 @@ public:
{ {
auto s = good; auto s = good;
s.resize (s.size() + i, s[i % s.size()]); s.resize (s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, s)); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
} }
// Strings with invalid Base58 characters // Strings with invalid Base58 characters
@@ -270,7 +270,7 @@ public:
{ {
auto s = good; auto s = good;
s[i % s.size()] = c; s[i % s.size()] = c;
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, s)); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
} }
} }
@@ -281,7 +281,7 @@ public:
for (auto c : std::string("apsrJqtv7")) for (auto c : std::string("apsrJqtv7"))
{ {
s[0] = c; s[0] = c;
BEAST_EXPECT(!parseBase58<PublicKey> (TOKEN_NODE_PUBLIC, s)); BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
} }
} }
@@ -294,12 +294,12 @@ public:
for (std::size_t i = 0; i != keys.size(); ++i) for (std::size_t i = 0; i != keys.size(); ++i)
{ {
auto const si = toBase58 ( auto const si = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
keys[i]); keys[i]);
BEAST_EXPECT(!si.empty()); BEAST_EXPECT(!si.empty());
auto const ski = parseBase58<PublicKey> ( auto const ski = parseBase58<PublicKey> (
TOKEN_NODE_PUBLIC, si); TokenType::NodePublic, si);
BEAST_EXPECT(ski && (keys[i] == *ski)); BEAST_EXPECT(ski && (keys[i] == *ski));
for (std::size_t j = i; j != keys.size(); ++j) for (std::size_t j = i; j != keys.size(); ++j)
@@ -307,13 +307,13 @@ public:
BEAST_EXPECT((keys[i] == keys[j]) == (i == j)); BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
auto const sj = toBase58 ( auto const sj = toBase58 (
TokenType::TOKEN_NODE_PUBLIC, TokenType::NodePublic,
keys[j]); keys[j]);
BEAST_EXPECT((si == sj) == (i == j)); BEAST_EXPECT((si == sj) == (i == j));
auto const skj = parseBase58<PublicKey> ( auto const skj = parseBase58<PublicKey> (
TOKEN_NODE_PUBLIC, sj); TokenType::NodePublic, sj);
BEAST_EXPECT(skj && (keys[j] == *skj)); BEAST_EXPECT(skj && (keys[j] == *skj));
BEAST_EXPECT((*ski == *skj) == (i == j)); BEAST_EXPECT((*ski == *skj) == (i == j));
@@ -333,7 +333,7 @@ public:
generateSeed ("masterpassphrase"))); generateSeed ("masterpassphrase")));
auto const pk2 = parseBase58<PublicKey> ( auto const pk2 = parseBase58<PublicKey> (
TOKEN_NODE_PUBLIC, TokenType::NodePublic,
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9"); "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
BEAST_EXPECT(pk2); BEAST_EXPECT(pk2);
@@ -352,7 +352,7 @@ public:
generateSeed ("masterpassphrase"))); generateSeed ("masterpassphrase")));
auto const pk2 = parseBase58<PublicKey> ( auto const pk2 = parseBase58<PublicKey> (
TOKEN_NODE_PUBLIC, TokenType::NodePublic,
"nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf"); "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
BEAST_EXPECT(pk2); BEAST_EXPECT(pk2);

View File

@@ -0,0 +1,111 @@
//------------------------------------------------------------------------------
/*
This file is part of rippled: https://github.com/ripple/rippled
Copyright (c) 2012, 2013 Ripple Labs Inc.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/protocol/JsonFields.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/st.h>
#include <ripple/json/json_reader.h>
#include <ripple/json/to_string.h>
#include <ripple/beast/unit_test.h>
#include <test/jtx.h>
#include <memory>
#include <type_traits>
namespace ripple {
class STValidation_test : public beast::unit_test::suite
{
public:
void testDeserialization ()
{
testcase ("Deserialization");
constexpr unsigned char payload1[] =
{ // specifies an Ed25519 public key
0x72, 0x00, 0x73, 0x21, 0xed, 0x78, 0x00, 0xe6, 0x73, 0x00, 0x72, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x88, 0x00, 0xe6, 0x73, 0x38, 0x00, 0x00, 0x8a, 0x00, 0x88, 0x4e, 0x31, 0x30, 0x5f, 0x5f, 0x63,
0x78, 0x78, 0x61, 0x62, 0x69, 0x76, 0x31, 0x30, 0x37, 0x5f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73,
0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x00, 0xe6, 0x88, 0x54, 0x72,
0x75, 0x73, 0x74, 0x53, 0x65, 0x74, 0x65, 0x61, 0x74, 0x65, 0x88, 0x00, 0xe6, 0x88, 0x00, 0xe6,
0x73, 0x00, 0x72, 0x00, 0x8a, 0x00, 0x88, 0x00, 0xe6
};
constexpr unsigned char payload2[] =
{
0x73, 0x21, 0xed, 0xff, 0x03, 0x1c, 0xbe, 0x65, 0x22, 0x61, 0x9c, 0x5e, 0x13, 0x12, 0x00, 0x3b,
0x43, 0x00, 0x00, 0x00, 0xf7, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x13, 0x13, 0x13,
0x3a, 0x27, 0xff
};
constexpr unsigned char payload3[] =
{ // Has no public key at all
0x72, 0x00, 0x76, 0x31, 0x30, 0x37, 0x5f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x74, 0x79,
0x70, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x45, 0x00, 0xe6, 0x88, 0x54, 0x72, 0x75, 0x73, 0x74,
0x53, 0x65, 0x74, 0x65, 0x61, 0x74, 0x65, 0x88, 0x00, 0xe6, 0x88, 0x00, 0xe6, 0x73, 0x00, 0x72,
0x00, 0x8a, 0x00, 0x88, 0x00, 0xe6
};
try
{
SerialIter sit{payload1, sizeof(payload1)};
auto stx = std::make_shared<ripple::STValidation>(sit);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
}
try
{
SerialIter sit{payload2, sizeof(payload2)};
auto stx = std::make_shared<ripple::STValidation>(sit);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
}
try
{
SerialIter sit{payload3, sizeof(payload3)};
auto stx = std::make_shared<ripple::STValidation>(sit);
fail("An exception should have been thrown");
}
catch (std::exception const& e)
{
log << e.what() << "\n";
BEAST_EXPECT(strcmp(e.what(), "Invalid public key in validation") == 0);
}
}
void
run()
{
testDeserialization();
}
};
BEAST_DEFINE_TESTSUITE(STValidation,protocol,ripple);
} // ripple

View File

@@ -320,7 +320,7 @@ public:
generateSeed ("masterpassphrase")); generateSeed ("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> ( auto const sk2 = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
"pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe"); "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe");
BEAST_EXPECT(sk2); BEAST_EXPECT(sk2);
@@ -333,7 +333,7 @@ public:
generateSeed ("masterpassphrase")); generateSeed ("masterpassphrase"));
auto const sk2 = parseBase58<SecretKey> ( auto const sk2 = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
"paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36"); "paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36");
BEAST_EXPECT(sk2); BEAST_EXPECT(sk2);
@@ -341,12 +341,12 @@ public:
} }
// Try converting short, long and malformed data // Try converting short, long and malformed data
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, "")); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, ""));
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, " ")); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, " "));
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, "!35gty9mhju8nfjl")); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, "!35gty9mhju8nfjl"));
auto const good = toBase58 ( auto const good = toBase58 (
TokenType::TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
randomSecretKey()); randomSecretKey());
// Short (non-empty) strings // Short (non-empty) strings
@@ -359,7 +359,7 @@ public:
while (!s.empty()) while (!s.empty())
{ {
s.erase (r(s) % s.size(), 1); s.erase (r(s) % s.size(), 1);
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s)); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
} }
} }
@@ -368,7 +368,7 @@ public:
{ {
auto s = good; auto s = good;
s.resize (s.size() + i, s[i % s.size()]); s.resize (s.size() + i, s[i % s.size()]);
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s)); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
} }
// Strings with invalid Base58 characters // Strings with invalid Base58 characters
@@ -378,7 +378,7 @@ public:
{ {
auto s = good; auto s = good;
s[i % s.size()] = c; s[i % s.size()] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s)); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
} }
} }
@@ -389,7 +389,7 @@ public:
for (auto c : std::string("ansrJqtv7")) for (auto c : std::string("ansrJqtv7"))
{ {
s[0] = c; s[0] = c;
BEAST_EXPECT(!parseBase58<SecretKey> (TOKEN_NODE_PRIVATE, s)); BEAST_EXPECT(!parseBase58<SecretKey> (TokenType::NodePrivate, s));
} }
} }
@@ -402,12 +402,12 @@ public:
for (std::size_t i = 0; i != keys.size(); ++i) for (std::size_t i = 0; i != keys.size(); ++i)
{ {
auto const si = toBase58 ( auto const si = toBase58 (
TokenType::TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
keys[i]); keys[i]);
BEAST_EXPECT(!si.empty()); BEAST_EXPECT(!si.empty());
auto const ski = parseBase58<SecretKey> ( auto const ski = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, si); TokenType::NodePrivate, si);
BEAST_EXPECT(ski && keys[i] == *ski); BEAST_EXPECT(ski && keys[i] == *ski);
for (std::size_t j = i; j != keys.size(); ++j) for (std::size_t j = i; j != keys.size(); ++j)
@@ -415,13 +415,13 @@ public:
BEAST_EXPECT((keys[i] == keys[j]) == (i == j)); BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
auto const sj = toBase58 ( auto const sj = toBase58 (
TokenType::TOKEN_NODE_PRIVATE, TokenType::NodePrivate,
keys[j]); keys[j]);
BEAST_EXPECT((si == sj) == (i == j)); BEAST_EXPECT((si == sj) == (i == j));
auto const skj = parseBase58<SecretKey> ( auto const skj = parseBase58<SecretKey> (
TOKEN_NODE_PRIVATE, sj); TokenType::NodePrivate, sj);
BEAST_EXPECT(skj && keys[j] == *skj); BEAST_EXPECT(skj && keys[j] == *skj);
BEAST_EXPECT((*ski == *skj) == (i == j)); BEAST_EXPECT((*ski == *skj) == (i == j));

View File

@@ -136,9 +136,9 @@ public:
auto const publicKey = derivePublicKey ( auto const publicKey = derivePublicKey (
KeyType::secp256k1, secretKey); KeyType::secp256k1, secretKey);
BEAST_EXPECT(toBase58(TokenType::TOKEN_NODE_PUBLIC, publicKey) == BEAST_EXPECT(toBase58(TokenType::NodePublic, publicKey) ==
"n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9"); "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
BEAST_EXPECT(toBase58(TokenType::TOKEN_NODE_PRIVATE, secretKey) == BEAST_EXPECT(toBase58(TokenType::NodePrivate, secretKey) ==
"pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe"); "pnen77YEeUd4fFKG7iycBWcwKpTaeFRkW2WFostaATy1DSupwXe");
BEAST_EXPECT(to_string(calcNodeID(publicKey)) == BEAST_EXPECT(to_string(calcNodeID(publicKey)) ==
"7E59C17D50F5959C7B158FEC95C8F815BF653DC8"); "7E59C17D50F5959C7B158FEC95C8F815BF653DC8");
@@ -179,9 +179,9 @@ public:
auto const publicKey = derivePublicKey ( auto const publicKey = derivePublicKey (
KeyType::ed25519, secretKey); KeyType::ed25519, secretKey);
BEAST_EXPECT(toBase58(TokenType::TOKEN_NODE_PUBLIC, publicKey) == BEAST_EXPECT(toBase58(TokenType::NodePublic, publicKey) ==
"nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf"); "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
BEAST_EXPECT(toBase58(TokenType::TOKEN_NODE_PRIVATE, secretKey) == BEAST_EXPECT(toBase58(TokenType::NodePrivate, secretKey) ==
"paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36"); "paKv46LztLqK3GaKz1rG2nQGN6M4JLyRtxFBYFTw4wAVHtGys36");
BEAST_EXPECT(to_string(calcNodeID(publicKey)) == BEAST_EXPECT(to_string(calcNodeID(publicKey)) ==
"AA066C988C712815CC37AF71472B7CBBBD4E2A0A"); "AA066C988C712815CC37AF71472B7CBBBD4E2A0A");
@@ -223,9 +223,9 @@ public:
BEAST_EXPECT(toBase58(calcAccountID(keyPair.first)) == BEAST_EXPECT(toBase58(calcAccountID(keyPair.first)) ==
"rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh"); "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
BEAST_EXPECT(toBase58(TokenType::TOKEN_ACCOUNT_PUBLIC, keyPair.first) == BEAST_EXPECT(toBase58(TokenType::AccountPublic, keyPair.first) ==
"aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw"); "aBQG8RQAzjs1eTKFEAQXr2gS4utcDiEC9wmi7pfUPTi27VCahwgw");
BEAST_EXPECT(toBase58(TokenType::TOKEN_ACCOUNT_SECRET, keyPair.second) == BEAST_EXPECT(toBase58(TokenType::AccountSecret, keyPair.second) ==
"p9JfM6HHi64m6mvB6v5k7G2b1cXzGmYiCNJf6GHPKvFTWdeRVjh"); "p9JfM6HHi64m6mvB6v5k7G2b1cXzGmYiCNJf6GHPKvFTWdeRVjh");
auto sig = sign (keyPair.first, keyPair.second, makeSlice(message1)); auto sig = sign (keyPair.first, keyPair.second, makeSlice(message1));
@@ -263,9 +263,9 @@ public:
BEAST_EXPECT(to_string(calcAccountID(keyPair.first)) == BEAST_EXPECT(to_string(calcAccountID(keyPair.first)) ==
"rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf"); "rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf");
BEAST_EXPECT(toBase58(TokenType::TOKEN_ACCOUNT_PUBLIC, keyPair.first) == BEAST_EXPECT(toBase58(TokenType::AccountPublic, keyPair.first) ==
"aKGheSBjmCsKJVuLNKRAKpZXT6wpk2FCuEZAXJupXgdAxX5THCqR"); "aKGheSBjmCsKJVuLNKRAKpZXT6wpk2FCuEZAXJupXgdAxX5THCqR");
BEAST_EXPECT(toBase58(TokenType::TOKEN_ACCOUNT_SECRET, keyPair.second) == BEAST_EXPECT(toBase58(TokenType::AccountSecret, keyPair.second) ==
"pwDQjwEhbUBmPuEjFpEG75bFhv2obkCB7NxQsfFxM7xGHBMVPu9"); "pwDQjwEhbUBmPuEjFpEG75bFhv2obkCB7NxQsfFxM7xGHBMVPu9");
auto sig = sign (keyPair.first, keyPair.second, makeSlice(message1)); auto sig = sign (keyPair.first, keyPair.second, makeSlice(message1));
@@ -305,16 +305,16 @@ public:
auto const node1 = randomKeyPair(KeyType::secp256k1); auto const node1 = randomKeyPair(KeyType::secp256k1);
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::TOKEN_NODE_PUBLIC, node1.first))); toBase58 (TokenType::NodePublic, node1.first)));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::TOKEN_NODE_PRIVATE, node1.second))); toBase58 (TokenType::NodePrivate, node1.second)));
auto const node2 = randomKeyPair(KeyType::ed25519); auto const node2 = randomKeyPair(KeyType::ed25519);
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::TOKEN_NODE_PUBLIC, node2.first))); toBase58 (TokenType::NodePublic, node2.first)));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58 (TokenType::TOKEN_NODE_PRIVATE, node2.second))); toBase58 (TokenType::NodePrivate, node2.second)));
auto const account1 = generateKeyPair( auto const account1 = generateKeyPair(
KeyType::secp256k1, randomSeed ()); KeyType::secp256k1, randomSeed ());
@@ -322,9 +322,9 @@ public:
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(calcAccountID(account1.first)))); toBase58(calcAccountID(account1.first))));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(TokenType::TOKEN_ACCOUNT_PUBLIC, account1.first))); toBase58(TokenType::AccountPublic, account1.first)));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(TokenType::TOKEN_ACCOUNT_SECRET, account1.second))); toBase58(TokenType::AccountSecret, account1.second)));
auto const account2 = generateKeyPair( auto const account2 = generateKeyPair(
KeyType::ed25519, randomSeed ()); KeyType::ed25519, randomSeed ());
@@ -332,9 +332,9 @@ public:
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(calcAccountID(account2.first)))); toBase58(calcAccountID(account2.first))));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(TokenType::TOKEN_ACCOUNT_PUBLIC, account2.first))); toBase58(TokenType::AccountPublic, account2.first)));
BEAST_EXPECT(!parseGenericSeed ( BEAST_EXPECT(!parseGenericSeed (
toBase58(TokenType::TOKEN_ACCOUNT_SECRET, account2.second))); toBase58(TokenType::AccountSecret, account2.second)));
} }
void run() override void run() override

View File

@@ -69,7 +69,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
{ // strict mode, using properly formatted bitcoin token { // strict mode, using properly formatted bitcoin token
Json::Value params; Json::Value params;
params[jss::account] = base58EncodeTokenBitcoin ( params[jss::account] = base58EncodeTokenBitcoin (
TOKEN_ACCOUNT_ID, alice.id().data(), alice.id().size()); TokenType::AccountID, alice.id().data(), alice.id().size());
params[jss::strict] = true; params[jss::strict] = true;
auto const result = env.rpc ("json", "account_currencies", auto const result = env.rpc ("json", "account_currencies",
boost::lexical_cast<std::string>(params)) [jss::result]; boost::lexical_cast<std::string>(params)) [jss::result];

View File

@@ -308,7 +308,7 @@ public:
(keyType ? *keyType : "no key_type")); (keyType ? *keyType : "no key_type"));
auto const publicKey = parseBase58<PublicKey>( auto const publicKey = parseBase58<PublicKey>(
TokenType::TOKEN_ACCOUNT_PUBLIC, strings.public_key); TokenType::AccountPublic, strings.public_key);
BEAST_EXPECT(publicKey); BEAST_EXPECT(publicKey);
if (!keyType) if (!keyType)

View File

@@ -112,7 +112,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
// parsing as a seed to fail // parsing as a seed to fail
Json::Value params; Json::Value params;
params[jss::account] = params[jss::account] =
toBase58 (TokenType::TOKEN_NODE_PRIVATE, alice.sk()); toBase58 (TokenType::NodePrivate, alice.sk());
params[jss::role] = "user"; params[jss::role] = "user";
params[jss::ledger] = "current"; params[jss::ledger] = "current";
auto const result = env.rpc ("json", "noripple_check", auto const result = env.rpc ("json", "noripple_check",

View File

@@ -58,7 +58,7 @@ class Peers_test : public beast::unit_test::suite
200, 200,
env.timeKeeper().now() - 10s); env.timeKeeper().now() - 10s);
nodes.insert( std::make_pair( nodes.insert( std::make_pair(
toBase58(TokenType::TOKEN_NODE_PUBLIC, kp.first), name)); toBase58(TokenType::NodePublic, kp.first), name));
} }
// make request, verify nodes we created match // make request, verify nodes we created match

View File

@@ -327,7 +327,7 @@ public:
return; return;
std::string const valPublicKey = std::string const valPublicKey =
toBase58 (TokenType::TOKEN_NODE_PUBLIC, toBase58 (TokenType::NodePublic,
derivePublicKey (KeyType::secp256k1, derivePublicKey (KeyType::secp256k1,
generateSecretKey (KeyType::secp256k1, *parsedseed))); generateSecretKey (KeyType::secp256k1, *parsedseed)));

View File

@@ -183,7 +183,7 @@ public:
using address_type = boost::asio::ip::address; using address_type = boost::asio::ip::address;
auto toStr = [](PublicKey const& publicKey) { auto toStr = [](PublicKey const& publicKey) {
return toBase58(TokenType::TOKEN_NODE_PUBLIC, publicKey); return toBase58(TokenType::NodePublic, publicKey);
}; };
// Publisher manifest/signing keys // Publisher manifest/signing keys

View File

@@ -31,6 +31,7 @@
#include <test/protocol/STAmount_test.cpp> #include <test/protocol/STAmount_test.cpp>
#include <test/protocol/STObject_test.cpp> #include <test/protocol/STObject_test.cpp>
#include <test/protocol/STTx_test.cpp> #include <test/protocol/STTx_test.cpp>
#include <test/protocol/STValidation_test.cpp>
#include <test/protocol/TER_test.cpp> #include <test/protocol/TER_test.cpp>
#include <test/protocol/types_test.cpp> #include <test/protocol/types_test.cpp>
#include <test/protocol/XRPAmount_test.cpp> #include <test/protocol/XRPAmount_test.cpp>