mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-06-06 20:43:44 +02:00
Add tests for identity marshal/unmarshal and fix an issue found.
This commit is contained in:
parent
ed8271530f
commit
6262374205
4 changed files with 49 additions and 25 deletions
|
@ -17,6 +17,8 @@
|
||||||
#include "Constants.hpp"
|
#include "Constants.hpp"
|
||||||
#include "TriviallyCopyable.hpp"
|
#include "TriviallyCopyable.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace ZeroTier {
|
namespace ZeroTier {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,12 +64,12 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZT_ALWAYS_INLINE bool operator==(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) == 0; }
|
ZT_ALWAYS_INLINE bool operator==(const Fingerprint &h) const noexcept { return std::equal(_h,_h + (384 / (sizeof(unsigned long) * 8)),h._h); }
|
||||||
ZT_ALWAYS_INLINE bool operator!=(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) != 0; }
|
ZT_ALWAYS_INLINE bool operator!=(const Fingerprint &h) const noexcept { return !(*this == h); }
|
||||||
ZT_ALWAYS_INLINE bool operator<(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) < 0; }
|
ZT_ALWAYS_INLINE bool operator<(const Fingerprint &h) const noexcept { return std::lexicographical_compare(_h,_h + (384 / (sizeof(unsigned long) * 8)),h._h,h._h + (384 / (sizeof(unsigned long) * 8))); }
|
||||||
ZT_ALWAYS_INLINE bool operator>(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) > 0; }
|
ZT_ALWAYS_INLINE bool operator>(const Fingerprint &h) const noexcept { return (h < *this); }
|
||||||
ZT_ALWAYS_INLINE bool operator<=(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) <= 0; }
|
ZT_ALWAYS_INLINE bool operator<=(const Fingerprint &h) const noexcept { return !(h < *this); }
|
||||||
ZT_ALWAYS_INLINE bool operator>=(const Fingerprint &h) const noexcept { return memcmp(_h,h._h,48) >= 0; }
|
ZT_ALWAYS_INLINE bool operator>=(const Fingerprint &h) const noexcept { return !(*this < h); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned long _h[384 / (sizeof(unsigned long) * 8)];
|
unsigned long _h[384 / (sizeof(unsigned long) * 8)];
|
||||||
|
|
|
@ -414,9 +414,7 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
|
||||||
switch(_type) {
|
switch(_type) {
|
||||||
case C25519:
|
case C25519:
|
||||||
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
|
data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
|
||||||
|
|
||||||
memcpy(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
|
memcpy(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519,ZT_C25519_PUBLIC_KEY_LEN);
|
||||||
|
|
||||||
if ((includePrivate)&&(_hasPrivate)) {
|
if ((includePrivate)&&(_hasPrivate)) {
|
||||||
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
|
data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN] = ZT_C25519_PRIVATE_KEY_LEN;
|
||||||
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
|
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,_priv.c25519,ZT_C25519_PRIVATE_KEY_LEN);
|
||||||
|
@ -428,9 +426,7 @@ int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool incl
|
||||||
|
|
||||||
case P384:
|
case P384:
|
||||||
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
|
data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
|
||||||
|
|
||||||
memcpy(data + ZT_ADDRESS_LENGTH + 1,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
|
memcpy(data + ZT_ADDRESS_LENGTH + 1,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
|
||||||
|
|
||||||
if ((includePrivate)&&(_hasPrivate)) {
|
if ((includePrivate)&&(_hasPrivate)) {
|
||||||
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
|
data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
|
||||||
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
|
memcpy(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
|
||||||
|
@ -451,6 +447,7 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
|
||||||
|
|
||||||
if (len < (ZT_ADDRESS_LENGTH + 1))
|
if (len < (ZT_ADDRESS_LENGTH + 1))
|
||||||
return -1;
|
return -1;
|
||||||
|
_address.setTo(data);
|
||||||
|
|
||||||
unsigned int privlen;
|
unsigned int privlen;
|
||||||
switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
|
switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
|
||||||
|
@ -460,21 +457,17 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1,ZT_C25519_PUBLIC_KEY_LEN);
|
memcpy(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1,ZT_C25519_PUBLIC_KEY_LEN);
|
||||||
|
_computeHash();
|
||||||
|
|
||||||
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
|
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN];
|
||||||
if (privlen == ZT_C25519_PRIVATE_KEY_LEN) {
|
if (privlen == ZT_C25519_PRIVATE_KEY_LEN) {
|
||||||
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
|
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
_hasPrivate = true;
|
_hasPrivate = true;
|
||||||
memcpy(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,ZT_C25519_PRIVATE_KEY_LEN);
|
memcpy(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1,ZT_C25519_PRIVATE_KEY_LEN);
|
||||||
|
|
||||||
_computeHash();
|
|
||||||
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
|
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1 + ZT_C25519_PRIVATE_KEY_LEN;
|
||||||
} else if (privlen == 0) {
|
} else if (privlen == 0) {
|
||||||
_hasPrivate = false;
|
_hasPrivate = false;
|
||||||
|
|
||||||
_computeHash();
|
|
||||||
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1;
|
return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_PUBLIC_KEY_LEN + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -484,21 +477,19 @@ int Identity::unmarshal(const uint8_t *data,const int len) noexcept
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
memcpy(&_pub,data + ZT_ADDRESS_LENGTH + 1,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
|
memcpy(&_pub,data + ZT_ADDRESS_LENGTH + 1,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
|
||||||
|
_computeHash();
|
||||||
|
if (_address != Address(_fp.data())) // for v1 we can sanity check this here, but this isn't a full validate
|
||||||
|
return -1;
|
||||||
|
|
||||||
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
|
privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
|
||||||
if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
|
if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
|
||||||
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
|
if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
_hasPrivate = true;
|
_hasPrivate = true;
|
||||||
memcpy(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
|
memcpy(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE);
|
||||||
|
|
||||||
_computeHash();
|
|
||||||
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
|
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
|
||||||
} else if (privlen == 0) {
|
} else if (privlen == 0) {
|
||||||
_hasPrivate = false;
|
_hasPrivate = false;
|
||||||
|
|
||||||
_computeHash();
|
|
||||||
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
|
return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -203,10 +203,7 @@ public:
|
||||||
|
|
||||||
ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _fp.hashCode(); }
|
ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _fp.hashCode(); }
|
||||||
|
|
||||||
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept
|
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept { return ((_address == id._address)&&(_fp == id._fp)); }
|
||||||
{
|
|
||||||
return ((_address == id._address)&&(_type == id._type)&&(memcmp(_fp.data(),id._fp.data(),ZT_SHA384_DIGEST_LEN) == 0));
|
|
||||||
}
|
|
||||||
ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
|
ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
|
||||||
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept
|
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept
|
||||||
{
|
{
|
||||||
|
@ -216,7 +213,7 @@ public:
|
||||||
if ((int)_type < (int)id._type)
|
if ((int)_type < (int)id._type)
|
||||||
return true;
|
return true;
|
||||||
if (_type == id._type)
|
if (_type == id._type)
|
||||||
return memcmp(_fp.data(),id._fp.data(),ZT_SHA384_DIGEST_LEN) < 0;
|
return _fp < id._fp;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -590,6 +590,24 @@ extern "C" const char *ZTT_general()
|
||||||
ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S);
|
||||||
return "Identity test failed: validation of known-good identity";
|
return "Identity test failed: validation of known-good identity";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t idm[ZT_IDENTITY_MARSHAL_SIZE_MAX];
|
||||||
|
int ms = id.marshal(idm,true);
|
||||||
|
if (ms <= 0) {
|
||||||
|
ZT_T_PRINTF("FAILED (v0 marshal)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v0 marshal";
|
||||||
|
}
|
||||||
|
ZT_T_PRINTF("(marshal: %d bytes) ",ms);
|
||||||
|
Identity id2;
|
||||||
|
if (id2.unmarshal(idm,ms) <= 0) {
|
||||||
|
ZT_T_PRINTF("FAILED (v0 unmarshal)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v0 unmarshal";
|
||||||
|
}
|
||||||
|
if (id != id2) {
|
||||||
|
ZT_T_PRINTF("FAILED (v0 unmarshal !=)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v0 unmarshal !=";
|
||||||
|
}
|
||||||
|
|
||||||
if (!id.fromString(IDENTITY_V0_KNOWN_BAD_0)) {
|
if (!id.fromString(IDENTITY_V0_KNOWN_BAD_0)) {
|
||||||
ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S);
|
||||||
return "Identity test failed: parse error";
|
return "Identity test failed: parse error";
|
||||||
|
@ -614,6 +632,22 @@ extern "C" const char *ZTT_general()
|
||||||
ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (validation of known-good identity failed)" ZT_EOL_S);
|
||||||
return "Identity test failed: validation of known-good identity";
|
return "Identity test failed: validation of known-good identity";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ms = id.marshal(idm,true);
|
||||||
|
if (ms <= 0) {
|
||||||
|
ZT_T_PRINTF("FAILED (v1 marshal)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v1 marshal";
|
||||||
|
}
|
||||||
|
ZT_T_PRINTF("(marshal: %d bytes) ",ms);
|
||||||
|
if (id2.unmarshal(idm,ms) <= 0) {
|
||||||
|
ZT_T_PRINTF("FAILED (v1 unmarshal)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v1 unmarshal";
|
||||||
|
}
|
||||||
|
if (id != id2) {
|
||||||
|
ZT_T_PRINTF("FAILED (v1 unmarshal !=)" ZT_EOL_S);
|
||||||
|
return "Identity test failed: v1 unmarshal !=";
|
||||||
|
}
|
||||||
|
|
||||||
if (!id.fromString(IDENTITY_V1_KNOWN_BAD_0)) {
|
if (!id.fromString(IDENTITY_V1_KNOWN_BAD_0)) {
|
||||||
ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S);
|
ZT_T_PRINTF("FAILED (error parsing test identity #2)" ZT_EOL_S);
|
||||||
return "Identity test failed: parse error";
|
return "Identity test failed: parse error";
|
||||||
|
|
Loading…
Add table
Reference in a new issue