diff --git a/node/CMakeLists.txt b/node/CMakeLists.txt index eb45b6df8..74fdbb2ab 100644 --- a/node/CMakeLists.txt +++ b/node/CMakeLists.txt @@ -51,7 +51,6 @@ set(core_headers set(core_src AES.cpp C25519.cpp - Capability.cpp Credential.cpp ECC384.cpp Identity.cpp diff --git a/node/Capability.cpp b/node/Capability.cpp deleted file mode 100644 index f10d385aa..000000000 --- a/node/Capability.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2019 ZeroTier, Inc. https://www.zerotier.com/ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * -- - * - * You can be released from the requirements of the license by purchasing - * a commercial license. Buying such a license is mandatory as soon as you - * develop commercial closed-source software that incorporates or links - * directly against ZeroTier software without disclosing the source code - * of your own application. - */ - -#include "Capability.hpp" -#include "RuntimeEnvironment.hpp" -#include "Identity.hpp" -#include "Topology.hpp" -#include "Switch.hpp" -#include "Network.hpp" -#include "Node.hpp" - -namespace ZeroTier { - -int Capability::verify(const RuntimeEnvironment *RR,void *tPtr) const -{ - try { - // There must be at least one entry, and sanity check for bad chain max length - if ((_maxCustodyChainLength < 1)||(_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) - return -1; - - // Validate all entries in chain of custody - Buffer<(sizeof(Capability) * 2)> tmp; - this->serialize(tmp,true); - for(unsigned int c=0;c<_maxCustodyChainLength;++c) { - if (c == 0) { - if ((!_custody[c].to)||(!_custody[c].from)||(_custody[c].from != Network::controllerFor(_nwid))) - return -1; // the first entry must be present and from the network's controller - } else { - if (!_custody[c].to) - return 0; // all previous entries were valid, so we are valid - else if ((!_custody[c].from)||(_custody[c].from != _custody[c-1].to)) - return -1; // otherwise if we have another entry it must be from the previous holder in the chain - } - - const Identity id(RR->topology->getIdentity(tPtr,_custody[c].from)); - if (id) { - if (!id.verify(tmp.data(),tmp.size(),_custody[c].signature,_custody[c].signatureLength)) - return -1; - } else { - RR->sw->requestWhois(tPtr,RR->node->now(),_custody[c].from); - return 1; - } - } - - // We reached max custody chain length and everything was valid - return 0; - } catch ( ... ) {} - return -1; -} - -} // namespace ZeroTier diff --git a/node/Capability.hpp b/node/Capability.hpp index 7334ad1df..2f4cd3c80 100644 --- a/node/Capability.hpp +++ b/node/Capability.hpp @@ -177,10 +177,9 @@ public: * Verify this capability's chain of custody and signatures * * @param RR Runtime environment to provide for peer lookup, etc. - * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain */ - int verify(const RuntimeEnvironment *RR,void *tPtr) const; - + inline Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); } + template static inline void serializeRules(Buffer &b,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) { diff --git a/node/Credential.cpp b/node/Credential.cpp index 4df96bf87..e0cd01a9e 100644 --- a/node/Credential.cpp +++ b/node/Credential.cpp @@ -85,4 +85,41 @@ Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *const RR, return (id.verify(buf,ptr * sizeof(uint64_t),credential._signature,credential._signatureLength) ? Credential::VERIFY_OK : Credential::VERIFY_BAD_SIGNATURE); } +Credential::VerifyResult Credential::_verify(const RuntimeEnvironment *RR,void *tPtr,const Capability &credential) const +{ + try { + // There must be at least one entry, and sanity check for bad chain max length + if ((credential._maxCustodyChainLength < 1)||(credential._maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) + return Credential::VERIFY_BAD_SIGNATURE; + + // Validate all entries in chain of custody + Buffer<(sizeof(Capability) * 2)> tmp; + credential.serialize(tmp,true); + for(unsigned int c=0;ctopology->getIdentity(tPtr,credential._custody[c].from)); + if (id) { + if (!id.verify(tmp.data(),tmp.size(),credential._custody[c].signature,credential._custody[c].signatureLength)) + return Credential::VERIFY_BAD_SIGNATURE; + } else { + RR->sw->requestWhois(tPtr,RR->node->now(),credential._custody[c].from); + return Credential::VERIFY_NEED_IDENTITY; + } + } + + // We reached max custody chain length and everything was valid + return Credential::VERIFY_OK; + } catch ( ... ) {} + return Credential::VERIFY_BAD_SIGNATURE; +} + } // namespace ZeroTier diff --git a/node/Credential.hpp b/node/Credential.hpp index 84808a3ef..7948e611d 100644 --- a/node/Credential.hpp +++ b/node/Credential.hpp @@ -81,6 +81,7 @@ protected: VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Revocation &credential) const; VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Tag &credential) const; VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const CertificateOfOwnership &credential) const; + VerifyResult _verify(const RuntimeEnvironment *const RR,void *tPtr,const Capability &credential) const; }; } // namespace ZeroTier diff --git a/objects.mk b/objects.mk index fe6aefe65..2bc708d81 100644 --- a/objects.mk +++ b/objects.mk @@ -1,7 +1,6 @@ CORE_OBJS=\ node/AES.o \ node/C25519.o \ - node/Capability.o \ node/Credential.o \ node/ECC384.o \ node/Identity.o \