20 #include <ripple/app/main/DBInit.h>
21 #include <ripple/app/misc/Manifest.h>
22 #include <ripple/app/misc/ValidatorList.h>
23 #include <ripple/basics/StringUtilities.h>
24 #include <ripple/basics/base64.h>
25 #include <ripple/basics/contract.h>
26 #include <ripple/core/DatabaseCon.h>
27 #include <ripple/protocol/STExchange.h>
28 #include <ripple/protocol/SecretKey.h>
29 #include <ripple/protocol/Sign.h>
30 #include <boost/algorithm/string.hpp>
31 #include <boost/filesystem.hpp>
32 #include <boost/utility/in_place_factory.hpp>
56 using namespace boost::filesystem;
57 if (!exists(dbPath) || !is_directory(dbPath) || !is_empty(dbPath))
65 using namespace boost::filesystem;
68 create_directory(dbPath);
72 if (!is_directory(dbPath))
75 Throw<std::runtime_error>(
76 "Cannot create directory: " + dbPath.string());
79 static boost::filesystem::path
82 return boost::filesystem::current_path() /
"manifest_test_databases";
139 bool invalidSig =
false)
189 return std::move(*r);
190 Throw<std::runtime_error>(
"Could not create a revocation manifest");
202 bool invalidSig =
false)
229 static_cast<char const*
>(s.
data()),
232 return std::move(*r);
233 Throw<std::runtime_error>(
"Could not create a manifest");
253 testcase(
"load/store");
266 auto getPopulatedManifests =
270 cache.for_each_manifest(
280 return lhs->serialized < rhs->serialized;
285 sort(getPopulatedManifests(m)));
288 auto& app = env.
app();
289 auto unl = std::make_unique<ValidatorList>(
293 app.config().legacy(
"database_path"),
301 "ValidatorManifests",
303 return unl->listed(pubKey);
308 loaded.
load(dbCon,
"ValidatorManifests");
312 sort(getPopulatedManifests(loaded)));
314 for (
auto const& man : loadedManifests)
315 BEAST_EXPECT(man->revoked());
323 for (
auto const& man : inManifests)
326 unl->load(emptyLocalKey, s1, keys);
330 "ValidatorManifests",
332 return unl->listed(pubKey);
335 loaded.
load(dbCon,
"ValidatorManifests");
339 sort(getPopulatedManifests(loaded)));
341 if (inManifests.size() == loadedManifests.
size())
346 loadedManifests.
begin(),
362 BEAST_EXPECT(!loaded.
load(
363 dbCon,
"ValidatorManifests", badManifest, emptyRevocation));
372 BEAST_EXPECT(loaded.
load(
373 dbCon,
"ValidatorManifests", cfgManifest, emptyRevocation));
382 BEAST_EXPECT(!loaded.
load(
383 dbCon,
"ValidatorManifests", emptyManifest, badRevocation));
392 BEAST_EXPECT(!loaded.
load(
393 dbCon,
"ValidatorManifests", emptyManifest, nonRevocation));
394 BEAST_EXPECT(!loaded.
revoked(pk));
398 BEAST_EXPECT(!loaded.
load(
400 "ValidatorManifests",
403 BEAST_EXPECT(!loaded.
revoked(pk));
407 BEAST_EXPECT(loaded.
load(
408 dbCon,
"ValidatorManifests", emptyManifest, cfgRevocation));
410 BEAST_EXPECT(loaded.
revoked(pk));
413 boost::filesystem::remove(
420 testcase(
"getSignature");
438 BEAST_EXPECT(
strHex(masterSig) ==
strHex(m.getMasterSignature()));
476 BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
487 BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
495 BEAST_EXPECT(cache.
revoked(pk));
497 BEAST_EXPECT(cache.
getMasterKey(kp0.first) == kp0.first);
498 BEAST_EXPECT(cache.
getMasterKey(kp1.first) == kp1.first);
504 testcase(
"validator token");
507 auto const valSecret = parseBase58<SecretKey>(
509 "paQmjZ37pKKPMrgadBLsuf9ab7Y7EUNzh27LQrZqoexpAs31nJi");
514 "eyJ2YWxpZGF0aW9uX3NlY3JldF9rZXkiOiI5ZWQ0NWY4NjYyNDFjYzE4YTI3ND"
516 " \tQzODdjMDYyNTkwNzk3MmY0ZTcxOTAyMzFmYWE5Mzc0NTdmYTlkYWY2Iiwib"
518 "\tc3QiOiJKQUFBQUFGeEllMUZ0d21pbXZHdEgyaUNjTUpxQzlnVkZLaWxHZncx"
521 "hYWExwbGMyR25NaEFrRTFhZ3FYeEJ3RHdEYklENk9NU1l1TTBGREFscEFnTms4"
523 "bjdNTzJmZGtjd1JRSWhBT25ndTlzQUtxWFlvdUorbDJWMFcrc0FPa1ZCK1pSUz"
525 "hsSkFmVXNYZkFpQnNWSkdlc2FhZE9KYy9hQVpva1MxdnltR21WcmxIUEtXWDNZ"
527 "NmluOEhBU1FLUHVnQkQ2N2tNYVJGR3ZtcEFUSGxHS0pkdkRGbFdQWXk1QXFEZW"
529 "VUSmEydzBpMjFlcTNNWXl3TFZKWm5GT3I3QzBrdzJBaVR6U0NqSXpkaXRROD0i"
533 "JAAAAAFxIe1FtwmimvGtH2iCcMJqC9gVFKilGfw1/"
534 "vCxHXXLplc2GnMhAkE1agqXxBwD"
535 "wDbID6OMSYuM0FDAlpAgNk8SKFn7MO2fdkcwRQIhAOngu9sAKqXYouJ+l2V0W+"
537 "+ZRS6PShlJAfUsXfAiBsVJGesaadOJc/"
538 "aAZokS1vymGmVrlHPKWX3Yywu6in8HASQKPu"
539 "gBD67kMaRFGvmpATHlGKJdvDFlWPYy5AqDedFv5TJa2w0i21eq3MYywLVJZnFO"
545 BEAST_EXPECT(token->validationSecret == *valSecret);
546 BEAST_EXPECT(token->manifest ==
manifest);
557 testcase(
"Versioning");
606 0x99, 0x30, 0xE7, 0xFC, 0x9D, 0x56, 0xBB, 0x25, 0xD6, 0x89, 0x3B,
607 0xA3, 0xF3, 0x17, 0xAE, 0x5B, 0xCF, 0x33, 0xB3, 0x29, 0x1B, 0xD6,
608 0x3D, 0xB3, 0x26, 0x54, 0xA3, 0x13, 0x22, 0x2F, 0x7F, 0xD0, 0x20};
629 auto toString = [](
STObject const& st) {
636 for (
auto const keyType : keyTypes)
641 for (
auto const sKeyType : keyTypes)
646 auto buildManifestObject =
648 boost::optional<std::string> domain,
649 bool noSigningPublic =
false,
650 bool noSignature =
false) {
658 if (!noSigningPublic)
675 testcase <<
"deserializeManifest: normal manifest ("
681 buildManifestObject(++sequence, boost::none);
683 auto const m = toString(st);
687 BEAST_EXPECT(
manifest->masterKey == pk);
688 BEAST_EXPECT(
manifest->signingKey == spk);
689 BEAST_EXPECT(
manifest->sequence == sequence);
690 BEAST_EXPECT(
manifest->serialized == m);
691 BEAST_EXPECT(
manifest->domain.empty());
704 buildManifestObject(++sequence,
std::string{
"a.b"});
710 buildManifestObject(++sequence, s +
".example.com");
716 buildManifestObject(++sequence, s +
".example.com");
720 auto const st = buildManifestObject(
725 auto const m = toString(st);
729 BEAST_EXPECT(
manifest->masterKey == pk);
730 BEAST_EXPECT(
manifest->signingKey == spk);
731 BEAST_EXPECT(
manifest->sequence == sequence);
732 BEAST_EXPECT(
manifest->serialized == m);
733 BEAST_EXPECT(
manifest->domain ==
"example.com");
741 auto const m = toString(badSigSt);
745 BEAST_EXPECT(
manifest->masterKey == spk);
746 BEAST_EXPECT(
manifest->signingKey == spk);
747 BEAST_EXPECT(
manifest->sequence == sequence);
748 BEAST_EXPECT(
manifest->serialized == m);
749 BEAST_EXPECT(
manifest->domain ==
"example.com");
809 testcase <<
"deserializeManifest: revocation manifest ("
815 auto const st = buildManifestObject(
821 auto const m = toString(st);
825 BEAST_EXPECT(
manifest->masterKey == pk);
828 BEAST_EXPECT(
manifest->domain.empty());
829 BEAST_EXPECT(
manifest->serialized == m);
834 auto const st = buildManifestObject(
843 auto const st = buildManifestObject(
852 auto const st = buildManifestObject(
868 testcase(
"Manifest Domain Names");
898 BEAST_EXPECT(test(
"example.com"));
899 BEAST_EXPECT(test(
"test.example.com"));
900 BEAST_EXPECT(test(
"example-domain.com"));
901 BEAST_EXPECT(test(
"xn--mxavchb.gr"));
902 BEAST_EXPECT(test(
"test.xn--mxavchb.gr"));
903 BEAST_EXPECT(test(
"123.gr"));
904 BEAST_EXPECT(test(
"x.yz"));
905 BEAST_EXPECT(test(
std::string(63,
'a') +
".example.com"));
909 BEAST_EXPECT(!test(
"example"));
912 BEAST_EXPECT(!test(
".com"));
913 BEAST_EXPECT(!test(
".example.com"));
916 BEAST_EXPECT(!test(
"example.com."));
919 BEAST_EXPECT(!test(
"-example.com"));
920 BEAST_EXPECT(!test(
"example-.com"));
923 BEAST_EXPECT(!test(
"double..periods.example.com"));
926 BEAST_EXPECT(!test(
"example.x"));
927 BEAST_EXPECT(!test(
"example." +
std::string(64,
'a')));
930 BEAST_EXPECT(!test(
"example.com-org"));
931 BEAST_EXPECT(!test(
"bang!.com"));
932 BEAST_EXPECT(!test(
"bang!.example.com"));
935 BEAST_EXPECT(!test(
"a.b"));
938 BEAST_EXPECT(!test(
std::string(64,
'a') +
".com"));
939 BEAST_EXPECT(!test(
std::string(64,
'a') +
".example.com"));
980 auto const fake = s_b1.serialized +
'\0';
1000 BEAST_EXPECT(!cache.
revoked(pk_a));
1001 BEAST_EXPECT(s_aMax.revoked());
1012 BEAST_EXPECT(cache.
revoked(pk_a));
void save(DatabaseCon &dbCon, std::string const &dbTable, std::function< bool(PublicKey const &)> isTrusted)
Save cached manifests to database.
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)
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
static boost::filesystem::path getDatabasePath()
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
const SField sfGeneric(access, 0)
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
const SF_UINT32 sfSequence
PublicKey signingKey
The ephemeral key associated with this manifest.
std::string serialized
The manifest in serialized form.
std::string base64_encode(std::uint8_t const *data, std::size_t len)
PublicKey masterKey
The master key associated with this manifest.
const SF_VL sfSigningPubKey
std::string makeManifestString(PublicKey const &pk, SecretKey const &sk, PublicKey const &spk, SecretKey const &ssk, int seq)
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
const beast::Journal journal
ManualTimeKeeper & timeKeeper()
boost::filesystem::path dataDir
std::string to_string(ListDisposition disposition)
void const * data() const noexcept
std::string makeRevocationString(SecretKey const &sk, KeyType type, bool invalidSig=false)
const SF_UINT16 sfVersion
Manifest clone(Manifest const &m)
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical)
Verify a signature on a message.
static PublicKey randomNode()
Manifest makeRevocation(SecretKey const &sk, KeyType type, bool invalidSig=false)
void testManifestDeserialization()
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
const SF_VL sfMasterSignature
bool revoked(PublicKey const &pk) const
Returns true if master key has been revoked in a manifest.
void testLoadStore(ManifestCache &m)
Seed randomSeed()
Create a seed using secure random numbers.
Slice slice() const noexcept
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
PublicKey getSigningKey(PublicKey const &pk) const
Returns master key's current signing key.
Set the regular signature on a JTx.
void addWithoutSigningFields(Serializer &s) const
static PublicKey randomMasterKey()
static void cleanupDatabaseDir(boost::filesystem::path const &dbPath)
@ invalid
Timely, but invalid signature.
void testManifestVersioning()
@ accepted
Manifest is valid.
std::uint32_t sequence
The sequence number of this manifest.
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Set the sequence number on a JTx.
Remembers manifests with the highest sequence number.
@ stale
Sequence is too old.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
boost::optional< Manifest > deserializeManifest(Slice s)
Constructs Manifest from serialized string.
std::size_t size() const noexcept
virtual void add(Serializer &s) const override
boost::optional< ValidatorToken > loadValidatorToken(std::vector< std::string > const &blob)
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
void testManifestDomainNames()
Manifest makeManifest(SecretKey const &sk, KeyType type, SecretKey const &ssk, KeyType stype, int seq, bool invalidSig=false)
static void setupDatabaseDir(boost::filesystem::path const &dbPath)
int add32(std::uint32_t i)
std::string strHex(FwdIt begin, FwdIt end)
constexpr std::array< char const *, 6 > WalletDBInit
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.
void testValidatorToken()
A transaction testing environment.
SecretKey randomSecretKey()
Create a secret key using secure random numbers.