From ed3efbbe271927f7fff0b806219163a994ab0c91 Mon Sep 17 00:00:00 2001 From: oneiric Date: Wed, 20 Jun 2018 23:22:54 +0000 Subject: [PATCH] RouterInfo: verify signed router Verify that a router has a valid signature. Referencing #627 + #917 --- src/core/router/info.cc | 36 +++++++++++++++++++++++++++--------- src/core/router/info.h | 6 ++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/core/router/info.cc b/src/core/router/info.cc index 44fa28c9..23b8e263 100644 --- a/src/core/router/info.cc +++ b/src/core/router/info.cc @@ -164,15 +164,7 @@ void RouterInfo::ReadFromBuffer(bool verify_signature) // Verify signature if (verify_signature) { - // Note: signature length is guaranteed to be no less than buffer length - std::uint16_t const len = - m_Buffer.size() - m_RouterIdentity.GetSignatureLen(); - if (!m_RouterIdentity.Verify( - m_Buffer.data(), len, m_Buffer.data() + len)) - { - LOG(error) << "RouterInfo: signature verification failed"; - m_IsUnreachable = true; - } + Verify(); m_RouterIdentity.DropVerifier(); } } @@ -699,6 +691,32 @@ void RouterInfo::CreateBuffer(const PrivateKeys& private_keys) m_Buffer( reinterpret_cast(router_info.Str().c_str()), router_info.Str().size()); + + // Verify signature + Verify(); + } + catch (...) + { + m_Exception.Dispatch(__func__); + throw; + } +} + +void RouterInfo::Verify() +{ + try + { + if (!m_Buffer.data()) + throw std::runtime_error("RouterInfo: null buffer"); + std::size_t const len = m_Buffer.size() - m_RouterIdentity.GetSignatureLen(); + if (len < Size::MinUnsignedBuffer) + throw std::length_error("RouterInfo: invalid RouterInfo size"); + auto const buf = m_Buffer.data(); + if (!m_RouterIdentity.Verify(buf, len, &buf[len])) + { + m_IsUnreachable = true; + throw std::runtime_error("RouterInfo: signature verification failed"); + } } catch (...) { diff --git a/src/core/router/info.h b/src/core/router/info.h index a834498c..de16e823 100644 --- a/src/core/router/info.h +++ b/src/core/router/info.h @@ -69,6 +69,7 @@ struct RouterInfoTraits { MinBuffer = core::DSA_SIGNATURE_LENGTH, // TODO(unassigned): see #498 MaxBuffer = 2048, // TODO(anonimal): review if arbitrary + MinUnsignedBuffer = 399, // Minimum RouterInfo length w/o signature, see spec // TODO(unassigned): algorithm to dynamically determine cost NTCPCost = 10, // NTCP *should* have priority over SSU SSUCost = 5, @@ -523,6 +524,11 @@ class RouterInfo : public RouterInfoTraits, public RoutingDestination /// (and subsequently sign the RI with) void CreateBuffer(const PrivateKeys& private_keys); + /// @brief Verify RI signature + /// @throws std::length_error if unsigned buffer length is below minimum + /// @throws std::runtime_error if signature verification fails + void Verify(); + /// @brief Save RI to file /// @param path Full RI path of file to save to void SaveToFile(const std::string& path);