20#include <xrpld/app/misc/Manifest.h> 
   21#include <xrpld/app/rdb/Wallet.h> 
   22#include <xrpld/core/DatabaseCon.h> 
   24#include <xrpl/basics/Log.h> 
   25#include <xrpl/basics/StringUtilities.h> 
   26#include <xrpl/basics/base64.h> 
   27#include <xrpl/json/json_reader.h> 
   28#include <xrpl/protocol/PublicKey.h> 
   29#include <xrpl/protocol/Sign.h> 
   31#include <boost/algorithm/string/trim.hpp> 
   44        return "Revocation Manifest " + mk;
 
   47        Throw<std::runtime_error>(
"No SigningKey in manifest " + mk);
 
 
   89        st.applyTemplate(manifestFormat);
 
   92        if (st.isFieldPresent(sfVersion) && st.getFieldU16(sfVersion) != 0)
 
   95        auto const pk = st.getFieldVL(sfPublicKey);
 
  107        if (st.isFieldPresent(sfDomain))
 
  109            auto const d = st.getFieldVL(sfDomain);
 
  111            domain.
assign(
reinterpret_cast<char const*
>(d.data()), d.size());
 
  117        bool const hasEphemeralKey = st.isFieldPresent(sfSigningPubKey);
 
  118        bool const hasEphemeralSig = st.isFieldPresent(sfSignature);
 
  134            if (!hasEphemeralKey)
 
  137            if (!hasEphemeralSig)
 
  140            auto const spk = st.getFieldVL(sfSigningPubKey);
 
  148            if (*signingKey == masterKey)
 
  153            reinterpret_cast<char const*
>(s.
data()), s.
size());
 
  156        return Manifest(serialized, masterKey, signingKey, seq, domain);
 
  160        JLOG(journal.
error())
 
  161            << 
"Exception in " << __func__ << 
": " << ex.
what();
 
 
  166template <
class Stream>
 
  174    s << 
"Manifest: " << action
 
 
  180template <
class Stream>
 
  189    s << 
"Manifest: " << action
 
  191      << 
";OldSeq: " << oldSeq << 
";";
 
 
  249    if (!
get(st, sfSignature))
 
 
  275                return init + s.size();
 
  278        for (
auto const& line : blob)
 
  279            tokenStr += boost::algorithm::trim_copy(line);
 
  286        if (r.
parse(tokenStr, token))
 
  291            if (m.isString() && k.isString())
 
  293                auto const key = 
strUnHex(k.asString());
 
  295                if (key && key->size() == 32)
 
  304        JLOG(journal.
error())
 
  305            << 
"Exception in " << __func__ << 
": " << ex.
what();
 
 
  314    auto const iter = 
map_.find(pk);
 
  316    if (iter != 
map_.end() && !iter->second.revoked())
 
  317        return iter->second.signingKey;
 
 
  338    auto const iter = 
map_.find(pk);
 
  340    if (iter != 
map_.end() && !iter->second.revoked())
 
  341        return iter->second.sequence;
 
 
  350    auto const iter = 
map_.find(pk);
 
  352    if (iter != 
map_.end() && !iter->second.revoked())
 
  353        return iter->second.domain;
 
 
  362    auto const iter = 
map_.find(pk);
 
  364    if (iter != 
map_.end() && !iter->second.revoked())
 
  365        return iter->second.serialized;
 
 
  374    auto const iter = 
map_.find(pk);
 
  376    if (iter != 
map_.end())
 
  377        return iter->second.revoked();
 
 
  392        [
this, &m](
auto const& iter, 
bool checkSignature, 
auto const& lock)
 
  396            "ripple::ManifestCache::applyManifest::prewriteCheck : locked");
 
  399        if (iter != 
map_.end() && m.
sequence <= iter->second.sequence)
 
  411                    iter->second.sequence);
 
  415        if (checkSignature && !m.
verify())
 
  417            if (
auto stream = 
j_.
warn())
 
  440                            << 
": Master key already used as ephemeral key for " 
  451                                << 
": is not revoked and the manifest has no " 
  452                                   "signing key. Hence, the manifest is " 
  464                    << 
": Ephemeral key already used as ephemeral key for " 
  473                    << 
to_string(m) << 
": Ephemeral key used as master key for " 
  501    if (
auto d = prewriteCheck(iter,  
false, sl))
 
  507    if (iter == 
map_.end())
 
  509        if (
auto stream = 
j_.
info())
 
  516        map_.emplace(std::move(masterKey), std::move(m));
 
  522    if (
auto stream = 
j_.
info())
 
  528            iter->second.sequence);
 
  535    iter->second = std::move(m);
 
 
  557    load(dbCon, dbTable);
 
  559    if (!configManifest.
empty())
 
  564            JLOG(
j_.
error()) << 
"Malformed validator_token in config";
 
  570            JLOG(
j_.
warn()) << 
"Configured manifest revokes public key";
 
  575            JLOG(
j_.
error()) << 
"Manifest in config was rejected";
 
  580    if (!configRevocation.
empty())
 
  584            configRevocation.
cbegin(),
 
  585            configRevocation.
cend(),
 
  588                return init + s.size();
 
  591        for (
auto const& line : configRevocation)
 
  592            revocationStr += boost::algorithm::trim_copy(line);
 
  596        if (!mo || !mo->revoked() ||
 
  599            JLOG(
j_.
error()) << 
"Invalid validator key revocation in config";
 
 
Unserialize a JSON document into a Value.
 
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
 
Value get(UInt index, Value const &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
 
A generic endpoint for log messages.
 
LockedSociSession checkoutDb()
 
std::optional< std::uint32_t > getSequence(PublicKey const &pk) const
Returns master key's current manifest sequence.
 
hash_map< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
 
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns mainfest corresponding to a given public key.
 
std::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
 
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
 
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
 
hash_map< PublicKey, Manifest > map_
Active manifests stored by master public key.
 
bool load(DatabaseCon &dbCon, std::string const &dbTable, std::string const &configManifest, std::vector< std::string > const &configRevocation)
Populate manifest cache with manifests in database and config.
 
std::atomic< std::uint32_t > seq_
 
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
 
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
 
std::optional< std::string > getDomain(PublicKey const &pk) const
Returns domain claimed by a given public key.
 
Defines the fields and their attributes within a STObject.
 
Blob getFieldVL(SField const &field) const
 
void set(SOTemplate const &)
 
uint256 getHash(HashPrefix prefix) const
 
An immutable linear range of bytes.
 
bool empty() const noexcept
Return true if the byte range is empty.
 
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
 
std::size_t size() const noexcept
Returns the number of bytes in the storage.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
 
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
 
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
 
void saveManifests(soci::session &session, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted, hash_map< PublicKey, Manifest > const &map, beast::Journal j)
saveManifests Saves all given manifests to the database.
 
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a signature on a message.
 
std::string base64_decode(std::string_view data)
 
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
 
Stream & logMftAct(Stream &s, std::string const &action, PublicKey const &pk, std::uint32_t seq)
 
@ badMasterKey
The master key is not acceptable to us.
 
@ stale
Sequence is too old.
 
@ accepted
Manifest is valid.
 
@ badEphemeralKey
The ephemeral key is not acceptable to us.
 
@ invalid
Timely, but invalid signature.
 
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)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
T get(Section const §ion, std::string const &name, T const &defaultValue=T{})
Retrieve a key/value pair from a section.
 
std::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal)
 
bool isProperlyFormedTomlDomain(std::string_view domain)
Determines if the given string looks like a TOML-file hosting domain.
 
void getManifests(soci::session &session, std::string const &dbTable, ManifestCache &mCache, beast::Journal j)
getManifests Loads a manifest from the wallet database and stores it in the cache.
 
std::string serialized
The manifest in serialized form.
 
std::uint32_t sequence
The sequence number of this manifest.
 
static bool revoked(std::uint32_t sequence)
Returns true if manifest revokes master key.
 
bool revoked() const
Returns true if manifest revokes master key.
 
bool verify() const
Returns true if manifest signature is valid.
 
uint256 hash() const
Returns hash of serialized manifest data.
 
std::optional< Blob > getSignature() const
Returns manifest signature.
 
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
 
Blob getMasterSignature() const
Returns manifest master key signature.
 
PublicKey masterKey
The master key associated with this manifest.