Skip to content

Commit 51c5f2b

Browse files
authored
Improve ValidatorList invalid UNL manifest logging (#5804)
This change raises logging severity from `INFO` to `WARN` when handling UNL manifest signed with an unexpected / invalid key. It also changes the internal error code for an invalid format of UNL manifest to `invalid` (from `untrusted`). This is a follow up to problems experienced by an UNL node due to old manifest key configured in `validators.txt`, which would be easier to diagnose with improved logging. It also replaces a log line with `UNREACHABLE` for an impossible situation when we match UNL manifest key against a configured key which has an invalid type (we cannot configure such a key because of checks when loading configured keys).
1 parent 73ff541 commit 51c5f2b

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

src/test/app/ValidatorList_test.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,24 @@ class ValidatorList_test : public beast::unit_test::suite
768768
expectUntrusted(lists.at(7));
769769
expectTrusted(lists.at(2));
770770

771+
// try empty or mangled manifest
772+
checkResult(
773+
trustedKeys->applyLists(
774+
"", version, {{blob7, sig7, {}}, {blob6, sig6, {}}}, siteUri),
775+
publisherPublic,
776+
ListDisposition::invalid,
777+
ListDisposition::invalid);
778+
779+
checkResult(
780+
trustedKeys->applyLists(
781+
base64_encode("not a manifest"),
782+
version,
783+
{{blob7, sig7, {}}, {blob6, sig6, {}}},
784+
siteUri),
785+
publisherPublic,
786+
ListDisposition::invalid,
787+
ListDisposition::invalid);
788+
771789
// do not use list from untrusted publisher
772790
auto const untrustedManifest = base64_encode(makeManifestString(
773791
randomMasterKey(),

src/xrpld/app/misc/ValidatorList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ class ValidatorList
877877
verify(
878878
lock_guard const&,
879879
Json::Value& list,
880-
std::string const& manifest,
880+
Manifest manifest,
881881
std::string const& blob,
882882
std::string const& signature);
883883

src/xrpld/app/misc/detail/ValidatorList.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,21 +1149,33 @@ ValidatorList::applyList(
11491149

11501150
Json::Value list;
11511151
auto const& manifest = localManifest ? *localManifest : globalManifest;
1152-
auto [result, pubKeyOpt] = verify(lock, list, manifest, blob, signature);
1152+
auto m = deserializeManifest(base64_decode(manifest));
1153+
if (!m)
1154+
{
1155+
JLOG(j_.warn()) << "UNL manifest cannot be deserialized";
1156+
return PublisherListStats{ListDisposition::invalid};
1157+
}
1158+
1159+
auto [result, pubKeyOpt] =
1160+
verify(lock, list, std::move(*m), blob, signature);
11531161

11541162
if (!pubKeyOpt)
11551163
{
1156-
JLOG(j_.info()) << "ValidatorList::applyList unable to retrieve the "
1157-
"master public key from the verify function\n";
1164+
JLOG(j_.warn())
1165+
<< "UNL manifest is signed with an unrecognized master public key";
11581166
return PublisherListStats{result};
11591167
}
11601168

11611169
if (!publicKeyType(*pubKeyOpt))
1162-
{
1163-
JLOG(j_.info()) << "ValidatorList::applyList Invalid Public Key type"
1164-
" retrieved from the verify function\n ";
1170+
{ // LCOV_EXCL_START
1171+
// This is an impossible situation because we will never load an
1172+
// invalid public key type (see checks in `ValidatorList::load`) however
1173+
// we can only arrive here if the key used by the manifest matched one of
1174+
// the loaded keys
1175+
UNREACHABLE(
1176+
"ripple::ValidatorList::applyList : invalid public key type");
11651177
return PublisherListStats{result};
1166-
}
1178+
} // LCOV_EXCL_STOP
11671179

11681180
PublicKey pubKey = *pubKeyOpt;
11691181
if (result > ListDisposition::pending)
@@ -1356,19 +1368,17 @@ std::pair<ListDisposition, std::optional<PublicKey>>
13561368
ValidatorList::verify(
13571369
ValidatorList::lock_guard const& lock,
13581370
Json::Value& list,
1359-
std::string const& manifest,
1371+
Manifest manifest,
13601372
std::string const& blob,
13611373
std::string const& signature)
13621374
{
1363-
auto m = deserializeManifest(base64_decode(manifest));
1364-
1365-
if (!m || !publisherLists_.count(m->masterKey))
1375+
if (!publisherLists_.count(manifest.masterKey))
13661376
return {ListDisposition::untrusted, {}};
13671377

1368-
PublicKey masterPubKey = m->masterKey;
1369-
auto const revoked = m->revoked();
1378+
PublicKey masterPubKey = manifest.masterKey;
1379+
auto const revoked = manifest.revoked();
13701380

1371-
auto const result = publisherManifests_.applyManifest(std::move(*m));
1381+
auto const result = publisherManifests_.applyManifest(std::move(manifest));
13721382

13731383
if (revoked && result == ManifestDisposition::accepted)
13741384
{
@@ -1796,7 +1806,7 @@ ValidatorList::getAvailable(
17961806

17971807
if (!keyBlob || !publicKeyType(makeSlice(*keyBlob)))
17981808
{
1799-
JLOG(j_.info()) << "Invalid requested validator list publisher key: "
1809+
JLOG(j_.warn()) << "Invalid requested validator list publisher key: "
18001810
<< pubKey;
18011811
return {};
18021812
}

0 commit comments

Comments
 (0)