20 #include <ripple/app/misc/Manifest.h>
21 #include <ripple/app/rdb/Wallet.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/StringUtilities.h>
24 #include <ripple/basics/base64.h>
25 #include <ripple/core/DatabaseCon.h>
26 #include <ripple/json/json_reader.h>
27 #include <ripple/protocol/PublicKey.h>
28 #include <ripple/protocol/Sign.h>
30 #include <boost/algorithm/string/trim.hpp>
43 return "Revocation Manifest " + mk;
46 Throw<std::runtime_error>(
"No SigningKey in manifest " + mk);
88 st.applyTemplate(manifestFormat);
108 auto const d = st.getFieldVL(
sfDomain);
110 domain.
assign(
reinterpret_cast<char const*
>(d.data()), d.size());
117 bool const hasEphemeralSig = st.isFieldPresent(
sfSignature);
133 if (!hasEphemeralKey)
136 if (!hasEphemeralSig)
147 if (*signingKey == masterKey)
152 reinterpret_cast<char const*
>(s.
data()), s.
size());
155 return Manifest(serialized, masterKey, signingKey, seq, domain);
159 JLOG(journal.
error())
160 <<
"Exception in " << __func__ <<
": " << ex.
what();
165 template <
class Stream>
173 s <<
"Manifest: " << action
179 template <
class Stream>
188 s <<
"Manifest: " << action
190 <<
";OldSeq: " << oldSeq <<
";";
274 return init + s.size();
277 for (
auto const& line : blob)
278 tokenStr += boost::algorithm::trim_copy(line);
285 if (r.
parse(tokenStr, token))
290 if (m.isString() && k.isString())
292 auto const key =
strUnHex(k.asString());
294 if (key && key->size() == 32)
303 JLOG(journal.
error())
304 <<
"Exception in " << __func__ <<
": " << ex.
what();
313 auto const iter =
map_.find(pk);
315 if (iter !=
map_.end() && !iter->second.revoked())
316 return iter->second.signingKey;
337 auto const iter =
map_.find(pk);
339 if (iter !=
map_.end() && !iter->second.revoked())
340 return iter->second.sequence;
349 auto const iter =
map_.find(pk);
351 if (iter !=
map_.end() && !iter->second.revoked())
352 return iter->second.domain;
361 auto const iter =
map_.find(pk);
363 if (iter !=
map_.end() && !iter->second.revoked())
364 return iter->second.serialized;
373 auto const iter =
map_.find(pk);
375 if (iter !=
map_.end())
376 return iter->second.revoked();
391 [
this, &m](
auto const& iter,
bool checkSignature,
auto const& lock)
393 assert(lock.owns_lock());
396 if (iter !=
map_.end() && m.
sequence <= iter->second.sequence)
408 iter->second.sequence);
412 if (checkSignature && !m.
verify())
414 if (
auto stream =
j_.
warn())
437 <<
": Master key already used as ephemeral key for "
448 <<
": is not revoked and the manifest has no "
449 "signing key. Hence, the manifest is "
461 <<
": Ephemeral key already used as ephemeral key for "
470 <<
to_string(m) <<
": Ephemeral key used as master key for "
498 if (
auto d = prewriteCheck(iter,
false, sl))
504 if (iter ==
map_.end())
506 if (
auto stream =
j_.
info())
513 map_.emplace(std::move(masterKey), std::move(m));
519 if (
auto stream =
j_.
info())
525 iter->second.sequence);
532 iter->second = std::move(m);
554 load(dbCon, dbTable);
556 if (!configManifest.
empty())
561 JLOG(
j_.
error()) <<
"Malformed validator_token in config";
567 JLOG(
j_.
warn()) <<
"Configured manifest revokes public key";
572 JLOG(
j_.
error()) <<
"Manifest in config was rejected";
577 if (!configRevocation.
empty())
581 configRevocation.
cbegin(),
582 configRevocation.
cend(),
585 return init + s.size();
588 for (
auto const& line : configRevocation)
589 revocationStr += boost::algorithm::trim_copy(line);
593 if (!mo || !mo->revoked() ||
596 JLOG(
j_.
error()) <<
"Invalid validator key revocation in config";
std::size_t size() const noexcept
Returns the number of bytes in the storage.
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< PublicKey > getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
const SField sfGeneric(access, 0)
std::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob, beast::Journal journal)
An immutable linear range of bytes.
const SF_UINT32 sfSequence
Value get(UInt index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical) noexcept
Verify a signature on a message.
std::string serialized
The manifest in serialized form.
PublicKey masterKey
The master key associated with this manifest.
bool verify() const
Returns true if manifest signature is valid.
const SF_VL sfSigningPubKey
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
hash_map< PublicKey, Manifest > map_
Active manifests stored by master public key.
@ badEphemeralKey
The ephemeral key is not acceptable to us.
static bool revoked(std::uint32_t sequence)
Returns true if manifest revokes master key.
Blob getFieldVL(SField const &field) const
Unserialize a JSON document into a Value.
bool empty() const noexcept
Return true if the byte range is empty.
bool revoked() const
Returns true if manifest revokes master key.
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> const &isTrusted)
Save cached manifests to database.
const SF_UINT16 sfVersion
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Defines the fields and their attributes within a STObject.
LockedSociSession checkoutDb()
hash_map< PublicKey, PublicKey > signingToMasterKeys_
Master public keys stored by current ephemeral public key.
@ badMasterKey
The master key is not acceptable to us.
const SF_VL sfMasterSignature
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::optional< Blob > getSignature() const
Returns manifest signature.
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
std::string base64_decode(std::string const &data)
std::atomic< std::uint32_t > seq_
A generic endpoint for log messages.
Blob getMasterSignature() const
Returns manifest master key signature.
@ invalid
Timely, but invalid signature.
std::optional< std::uint32_t > getSequence(PublicKey const &pk) const
Returns master key's current manifest sequence.
@ accepted
Manifest is valid.
std::uint32_t sequence
The sequence number of this manifest.
std::optional< std::string > getManifest(PublicKey const &pk) const
Returns mainfest corresponding to a given public key.
std::optional< std::string > getDomain(PublicKey const &pk) const
Returns domain claimed by a given public key.
@ stale
Sequence is too old.
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)
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
uint256 hash() const
Returns hash of serialized manifest data.
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
bool isProperlyFormedTomlDomain(std::string const &domain)
Determines if the given string looks like a TOML-file hosting domain.
std::optional< PublicKey > signingKey
The ephemeral key associated with this manifest.
std::optional< Manifest > deserializeManifest(Slice s, beast::Journal journal)
Constructs Manifest from serialized string.
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.
ManifestDisposition applyManifest(Manifest m)
Add manifest to cache.
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
void set(const SOTemplate &)
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.
T & get(EitherAmount &amt)
uint256 getHash(HashPrefix prefix) const