summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2014-08-08 12:46:00 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2014-08-08 12:46:00 -0400
commit673aab5ba24acf91961972b71ae2b92f5ffe4b83 (patch)
tree0b179efbaf6061156761b83036eb922be9956705
parent77457cbff14546a6b6173a46c0486767dab60847 (diff)
downloadinfinitytier-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/
-rw-r--r--node/Dictionary.cpp24
-rw-r--r--node/Dictionary.hpp13
-rw-r--r--root-topology/Makefile12
-rw-r--r--root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c28
-rw-r--r--root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.dict4
-rw-r--r--root-topology/mktopology.cpp6
6 files changed, 54 insertions, 33 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);
diff --git a/node/Dictionary.hpp b/node/Dictionary.hpp
index 31930eff..22eb8a7e 100644
--- a/node/Dictionary.hpp
+++ b/node/Dictionary.hpp
@@ -51,8 +51,7 @@ class Identity;
* human-readable if the keys and values in the dictionary are also
* human-readable. Otherwise it might contain unprintable characters.
*
- * Keys beginning with "~!" are reserved for signatures and are ignored
- * during the signature process.
+ * Keys beginning with "~!" are reserved for signature data fields.
*
* Note: the signature code depends on std::map<> being sorted, but no
* other code does. So if the underlying data structure is ever swapped
@@ -66,13 +65,14 @@ public:
/**
* @param s String-serialized dictionary
+ * @param maxlen Maximum length of buffer
*/
- Dictionary(const char *s) { fromString(s); }
+ Dictionary(const char *s,unsigned int maxlen) { fromString(s,maxlen); }
/**
* @param s String-serialized dictionary
*/
- Dictionary(const std::string &s) { fromString(s.c_str()); }
+ Dictionary(const std::string &s) { fromString(s.c_str(),(unsigned int)s.length()); }
/**
* Get a key, throwing an exception if it is not present
@@ -130,9 +130,10 @@ public:
* Clear and initialize from a string
*
* @param s String-serialized dictionary
+ * @param maxlen Maximum length of string buffer
*/
- void fromString(const char *s);
- inline void fromString(const std::string &s) { fromString(s.c_str()); }
+ void fromString(const char *s,unsigned int maxlen);
+ inline void fromString(const std::string &s) { fromString(s.c_str(),(unsigned int)s.length()); }
/**
* @return True if this dictionary is cryptographically signed
diff --git a/root-topology/Makefile b/root-topology/Makefile
index 4c256a50..58226fd0 100644
--- a/root-topology/Makefile
+++ b/root-topology/Makefile
@@ -2,16 +2,16 @@ all: FORCE
g++ -o mktopology mktopology.cpp ../node/Utils.cpp ../node/Identity.cpp ../node/C25519.cpp ../node/Salsa20.cpp ../node/Dictionary.cpp ../node/SHA512.cpp
gcc -o bin2c bin2c.c
-official: all
- rm -f root_topology.out
- ./mktopology >root_topology.out
- ./bin2c ZT_DEFAULT_ROOT_TOPOLOGY < root_topology.out > ZT_DEFAULT_ROOT_TOPOLOGY.c
+official: FORCE
+ rm -f ZT_DEFAULT_ROOT_TOPOLOGY.dict
+ ./mktopology >ZT_DEFAULT_ROOT_TOPOLOGY.dict
+ ./bin2c ZT_DEFAULT_ROOT_TOPOLOGY < ZT_DEFAULT_ROOT_TOPOLOGY.dict > ZT_DEFAULT_ROOT_TOPOLOGY.c
ls -l ZT_DEFAULT_ROOT_TOPOLOGY.c
clean:
- rm -f *.o mktopology bin2c root_topology.out
+ rm -f *.o mktopology bin2c
realclean: clean
- rm -f ZT_DEFAULT_ROOT_TOPOLOGY.c
+ rm -f ZT_DEFAULT_ROOT_TOPOLOGY.c ZT_DEFAULT_ROOT_TOPOLOGY.dict
FORCE:
diff --git a/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c b/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c
index 0d313120..9a5be2c2 100644
--- a/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c
+++ b/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.c
@@ -71,19 +71,19 @@ static unsigned char ZT_DEFAULT_ROOT_TOPOLOGY[] = {
0x5c, 0x5c, 0x6e, 0x64, 0x65, 0x73, 0x63, 0x5c, 0x5c, 0x5c, 0x3d, 0x53, 0x69, 0x6e, 0x67, 0x61,
0x70, 0x6f, 0x72, 0x65, 0x5c, 0x5c, 0x6e, 0x68, 0x6e, 0x5c, 0x5c, 0x5c, 0x3d, 0x6d, 0x69, 0x2d,
0x67, 0x6f, 0x2e, 0x7a, 0x65, 0x72, 0x6f, 0x74, 0x69, 0x65, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x5c,
- 0x5c, 0x6e, 0x5c, 0x6e, 0x0a, 0x7e, 0x21, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x3d, 0x64,
- 0x37, 0x35, 0x32, 0x38, 0x30, 0x66, 0x30, 0x31, 0x39, 0x39, 0x32, 0x63, 0x32, 0x36, 0x38, 0x36,
- 0x66, 0x38, 0x34, 0x31, 0x65, 0x64, 0x32, 0x62, 0x39, 0x37, 0x63, 0x62, 0x34, 0x38, 0x64, 0x63,
- 0x64, 0x66, 0x35, 0x37, 0x35, 0x37, 0x64, 0x66, 0x31, 0x37, 0x37, 0x36, 0x34, 0x66, 0x33, 0x31,
- 0x33, 0x37, 0x30, 0x64, 0x66, 0x63, 0x37, 0x36, 0x64, 0x30, 0x35, 0x63, 0x61, 0x31, 0x35, 0x32,
- 0x39, 0x35, 0x62, 0x63, 0x33, 0x62, 0x62, 0x32, 0x64, 0x61, 0x64, 0x63, 0x63, 0x65, 0x63, 0x38,
- 0x61, 0x63, 0x36, 0x30, 0x37, 0x61, 0x31, 0x64, 0x34, 0x35, 0x33, 0x38, 0x30, 0x39, 0x64, 0x38,
- 0x62, 0x65, 0x62, 0x66, 0x38, 0x64, 0x31, 0x31, 0x63, 0x61, 0x30, 0x37, 0x63, 0x65, 0x66, 0x66,
- 0x35, 0x64, 0x62, 0x66, 0x33, 0x31, 0x32, 0x30, 0x36, 0x64, 0x66, 0x38, 0x31, 0x30, 0x35, 0x64,
- 0x63, 0x34, 0x39, 0x38, 0x32, 0x62, 0x65, 0x64, 0x30, 0x31, 0x30, 0x35, 0x37, 0x66, 0x63, 0x32,
- 0x66, 0x65, 0x64, 0x64, 0x34, 0x39, 0x38, 0x64, 0x35, 0x64, 0x63, 0x61, 0x63, 0x30, 0x37, 0x34,
- 0x62, 0x32, 0x65, 0x30, 0x36, 0x37, 0x30, 0x62, 0x66, 0x38, 0x33, 0x36, 0x37, 0x32, 0x39, 0x37,
- 0x36, 0x30, 0x61, 0x39, 0x64, 0x33, 0x62, 0x37, 0x37, 0x64, 0x33, 0x61, 0x62, 0x63, 0x39, 0x0a,
+ 0x5c, 0x6e, 0x5c, 0x6e, 0x0a, 0x7e, 0x21, 0x65, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x3d, 0x39,
+ 0x62, 0x35, 0x66, 0x62, 0x35, 0x63, 0x33, 0x30, 0x64, 0x62, 0x39, 0x32, 0x31, 0x34, 0x63, 0x39,
+ 0x63, 0x61, 0x65, 0x32, 0x62, 0x38, 0x36, 0x64, 0x31, 0x35, 0x39, 0x63, 0x32, 0x62, 0x65, 0x66,
+ 0x66, 0x61, 0x31, 0x61, 0x66, 0x38, 0x62, 0x61, 0x31, 0x66, 0x33, 0x32, 0x39, 0x66, 0x33, 0x38,
+ 0x37, 0x33, 0x33, 0x61, 0x33, 0x63, 0x66, 0x37, 0x34, 0x34, 0x35, 0x65, 0x64, 0x33, 0x65, 0x33,
+ 0x32, 0x31, 0x63, 0x39, 0x36, 0x33, 0x36, 0x64, 0x36, 0x34, 0x61, 0x31, 0x63, 0x34, 0x36, 0x64,
+ 0x62, 0x38, 0x37, 0x37, 0x31, 0x64, 0x63, 0x33, 0x66, 0x37, 0x32, 0x36, 0x66, 0x31, 0x34, 0x63,
+ 0x31, 0x65, 0x65, 0x62, 0x63, 0x31, 0x65, 0x32, 0x36, 0x64, 0x34, 0x36, 0x62, 0x33, 0x65, 0x33,
+ 0x63, 0x36, 0x39, 0x38, 0x61, 0x32, 0x66, 0x63, 0x34, 0x37, 0x31, 0x39, 0x61, 0x30, 0x30, 0x32,
+ 0x36, 0x63, 0x35, 0x64, 0x66, 0x30, 0x64, 0x32, 0x64, 0x38, 0x31, 0x38, 0x33, 0x33, 0x39, 0x32,
+ 0x30, 0x34, 0x61, 0x64, 0x30, 0x34, 0x62, 0x36, 0x34, 0x32, 0x30, 0x61, 0x36, 0x64, 0x61, 0x34,
+ 0x38, 0x36, 0x37, 0x63, 0x38, 0x30, 0x63, 0x37, 0x31, 0x64, 0x39, 0x63, 0x38, 0x30, 0x33, 0x63,
+ 0x34, 0x38, 0x37, 0x61, 0x65, 0x63, 0x30, 0x66, 0x64, 0x66, 0x33, 0x32, 0x31, 0x61, 0x34, 0x0a,
0x7e, 0x21, 0x73, 0x69, 0x67, 0x69, 0x64, 0x3d, 0x37, 0x37, 0x37, 0x39, 0x32, 0x62, 0x31, 0x63,
0x30, 0x32, 0x3a, 0x30, 0x3a, 0x62, 0x35, 0x63, 0x33, 0x36, 0x31, 0x65, 0x38, 0x65, 0x39, 0x63,
0x32, 0x31, 0x35, 0x34, 0x65, 0x38, 0x32, 0x63, 0x33, 0x65, 0x39, 0x30, 0x32, 0x66, 0x64, 0x66,
@@ -94,6 +94,6 @@ static unsigned char ZT_DEFAULT_ROOT_TOPOLOGY[] = {
0x34, 0x32, 0x38, 0x33, 0x37, 0x33, 0x35, 0x38, 0x32, 0x64, 0x61, 0x33, 0x64, 0x30, 0x61, 0x39,
0x61, 0x31, 0x34, 0x62, 0x33, 0x36, 0x65, 0x34, 0x35, 0x34, 0x36, 0x63, 0x33, 0x31, 0x37, 0x65,
0x38, 0x31, 0x31, 0x65, 0x36, 0x0a, 0x7e, 0x21, 0x73, 0x69, 0x67, 0x74, 0x73, 0x3d, 0x31, 0x34,
- 0x37, 0x62, 0x32, 0x66, 0x62, 0x65, 0x66, 0x38, 0x35, 0x0a
+ 0x37, 0x62, 0x36, 0x38, 0x32, 0x31, 0x65, 0x66, 0x62, 0x0a
};
#define ZT_DEFAULT_ROOT_TOPOLOGY_LEN 1530
diff --git a/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.dict b/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.dict
new file mode 100644
index 00000000..20a98108
--- /dev/null
+++ b/root-topology/ZT_DEFAULT_ROOT_TOPOLOGY.dict
@@ -0,0 +1,4 @@
+supernodes=36f63d6574\=id\\\=36f63d6574:0:67a776487a1a99b32f413329f2b67c43fbf6152e42c6b66e89043e69d93e48314c7d709b58a83016bd2612dd89400b856e18c553da94892f7d3ca16bf2c92c24\\nudp\\\=198.211.127.172/9993\\ntcp\\\=198.211.127.172/443\\ndesc\\\=Amsterdam, Netherlands\\ndns\\\=shub-niggurath.zerotier.com\\n\n7e19876aba\=id\\\=7e19876aba:0:2a6e2b2318930f60eb097f70d0f4b028b2cd6d3d0c63c014b9039ff35390e41181f216fb2e6fa8d95c1ee9667156411905c3dccfea78d8c6dfafba688170b3fa\\nudp\\\=198.199.97.220/9993\\ntcp\\\=198.199.97.220/443\\ndesc\\\=San Francisco, California, USA\\ndns\\\=nyarlathotep.zerotier.com\\n\n8acf059fe3\=id\\\=8acf059fe3:0:482f6ee5dfe902319b419de5bdc765209c0ecda38c4d6e4fcf0d33658398b4527dcd22f93112fb9befd02fd78bf7261b333fc105d192a623ca9e50fc60b374a5\\nudp\\\=162.243.77.111/9993\\ntcp\\\=162.243.77.111/443\\ndesc\\\=New York, New York, USA\\ndns\\\=cthulhu.zerotier.com\\n\n9d219039f3\=id\\\=9d219039f3:0:01f0922a98e3b34ebcbff333269dc265d7a020aab69d72be4d4acc9c8c9294785771256cd1d942a90d1bd1d2dca3ea84ef7d85afe6611fb43ff0b74126d90a6e\\nudp\\\=128.199.197.217/9993\\ntcp\\\=128.199.197.217/443\\ndesc\\\=Singapore\\nhn\\\=mi-go.zerotier.com\\n\n
+~!ed25519=9b5fb5c30db9214c9cae2b86d159c2beffa1af8ba1f329f38733a3cf7445ed3e321c9636d64a1c46db8771dc3f726f14c1eebc1e26d46b3e3c698a2fc4719a0026c5df0d2d818339204ad04b6420a6da4867c80c71d9c803c487aec0fdf321a4
+~!sigid=77792b1c02:0:b5c361e8e9c2154e82c3e902fdfc337468b092a7c4d8dc685c37eb10ee4f3c17cc0bb1d024167e8cb0824d12263428373582da3d0a9a14b36e4546c317e811e6
+~!sigts=147b6821efb
diff --git a/root-topology/mktopology.cpp b/root-topology/mktopology.cpp
index 516fd71b..d6a2be3c 100644
--- a/root-topology/mktopology.cpp
+++ b/root-topology/mktopology.cpp
@@ -43,6 +43,12 @@ int main(int argc,char **argv)
return 1;
}
+ Dictionary test(topology.toString());
+ if (!test.verify(topologyAuthority)) {
+ std::cerr << "Test verification of signed dictionary failed!" << std::endl;
+ return 1;
+ }
+
std::cout << topology.toString();
return 0;
}