Locator work

This commit is contained in:
Adam Ierymenko 2019-08-08 23:23:16 -05:00
parent beebca98fe
commit 652c7e8f37
No known key found for this signature in database
GPG key ID: 1657198823E52A61
3 changed files with 62 additions and 14 deletions

View file

@ -627,6 +627,9 @@
*/
#define ZT_THREAD_MIN_STACK_SIZE 1048576
#define ZT_CRYPTO_ALG_C25519 0
#define ZT_CRYPTO_ALG_P384 1
// Exceptions thrown in core ZT code
#define ZT_EXCEPTION_OUT_OF_BOUNDS 100
#define ZT_EXCEPTION_OUT_OF_MEMORY 101

View file

@ -55,10 +55,13 @@ namespace ZeroTier {
class Identity
{
public:
/**
* Identity type -- numeric values of these enums are protocol constants
*/
enum Type
{
C25519 = 0, // Curve25519 and Ed25519 (1.0 and 2.0, default)
P384 = 1 // NIST P-384 ECDH and ECDSA (2.0+ only)
C25519 = ZT_CRYPTO_ALG_C25519, // Type 0 -- Curve25519 and Ed25519 (1.0 and 2.0, default)
P384 = ZT_CRYPTO_ALG_P384 // Type 1 -- NIST P-384 ECDH and ECDSA (2.0+ only)
};
Identity() { memset(reinterpret_cast<void *>(this),0,sizeof(Identity)); }

View file

@ -33,6 +33,7 @@
#include "Utils.hpp"
#include "Buffer.hpp"
#include "SHA512.hpp"
#include "Str.hpp"
#include <algorithm>
#include <vector>
@ -68,6 +69,7 @@ public:
if (_virtual.size() < ZT_LOCATOR_MAX_VIRTUAL_ADDRESSES)
_virtual.push_back(zt);
}
inline void finish(const Identity &id,const int64_t ts)
{
_ts = ts;
@ -103,35 +105,75 @@ public:
{
if ((_signatureLength == 0)||(_signatureLength > sizeof(_signature)))
return false;
Buffer<16384> *tmp;
Buffer<65536> *tmp = nullptr;
try {
tmp = new Buffer<16384>(); // 16384 would be huge
tmp = new Buffer<65536>();
serialize(*tmp,true);
const bool ok = (_signedBy) ? _signedBy.verify(tmp->data(),tmp->size(),_signature,_signatureLength) : _id.verify(tmp->data(),tmp->size(),_signature,_signatureLength);
delete tmp;
return ok;
} catch ( ... ) {
delete tmp;
if (tmp) delete tmp;
return false;
}
}
inline std::pair< Str,std::vector<Str> > makeTxtRecords(const uint8_t p384SigningKeyPrivate[ZT_ECC384_PUBLIC_KEY_SIZE],const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
inline std::vector<Str> makeTxtRecords(const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE],const uint8_t p384SigningKeyPrivate[ZT_ECC384_PUBLIC_KEY_SIZE])
{
uint8_t s384[48],dnsSig[ZT_ECC384_SIGNATURE_SIZE];
char dnsSigTxtF0[64],dnsSigTxtF1[64],dnsSigTxtF2[64];
char enc[256];
Buffer<16384> *tmp = new Buffer<16384>(); // 16384 would be huge
Buffer<65536> *const tmp = new Buffer<65536>();
serialize(*tmp,false);
SHA384(s384,tmp->data(),tmp->size());
ECC384ECDSASign(p384SigningKeyPrivate,s384,dnsSig);
tmp->append(dnsSig,ZT_ECC384_SIGNATURE_SIZE);
Utils::b32e(dnsSig,32,dnsSigTxtF0,sizeof(dnsSigTxtF0));
Utils::b32e(dnsSig+32,32,dnsSigTxtF0,sizeof(dnsSigTxtF0));
Utils::b32e(dnsSig+64,32,dnsSigTxtF0,sizeof(dnsSigTxtF0));
Str name;
// Blob must be broken into multiple TXT records that must remain sortable so they are prefixed by a hex value.
// 186-byte chunks yield 248-byte base64 chunks which leaves some margin below the limit of 255.
std::vector<Str> txtRecords;
for(unsigned int p=0;p<tmp->size();p+=186) {
unsigned int rem = tmp->size() - p;
if (rem > 186) rem = 186;
Utils::b64e(((const uint8_t *)tmp->data()) + p,rem,enc,sizeof(enc));
txtRecords.push_back(Str());
txtRecords.back() << Utils::HEXCHARS[(p >> 4) & 0xf] << Utils::HEXCHARS[p & 0xf] << enc;
}
delete tmp;
return txtRecords;
}
template<typename I>
inline bool decodeTxtRecords(I start,I end,const uint8_t p384SigningKeyPublic[ZT_ECC384_PUBLIC_KEY_SIZE])
{
uint8_t dec[256],s384[48];
Buffer<65536> *tmp = nullptr;
try {
tmp = new Buffer<65536>();
while (start != end) {
tmp->append(dec,Utils::b64d(start->c_str(),dec,sizeof(dec)));
++start;
}
if (tmp->size() <= ZT_ECC384_SIGNATURE_SIZE) {
delete tmp;
return false;
}
SHA384(s384,tmp->data(),tmp->size() - ZT_ECC384_SIGNATURE_SIZE);
if (!ECC384ECDSAVerify(p384SigningKeyPublic,s384,((const uint8_t *)tmp->data()) + (tmp->size() - ZT_ECC384_SIGNATURE_SIZE))) {
delete tmp;
return false;
}
deserialize(*tmp,0);
delete tmp;
return verify();
} catch ( ... ) {
if (tmp) delete tmp;
return false;
}
}
template<unsigned int C>
@ -139,11 +181,11 @@ public:
{
if (forSign) b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
b.append((uint8_t)0; // version/flags, currently 0
b.append((uint8_t)0); // version/flags, currently 0
b.append((uint64_t)_ts);
_id.serialise(b,false);
if (_signedBy) {
b.append((uint8_t)1); // number of signers
b.append((uint8_t)1); // number of signers, current max is 1
_signedBy.serialize(b,false);
} else {
b.append((uint8_t)0); // signer is _id