From 150850b80012f852521c9935145cf966946334d5 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 4 Jul 2013 16:56:19 -0400 Subject: New git repository for release - version 0.2.0 tagged --- node/Pack.cpp | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 node/Pack.cpp (limited to 'node/Pack.cpp') diff --git a/node/Pack.cpp b/node/Pack.cpp new file mode 100644 index 00000000..8bac1300 --- /dev/null +++ b/node/Pack.cpp @@ -0,0 +1,159 @@ +/* + * ZeroTier One - Global Peer to Peer Ethernet + * Copyright (C) 2012-2013 ZeroTier Networks LLC + * + * 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 . + * + * -- + * + * ZeroTier may be used and distributed under the terms of the GPLv3, which + * are available at: http://www.gnu.org/licenses/gpl-3.0.html + * + * If you would like to embed ZeroTier into a commercial application or + * redistribute it in a modified binary form, please contact ZeroTier Networks + * LLC. Start here: http://www.zerotier.com/ + */ + +#include +#include +#include +#include "Pack.hpp" +#include "BlobArray.hpp" +#include "Utils.hpp" + +#include + +namespace ZeroTier { + +std::vector Pack::getAll() const +{ + std::vector v; + for(std::map::const_iterator e=_entries.begin();e!=_entries.end();++e) + v.push_back(&(e->second)); + return v; +} + +const Pack::Entry *Pack::get(const std::string &name) const +{ + std::map::const_iterator e(_entries.find(name)); + return ((e == _entries.end()) ? (const Entry *)0 : &(e->second)); +} + +const Pack::Entry *Pack::put(const std::string &name,const std::string &content) +{ + SHA256_CTX sha; + + Pack::Entry &e = _entries[name]; + e.name = name; + e.content = content; + + SHA256_Init(&sha); + SHA256_Update(&sha,content.data(),content.length()); + SHA256_Final(e.sha256,&sha); + + e.signedBy.zero(); + e.signature.assign((const char *)0,0); + + return &e; +} + +void Pack::clear() +{ + _entries.clear(); +} + +std::string Pack::serialize() const +{ + BlobArray archive; + for(std::map::const_iterator e=_entries.begin();e!=_entries.end();++e) { + BlobArray entry; + entry.push_back(e->second.name); + entry.push_back(e->second.content); + entry.push_back(std::string((const char *)e->second.sha256,sizeof(e->second.sha256))); + entry.push_back(std::string((const char *)e->second.signedBy.data(),e->second.signedBy.size())); + entry.push_back(e->second.signature); + archive.push_back(entry.serialize()); + } + + std::string ser(archive.serialize()); + std::string comp; + Utils::compress(ser.begin(),ser.end(),Utils::StringAppendOutput(comp)); + return comp; +} + +bool Pack::deserialize(const void *sd,unsigned int sdlen) +{ + unsigned char dig[32]; + SHA256_CTX sha; + + std::string decomp; + if (!Utils::decompress(((const char *)sd),((const char *)sd) + sdlen,Utils::StringAppendOutput(decomp))) + return false; + + BlobArray archive; + archive.deserialize(decomp.data(),decomp.length()); + clear(); + for(BlobArray::const_iterator i=archive.begin();i!=archive.end();++i) { + BlobArray entry; + entry.deserialize(i->data(),i->length()); + + if (entry.size() != 5) return false; + if (entry[2].length() != 32) return false; // SHA-256 + if (entry[3].length() != ZT_ADDRESS_LENGTH) return false; // Address + + Pack::Entry &e = _entries[entry[0]]; + e.name = entry[0]; + e.content = entry[1]; + + SHA256_Init(&sha); + SHA256_Update(&sha,e.content.data(),e.content.length()); + SHA256_Final(dig,&sha); + if (memcmp(dig,entry[2].data(),32)) return false; // integrity check failed + memcpy(e.sha256,dig,32); + + if (entry[3].length() == ZT_ADDRESS_LENGTH) + e.signedBy = entry[3].data(); + else e.signedBy.zero(); + e.signature = entry[4]; + } + return true; +} + +bool Pack::signAll(const Identity &id) +{ + for(std::map::iterator e=_entries.begin();e!=_entries.end();++e) { + e->second.signedBy = id.address(); + e->second.signature = id.sign(e->second.sha256); + if (!e->second.signature.length()) + return false; + } + return true; +} + +std::vector Pack::verifyAll(const Identity &id,bool mandatory) const +{ + std::vector bad; + for(std::map::const_iterator e=_entries.begin();e!=_entries.end();++e) { + if ((e->second.signedBy)&&(e->second.signature.length())) { + if (id.address() != e->second.signedBy) + bad.push_back(&(e->second)); + else if (!id.verifySignature(e->second.sha256,e->second.signature.data(),e->second.signature.length())) + bad.push_back(&(e->second)); + } else if (mandatory) + bad.push_back(&(e->second)); + } + return bad; +} + +} // namespace ZeroTier -- cgit v1.2.3