diff options
author | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-08-08 12:46:00 -0400 |
---|---|---|
committer | Adam Ierymenko <adam.ierymenko@gmail.com> | 2014-08-08 12:46:00 -0400 |
commit | 673aab5ba24acf91961972b71ae2b92f5ffe4b83 (patch) | |
tree | 0b179efbaf6061156761b83036eb922be9956705 /node/Dictionary.cpp | |
parent | 77457cbff14546a6b6173a46c0486767dab60847 (diff) | |
download | infinitytier-673aab5ba24acf91961972b71ae2b92f5ffe4b83.tar.gz infinitytier-673aab5ba24acf91961972b71ae2b92f5ffe4b83.zip |
Fix an oversight in signed dictionaries: the timestamp and signing identity should themselves be part of the signature. Also include the raw dictionary in addition to the bin2c version in root-topology/
Diffstat (limited to 'node/Dictionary.cpp')
-rw-r--r-- | node/Dictionary.cpp | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/node/Dictionary.cpp b/node/Dictionary.cpp index 0572783b..835cc0c9 100644 --- a/node/Dictionary.cpp +++ b/node/Dictionary.cpp @@ -32,13 +32,14 @@ namespace ZeroTier { -void Dictionary::fromString(const char *s) +void Dictionary::fromString(const char *s,unsigned int maxlen) { clear(); bool escapeState = false; std::string keyBuf; std::string *element = &keyBuf; - while (*s) { + const char *end = s + maxlen; + while ((*s)&&(s < end)) { if (escapeState) { escapeState = false; switch(*s) { @@ -77,16 +78,25 @@ void Dictionary::fromString(const char *s) bool Dictionary::sign(const Identity &id) { try { - std::string buf; - _mkSigBuf(buf); + // Sign identity and timestamp fields too. If there's an existing + // signature, _mkSigBuf() ignores it. char nows[32]; Utils::snprintf(nows,sizeof(nows),"%llx",(unsigned long long)Utils::now()); - C25519::Signature sig(id.sign(buf.data(),buf.length())); - (*this)[ZT_DICTIONARY_SIGNATURE] = Utils::hex(sig.data,sig.size()); (*this)[ZT_DICTIONARY_SIGNATURE_IDENTITY] = id.toString(false); (*this)[ZT_DICTIONARY_SIGNATURE_TIMESTAMP] = nows; + + // Create a blob to hash and sign from fields in sorted order + std::string buf; + _mkSigBuf(buf); + + // Add signature field + C25519::Signature sig(id.sign(buf.data(),(unsigned int)buf.length())); + (*this)[ZT_DICTIONARY_SIGNATURE] = Utils::hex(sig.data,(unsigned int)sig.size()); + return true; } catch ( ... ) { + // Probably means identity has no secret key field + removeSignature(); return false; } } @@ -110,7 +120,7 @@ void Dictionary::_mkSigBuf(std::string &buf) const { unsigned long pairs = 0; for(const_iterator i(begin());i!=end();++i) { - if ((i->first.length() < 2)||( (i->first[0] != '~')&&(i->first[1] != '!') )) { + if (i->first != ZT_DICTIONARY_SIGNATURE) { buf.append(i->first); buf.push_back('='); buf.append(i->second); |