1#include <xrpl/basics/Log.h>
2#include <xrpl/basics/StringUtilities.h>
3#include <xrpl/basics/base64.h>
4#include <xrpl/json/json_reader.h>
5#include <xrpl/protocol/PublicKey.h>
6#include <xrpl/protocol/Sign.h>
7#include <xrpl/rdb/DatabaseCon.h>
8#include <xrpl/server/Manifest.h>
9#include <xrpl/server/Wallet.h>
11#include <boost/algorithm/string/trim.hpp>
24 return "Revocation Manifest " + mk;
27 Throw<std::runtime_error>(
"No SigningKey in manifest " + mk);
69 st.applyTemplate(manifestFormat);
72 if (st.isFieldPresent(sfVersion) && st.getFieldU16(sfVersion) != 0)
75 auto const pk = st.getFieldVL(sfPublicKey);
87 if (st.isFieldPresent(sfDomain))
89 auto const d = st.getFieldVL(sfDomain);
91 domain.
assign(
reinterpret_cast<char const*
>(d.data()), d.size());
97 bool const hasEphemeralKey = st.isFieldPresent(sfSigningPubKey);
98 bool const hasEphemeralSig = st.isFieldPresent(sfSignature);
114 if (!hasEphemeralKey)
117 if (!hasEphemeralSig)
120 auto const spk = st.getFieldVL(sfSigningPubKey);
128 if (*signingKey == masterKey)
135 return Manifest(serialized, masterKey, signingKey, seq, domain);
139 JLOG(journal.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
144template <
class Stream>
153template <
class Stream>
163 <<
";OldSeq: " << oldSeq <<
";";
220 if (!
get(st, sfSignature))
248 for (
auto const& line : blob)
249 tokenStr += boost::algorithm::trim_copy(line);
256 if (r.
parse(tokenStr, token))
261 if (m.isString() && k.isString())
263 auto const key =
strUnHex(k.asString());
265 if (key && key->size() == 32)
274 JLOG(journal.
error()) <<
"Exception in " << __func__ <<
": " << ex.
what();
283 auto const iter =
map_.find(pk);
285 if (iter !=
map_.end() && !iter->second.revoked())
286 return iter->second.signingKey;
306 auto const iter =
map_.find(pk);
308 if (iter !=
map_.end() && !iter->second.revoked())
309 return iter->second.sequence;
318 auto const iter =
map_.find(pk);
320 if (iter !=
map_.end() && !iter->second.revoked())
321 return iter->second.domain;
330 auto const iter =
map_.find(pk);
332 if (iter !=
map_.end() && !iter->second.revoked())
333 return iter->second.serialized;
342 auto const iter =
map_.find(pk);
344 if (iter !=
map_.end())
345 return iter->second.revoked();
359 auto prewriteCheck = [
this, &m](
auto const& iter,
bool checkSignature,
auto const& lock)
361 XRPL_ASSERT(lock.owns_lock(),
"xrpl::ManifestCache::applyManifest::prewriteCheck : locked");
364 if (iter !=
map_.end() && m.
sequence <= iter->second.sequence)
375 if (checkSignature && !m.
verify())
377 if (
auto stream =
j_.
warn())
398 JLOG(
j_.
warn()) <<
to_string(m) <<
": Master key already used as ephemeral key for "
409 <<
": is not revoked and the manifest has no "
410 "signing key. Hence, the manifest is "
421 <<
": Ephemeral key already used as ephemeral key for "
429 JLOG(
j_.
warn()) <<
to_string(m) <<
": Ephemeral key used as master key for "
441 if (
auto d = prewriteCheck(
map_.find(m.
masterKey),
true, sl))
456 if (
auto d = prewriteCheck(iter,
false, sl))
462 if (iter ==
map_.end())
464 if (
auto stream =
j_.
info())
471 map_.emplace(std::move(masterKey), std::move(m));
481 if (
auto stream =
j_.
info())
489 iter->second = std::move(m);
511 load(dbCon, dbTable);
513 if (!configManifest.
empty())
518 JLOG(
j_.
error()) <<
"Malformed validator_token in config";
524 JLOG(
j_.
warn()) <<
"Configured manifest revokes public key";
529 JLOG(
j_.
error()) <<
"Manifest in config was rejected";
534 if (!configRevocation.
empty())
539 configRevocation.
cbegin(),
540 configRevocation.
cend(),
544 for (
auto const& line : configRevocation)
545 revocationStr += boost::algorithm::trim_copy(line);
551 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::atomic< std::uint32_t > seq_
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::optional< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
std::optional< std::string > getDomain(PublicKey const &pk) const
Returns domain claimed by a given public key.
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
hash_map< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns manifest corresponding to a given public key.
hash_map< PublicKey, Manifest > map_
Active manifests stored by master public key.
std::optional< std::uint32_t > getSequence(PublicKey const &pk) const
Returns master key's current manifest sequence.
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
Defines the fields and their attributes within a STObject.
Blob getFieldVL(SField const &field) const
uint256 getHash(HashPrefix prefix) const
void set(SOTemplate 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.
Stream & logMftAct(Stream &s, std::string const &action, PublicKey const &pk, std::uint32_t seq)
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.
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 isProperlyFormedTomlDomain(std::string_view domain)
Determines if the given string looks like a TOML-file hosting domain.
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::string base64_decode(std::string_view data)
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
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)
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::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal=beast::Journal(beast::Journal::getNullSink()))
@ 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.
static bool revoked(std::uint32_t sequence)
Returns true if manifest revokes master key.
PublicKey masterKey
The master key associated with this manifest.
std::string serialized
The manifest in serialized form.
Blob getMasterSignature() const
Returns manifest master key signature.
std::optional< Blob > getSignature() const
Returns manifest signature.
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
std::uint32_t sequence
The sequence number of this manifest.
bool revoked() const
Returns true if manifest revokes master key.
uint256 hash() const
Returns hash of serialized manifest data.
bool verify() const
Returns true if manifest signature is valid.