From cba7a5d4d78e214ee607804da4a9e280b61ae352 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 13 Jan 2020 16:35:49 -0800 Subject: [PATCH] Self test is back, wiring up roots again. --- CMakeLists.txt | 6 +++--- go/pkg/zerotier/identity.go | 6 +++--- go/pkg/zerotier/locator.go | 7 +++++++ go/pkg/zerotier/node.go | 10 +++++----- go/pkg/zerotier/path.go | 10 +++++----- go/pkg/zerotier/root.go | 12 +++++++++--- node/Identity.cpp | 1 + node/Locator.hpp | 24 ++++++++++++++++++++++-- selftest.cpp | 30 +++++------------------------- 9 files changed, 60 insertions(+), 46 deletions(-) create mode 100644 go/pkg/zerotier/locator.go diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f1e839a7..0b1d104b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,6 @@ add_custom_command( ) add_custom_target(build_zerotier ALL DEPENDS zerotier) -#add_executable(zerotier-selftest selftest.cpp) -#target_link_libraries(zerotier-selftest ${libs} zt_core zt_osdep) -#target_compile_features(zerotier-selftest PUBLIC cxx_std_11) +add_executable(zerotier-selftest selftest.cpp) +target_link_libraries(zerotier-selftest ${libs} zt_core zt_osdep) +target_compile_features(zerotier-selftest PUBLIC cxx_std_11) diff --git a/go/pkg/zerotier/identity.go b/go/pkg/zerotier/identity.go index d5099fc57..cbccb3699 100644 --- a/go/pkg/zerotier/identity.go +++ b/go/pkg/zerotier/identity.go @@ -51,7 +51,7 @@ func newIdentityFromCIdentity(cid unsafe.Pointer) (*Identity, error) { return nil, ErrInvalidParameter } var idStrBuf [4096]byte - idStr := C.ZT_Identity_toString(cid,(*C.char)(unsafe.Pointer(&idStrBuf[0])),4096,1) + idStr := C.ZT_Identity_toString(cid, (*C.char)(unsafe.Pointer(&idStrBuf[0])), 4096, 1) if uintptr(unsafe.Pointer(idStr)) == 0 { return nil, ErrInternal } @@ -192,7 +192,7 @@ func (id *Identity) Sign(msg []byte) ([]byte, error) { dataP = unsafe.Pointer(&msg[0]) } var sig [96]byte - sigLen := C.ZT_Identity_sign(cid,dataP,C.uint(len(msg)),unsafe.Pointer(&sig[0]),96) + sigLen := C.ZT_Identity_sign(cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), 96) if sigLen <= 0 { return nil, ErrInvalidKey } @@ -218,7 +218,7 @@ func (id *Identity) Verify(msg, sig []byte) bool { if len(msg) > 0 { dataP = unsafe.Pointer(&msg[0]) } - return C.ZT_Identity_verify(cid,dataP,C.uint(len(msg)),unsafe.Pointer(&sig[0]),C.uint(len(sig))) != 0 + return C.ZT_Identity_verify(cid, dataP, C.uint(len(msg)), unsafe.Pointer(&sig[0]), C.uint(len(sig))) != 0 } // MarshalJSON marshals this Identity in its string format (private key is never included) diff --git a/go/pkg/zerotier/locator.go b/go/pkg/zerotier/locator.go new file mode 100644 index 000000000..257513070 --- /dev/null +++ b/go/pkg/zerotier/locator.go @@ -0,0 +1,7 @@ +package zerotier + +type Locator struct { + Timestamp int64 + Endpoints []InetAddress + Bytes []byte +} diff --git a/go/pkg/zerotier/node.go b/go/pkg/zerotier/node.go index dd86e85c2..e83898a16 100644 --- a/go/pkg/zerotier/node.go +++ b/go/pkg/zerotier/node.go @@ -615,11 +615,11 @@ func (n *Node) Peers() []*Peer { a := sockaddrStorageToUDPAddr(&pt.address) if a != nil { p2.Paths = append(p2.Paths, Path{ - IP: a.IP, - Port: a.Port, - LastSend: int64(pt.lastSend), - LastReceive: int64(pt.lastReceive), - TrustedPathID: uint64(pt.trustedPathId), + IP: a.IP, + Port: a.Port, + LastSend: int64(pt.lastSend), + LastReceive: int64(pt.lastReceive), + TrustedPathID: uint64(pt.trustedPathId), }) } } diff --git a/go/pkg/zerotier/path.go b/go/pkg/zerotier/path.go index 116a7cfe9..85479196b 100644 --- a/go/pkg/zerotier/path.go +++ b/go/pkg/zerotier/path.go @@ -17,9 +17,9 @@ import "net" // Path is a path to another peer on the network type Path struct { - IP net.IP `json:"ip"` - Port int `json:"port"` - LastSend int64 `json:"lastSend"` - LastReceive int64 `json:"lastReceive"` - TrustedPathID uint64 `json:"trustedPathID"` + IP net.IP `json:"ip"` + Port int `json:"port"` + LastSend int64 `json:"lastSend"` + LastReceive int64 `json:"lastReceive"` + TrustedPathID uint64 `json:"trustedPathID"` } diff --git a/go/pkg/zerotier/root.go b/go/pkg/zerotier/root.go index b9196b686..0b465570a 100644 --- a/go/pkg/zerotier/root.go +++ b/go/pkg/zerotier/root.go @@ -1,8 +1,14 @@ package zerotier -// Root is a root server with one or more permanent IPs. +// Root nodes are long-lived nodes at stable physical addresses that can help locate other nodes. type Root struct { + // Identity is this root's address and public key(s). Identity Identity - DNSName string - PhysicalAddresses []InetAddress + + // Locator describes the endpoints where this root may be found. + Locator Locator + + // URL is an optional URL where the latest Locator may be fetched. + // This is one method of locator update, while in-band mechanisms are the other. + URL string } diff --git a/node/Identity.cpp b/node/Identity.cpp index ddcd5c948..274f8c955 100644 --- a/node/Identity.cpp +++ b/node/Identity.cpp @@ -124,6 +124,7 @@ bool Identity::locallyValidate() const SHA384(digest,&_pub,ZT_C25519_PUBLIC_KEY_LEN + ZT_ECC384_PUBLIC_KEY_SIZE); if (!ECC384ECDSAVerify(_pub.p384,digest,_pub.p384s)) return false; + break; default: return false; } diff --git a/node/Locator.hpp b/node/Locator.hpp index e18399884..aa54cd5c0 100644 --- a/node/Locator.hpp +++ b/node/Locator.hpp @@ -53,6 +53,26 @@ public: */ ZT_ALWAYS_INLINE bool isSigned() const { return (_signatureLength > 0); } + /** + * @return Length of signature in bytes or 0 if none + */ + ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; } + + /** + * @return Pointer to signature bytes + */ + ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; } + + /** + * @return Number of endpoints in this locator + */ + ZT_ALWAYS_INLINE unsigned int endpointCount() const { return _endpointCount; } + + /** + * @return Pointer to array of endpoints + */ + ZT_ALWAYS_INLINE const Endpoint *endpoints() const { return _at; } + /** * Add an endpoint to this locator * @@ -92,8 +112,8 @@ public: explicit ZT_ALWAYS_INLINE operator bool() const { return (_ts != 0); } static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_LOCATOR_MARSHAL_SIZE_MAX; } - int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature = false) const; - int unmarshal(const uint8_t *restrict data,const int len); + int marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],bool excludeSignature = false) const; + int unmarshal(const uint8_t *restrict data,int len); private: int64_t _ts; diff --git a/selftest.cpp b/selftest.cpp index 1ee79ad96..063e3263f 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -434,16 +434,16 @@ static int testCrypto() } std::cout << "[crypto] ECDH Agree: " << Utils::hex(p384sec,sizeof(p384sec),p384hex) << ZT_EOL_S; - Utils::unhex(ECC384_TEST_PUBLIC,p384pub,sizeof(p384pub)); - Utils::unhex(ECC384_TEST_PRIVATE,p384priv,sizeof(p384priv)); + Utils::unhex(ECC384_TEST_PUBLIC,strlen(ECC384_TEST_PUBLIC),p384pub,sizeof(p384pub)); + Utils::unhex(ECC384_TEST_PRIVATE,strlen(ECC384_TEST_PRIVATE),p384priv,sizeof(p384priv)); ECC384ECDH(p384pub,p384priv,p384sec); - Utils::unhex(ECC384_TEST_DH_SELF_AGREE,p384sec2,sizeof(p384sec2)); + Utils::unhex(ECC384_TEST_DH_SELF_AGREE,strlen(ECC384_TEST_DH_SELF_AGREE),p384sec2,sizeof(p384sec2)); if (memcmp(p384sec,p384sec2,ZT_ECC384_SHARED_SECRET_SIZE)) { std::cout << "[crypto] ECDH Test Vector: FAILED (secrets do not match)" ZT_EOL_S; return -1; } std::cout << "[crypto] ECDH Test Vector: PASS" ZT_EOL_S; - Utils::unhex(ECC384_TEST_SIG,p384sig,sizeof(p384sig)); + Utils::unhex(ECC384_TEST_SIG,strlen(ECC384_TEST_SIG),p384sig,sizeof(p384sig)); if (!ECC384ECDSAVerify(p384pub,p384pub,p384sig)) { std::cout << "[crypto] ECDSA Test Vector: FAILED (verify failed)" ZT_EOL_S; return -1; @@ -768,7 +768,7 @@ static int testOther() std::cout << "[other] Testing hex/unhex... "; std::cout.flush(); Utils::getSecureRandom(buf,(unsigned int)sizeof(buf)); Utils::hex(buf,(unsigned int)sizeof(buf),buf2); - Utils::unhex(buf2,buf3,(unsigned int)sizeof(buf3)); + Utils::unhex(buf2,sizeof(buf2),buf3,(unsigned int)sizeof(buf3)); if (memcmp(buf,buf3,sizeof(buf)) == 0) { std::cout << "PASS" ZT_EOL_S; } else { @@ -801,26 +801,6 @@ static int testOther() } std::cout << "PASS" ZT_EOL_S; - std::cout << "[other] Testing base64... "; std::cout.flush(); - for(unsigned int i=1;i<1024;++i) { - Utils::getSecureRandom(buf,(unsigned int)sizeof(buf)); - unsigned int l = Utils::b64e((const uint8_t *)buf,i,buf2,sizeof(buf2)); - if (l == 0) { - std::cout << "FAIL (encode returned 0)" ZT_EOL_S; - return -1; - } - unsigned int l2 = Utils::b64d(buf2,(uint8_t *)buf3,sizeof(buf3)); - if (l2 != i) { - std::cout << "FAIL (decode returned wrong count)" ZT_EOL_S; - return -1; - } - if (memcmp(buf,buf3,i) != 0) { - std::cout << "FAIL (decode result incorrect)" ZT_EOL_S; - return -1; - } - } - std::cout << "PASS" ZT_EOL_S; - std::cout << "[other] Testing InetAddress encode/decode..."; std::cout.flush(); std::cout << " " << InetAddress("127.0.0.1/9993").toString(buf); std::cout << " " << InetAddress("feed:dead:babe:dead:beef:f00d:1234:5678/12345").toString(buf);