From 8c59c514b2e6d07e9a540a7e9e7b1c8964d605f6 Mon Sep 17 00:00:00 2001 From: zzz <zzz@i2pmail.org> Date: Sun, 27 Mar 2022 08:21:22 -0400 Subject: [PATCH] Router: Validate family sig at startup when loaded from router.info, and discard if invalid or when family changed. This fixes some routers out there with bad sigs. Don't loop forever through LoadRouterInfoJob. --- .../i2p/router/startup/LoadRouterInfoJob.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java index c91b6991cf..8ff2f88927 100644 --- a/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java +++ b/router/java/src/net/i2p/router/startup/LoadRouterInfoJob.java @@ -104,11 +104,32 @@ class LoadRouterInfoJob extends JobImpl { if (_log.shouldLog(Log.DEBUG)) _log.debug("Reading in routerInfo from " + rif.getAbsolutePath() + " and it has " + info.getAddresses().size() + " addresses"); // don't reuse if family name changed - if (DataHelper.eq(info.getOption(FamilyKeyCrypto.OPT_NAME), - getContext().getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME))) { + String oldFamily = info.getOption(FamilyKeyCrypto.OPT_NAME); + if (oldFamily == null) { _us = info; + } else if (oldFamily.equals(getContext().getProperty(FamilyKeyCrypto.PROP_FAMILY_NAME))) { + // This keeps the signature the same across restarts, + // which is good because ECDSA creates a different signature each time, + // but in some situations such as leaving and re-joining or recreating a family, + // or copying router.info to a new router, + // could lead to a bad signature being perpetuated forever. + // Here we ignore and delete router.info if the sig is invalid. + FamilyKeyCrypto fkc = getContext().router().getFamilyKeyCrypto(); + if (fkc != null && fkc.verifyOurFamily(info)) { + _us = info; + } else { + _log.logAlways(Log.WARN, "NetDb family keys are invalid"); + // close and delete so we don't infinite loop + try { fis1.close(); } catch (IOException ioe2) {} + fis1 = null; + rif.delete(); + } } else { _log.logAlways(Log.WARN, "NetDb family name changed"); + // close and delete so we don't infinite loop + try { fis1.close(); } catch (IOException ioe2) {} + fis1 = null; + rif.delete(); } } -- GitLab