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/basics/contract.h>
26 #include <ripple/beast/rfc2616.h>
27 #include <ripple/core/DatabaseCon.h>
28 #include <ripple/json/json_reader.h>
29 #include <ripple/protocol/PublicKey.h>
30 #include <ripple/protocol/Sign.h>
32 #include <boost/algorithm/string/trim.hpp>
46 return "Revocation Manifest " + mk;
88 st.applyTemplate(manifestFormat);
106 auto const d = st.getFieldVL(
sfDomain);
108 m.
domain.
assign(
reinterpret_cast<char const*
>(d.data()), d.size());
115 bool const hasEphemeralSig = st.isFieldPresent(
sfSignature);
131 if (!hasEphemeralKey)
134 if (!hasEphemeralSig)
153 JLOG(journal.
error())
154 <<
"Exception in " << __func__ <<
": " << ex.
what();
159 template <
class Stream>
167 s <<
"Manifest: " << action
173 template <
class Stream>
182 s <<
"Manifest: " << action
184 <<
";OldSeq: " << oldSeq <<
";";
255 return init + s.size();
258 for (
auto const& line : blob)
259 tokenStr += boost::algorithm::trim_copy(line);
266 if (r.
parse(tokenStr, token))
271 if (m.isString() && k.isString())
273 auto const key =
strUnHex(k.asString());
275 if (key && key->size() == 32)
284 JLOG(journal.
error())
285 <<
"Exception in " << __func__ <<
": " << ex.
what();
294 auto const iter =
map_.find(pk);
296 if (iter !=
map_.end() && !iter->second.revoked())
297 return iter->second.signingKey;
318 auto const iter =
map_.find(pk);
320 if (iter !=
map_.end() && !iter->second.revoked())
321 return iter->second.sequence;
330 auto const iter =
map_.find(pk);
332 if (iter !=
map_.end() && !iter->second.revoked())
333 return iter->second.domain;
342 auto const iter =
map_.find(pk);
344 if (iter !=
map_.end() && !iter->second.revoked())
345 return iter->second.serialized;
354 auto const iter =
map_.find(pk);
356 if (iter !=
map_.end())
357 return iter->second.revoked();
372 [
this, &m](
auto const& iter,
bool checkSignature,
auto const& lock)
374 assert(lock.owns_lock());
377 if (iter !=
map_.end() && m.
sequence <= iter->second.sequence)
389 iter->second.sequence);
393 if (checkSignature && !m.
verify())
395 if (
auto stream =
j_.
warn())
418 <<
": Master key already used as ephemeral key for "
433 <<
": Ephemeral key already used as ephemeral key for "
442 <<
to_string(m) <<
": Ephemeral key used as master key for "
470 if (
auto d = prewriteCheck(iter,
false, sl))
476 if (iter ==
map_.end())
478 if (
auto stream =
j_.
info())
485 map_.emplace(std::move(masterKey), std::move(m));
491 if (
auto stream =
j_.
info())
497 iter->second.sequence);
504 iter->second = std::move(m);
526 load(dbCon, dbTable);
528 if (!configManifest.
empty())
533 JLOG(
j_.
error()) <<
"Malformed validator_token in config";
539 JLOG(
j_.
warn()) <<
"Configured manifest revokes public key";
544 JLOG(
j_.
error()) <<
"Manifest in config was rejected";
549 if (!configRevocation.
empty())
553 configRevocation.
cbegin(),
554 configRevocation.
cend(),
557 return init + s.size();
560 for (
auto const& line : configRevocation)
561 revocationStr += boost::algorithm::trim_copy(line);
565 if (!mo || !mo->revoked() ||
568 JLOG(
j_.
error()) <<
"Invalid validator key revocation in config";
std::size_t size() const noexcept
Returns the number of bytes in the storage.
std::string domain
The domain, if one was specified in the manifest; empty otherwise.
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)
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.
PublicKey signingKey
The ephemeral key associated with this manifest.
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.
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_
PublicKey getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
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< 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