diff options
Diffstat (limited to 'node/CertificateOfMembership.cpp')
-rw-r--r-- | node/CertificateOfMembership.cpp | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/node/CertificateOfMembership.cpp b/node/CertificateOfMembership.cpp index 55537fd9..8184ce99 100644 --- a/node/CertificateOfMembership.cpp +++ b/node/CertificateOfMembership.cpp @@ -1,6 +1,6 @@ /* * ZeroTier One - Network Virtualization Everywhere - * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * Copyright (C) 2011-2018 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 @@ -14,9 +14,22 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * -- + * + * 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 "CertificateOfMembership.hpp" +#include "RuntimeEnvironment.hpp" +#include "Topology.hpp" +#include "Switch.hpp" +#include "Network.hpp" +#include "Node.hpp" namespace ZeroTier { @@ -45,6 +58,7 @@ void CertificateOfMembership::setQualifier(uint64_t id,uint64_t value,uint64_t m std::string CertificateOfMembership::toString() const { + char tmp[ZT_NETWORK_COM_MAX_QUALIFIERS * 32]; std::string s; s.append("1:"); // COM_UINT64_ED25519 @@ -57,7 +71,7 @@ std::string CertificateOfMembership::toString() const buf[ptr++] = Utils::hton(_qualifiers[i].value); buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); } - s.append(Utils::hex(buf,ptr * sizeof(uint64_t))); + s.append(Utils::hex(buf,ptr * sizeof(uint64_t),tmp)); delete [] buf; } catch ( ... ) { delete [] buf; @@ -66,11 +80,11 @@ std::string CertificateOfMembership::toString() const s.push_back(':'); - s.append(_signedBy.toString()); + s.append(_signedBy.toString(tmp)); if (_signedBy) { s.push_back(':'); - s.append(Utils::hex(_signature.data,(unsigned int)_signature.size())); + s.append(Utils::hex(_signature.data,ZT_C25519_SIGNATURE_LEN,tmp)); } return s; @@ -80,7 +94,7 @@ void CertificateOfMembership::fromString(const char *s) { _qualifierCount = 0; _signedBy.zero(); - memset(_signature.data,0,_signature.size()); + memset(_signature.data,0,ZT_C25519_SIGNATURE_LEN); if (!*s) return; @@ -131,7 +145,7 @@ void CertificateOfMembership::fromString(const char *s) colonAt = 0; while ((s[colonAt])&&(s[colonAt] != ':')) ++colonAt; if (colonAt) { - if (Utils::unhex(s,colonAt,_signature.data,(unsigned int)_signature.size()) != _signature.size()) + if (Utils::unhex(s,colonAt,_signature.data,ZT_C25519_SIGNATURE_LEN) != ZT_C25519_SIGNATURE_LEN) _signedBy.zero(); } else { _signedBy.zero(); @@ -152,6 +166,9 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) c unsigned int myidx = 0; unsigned int otheridx = 0; + if ((_qualifierCount == 0)||(other._qualifierCount == 0)) + return false; + while (myidx < _qualifierCount) { // Fail if we're at the end of other, since this means the field is // missing. @@ -182,7 +199,7 @@ bool CertificateOfMembership::agreesWith(const CertificateOfMembership &other) c bool CertificateOfMembership::sign(const Identity &with) { - uint64_t *const buf = new uint64_t[_qualifierCount * 3]; + uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; unsigned int ptr = 0; for(unsigned int i=0;i<_qualifierCount;++i) { buf[ptr++] = Utils::hton(_qualifiers[i].id); @@ -193,38 +210,32 @@ bool CertificateOfMembership::sign(const Identity &with) try { _signature = with.sign(buf,ptr * sizeof(uint64_t)); _signedBy = with.address(); - delete [] buf; return true; } catch ( ... ) { _signedBy.zero(); - delete [] buf; return false; } } -bool CertificateOfMembership::verify(const Identity &id) const +int CertificateOfMembership::verify(const RuntimeEnvironment *RR,void *tPtr) const { - if (!_signedBy) - return false; - if (id.address() != _signedBy) - return false; + if ((!_signedBy)||(_signedBy != Network::controllerFor(networkId()))||(_qualifierCount > ZT_NETWORK_COM_MAX_QUALIFIERS)) + return -1; - uint64_t *const buf = new uint64_t[_qualifierCount * 3]; + const Identity id(RR->topology->getIdentity(tPtr,_signedBy)); + if (!id) { + RR->sw->requestWhois(tPtr,RR->node->now(),_signedBy); + return 1; + } + + uint64_t buf[ZT_NETWORK_COM_MAX_QUALIFIERS * 3]; unsigned int ptr = 0; for(unsigned int i=0;i<_qualifierCount;++i) { buf[ptr++] = Utils::hton(_qualifiers[i].id); buf[ptr++] = Utils::hton(_qualifiers[i].value); buf[ptr++] = Utils::hton(_qualifiers[i].maxDelta); } - - bool valid = false; - try { - valid = id.verify(buf,ptr * sizeof(uint64_t),_signature); - delete [] buf; - } catch ( ... ) { - delete [] buf; - } - return valid; + return (id.verify(buf,ptr * sizeof(uint64_t),_signature) ? 0 : -1); } } // namespace ZeroTier |