Fingerprint string conversion, API stuff

This commit is contained in:
Adam Ierymenko 2020-03-02 15:13:34 -08:00
parent fbd3e10488
commit b96ea5ae03
No known key found for this signature in database
GPG key ID: C8877CF2D7A5D7F3
4 changed files with 62 additions and 13 deletions

View file

@ -299,7 +299,14 @@ typedef void ZT_Identity;
*/
ZT_PACKED_STRUCT(struct _ZT_Fingerprint
{
/**
* Short address (only least significant 40 bits are used)
*/
uint64_t address;
/**
* 384-bit hash of identity public key(s)
*/
uint8_t hash[48];
});
typedef struct _ZT_Fingerprint ZT_Fingerprint;
@ -2142,6 +2149,14 @@ ZT_SDK_API int ZT_Identity_hasPrivate(const ZT_Identity *id);
*/
ZT_SDK_API uint64_t ZT_Identity_address(const ZT_Identity *id);
/**
* Get this identity's full fingerprint
*
* @param id Identity to query
* @return Pointer to fingerprint (remains valid as long as identity itself is valid)
*/
ZT_SDK_API const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id);
/**
* Delete an identity and free associated memory
*

View file

@ -17,9 +17,12 @@
#include "Constants.hpp"
#include "TriviallyCopyable.hpp"
#include "Address.hpp"
#include "Utils.hpp"
#include <algorithm>
#define ZT_FINGERPRINT_STRING_BUFFER_LENGTH 96
namespace ZeroTier {
class Identity;
@ -54,6 +57,41 @@ public:
*/
ZT_ALWAYS_INLINE void getAPIFingerprint(ZT_Fingerprint *fp) const noexcept { memcpy(fp,&_fp,sizeof(ZT_Fingerprint)); }
/**
* @return Pointer to ZT_Fingerprint for API use
*/
ZT_ALWAYS_INLINE const ZT_Fingerprint *apiFingerprint() const noexcept { return &_fp; }
/**
* Get a base32-encoded representation of this fingerprint
*
* @param s Base32 string
*/
ZT_ALWAYS_INLINE void toString(char s[ZT_FINGERPRINT_STRING_BUFFER_LENGTH])
{
uint8_t tmp[48 + 5];
address().copyTo(tmp);
memcpy(tmp + 5,_fp.hash,48);
Utils::b32e(tmp,sizeof(tmp),s,ZT_FINGERPRINT_STRING_BUFFER_LENGTH);
s[ZT_FINGERPRINT_STRING_BUFFER_LENGTH-1] = 0; // sanity check, ensure always zero terminated
}
/**
* Set this fingerprint to a base32-encoded string
*
* @param s String to decode
* @return True if string appears to be valid and of the proper length (no other checking is done)
*/
ZT_ALWAYS_INLINE bool fromString(const char *s)
{
uint8_t tmp[48 + 5];
if (Utils::b32d(s,tmp,sizeof(tmp)) != sizeof(tmp))
return false;
_fp.address = Address(tmp).toInt();
memcpy(_fp.hash,tmp + 5,48);
return true;
}
ZT_ALWAYS_INLINE void zero() noexcept { memoryZero(this); }
ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _fp.address; }

View file

@ -599,6 +599,13 @@ uint64_t ZT_Identity_address(const ZT_Identity *id)
return reinterpret_cast<const ZeroTier::Identity *>(id)->address().toInt();
}
const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
{
if (!id)
return nullptr;
return reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint().apiFingerprint();
}
ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
{
if (id)

View file

@ -203,20 +203,9 @@ public:
ZT_ALWAYS_INLINE unsigned long hashCode() const noexcept { return _fp.hashCode(); }
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept { return ((_address == id._address)&&(_fp == id._fp)); }
ZT_ALWAYS_INLINE bool operator==(const Identity &id) const noexcept { return (_fp == id._fp); }
ZT_ALWAYS_INLINE bool operator!=(const Identity &id) const noexcept { return !(*this == id); }
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept
{
if (_address < id._address)
return true;
if (_address == id._address) {
if ((int)_type < (int)id._type)
return true;
if (_type == id._type)
return _fp < id._fp;
}
return false;
}
ZT_ALWAYS_INLINE bool operator<(const Identity &id) const noexcept { return (_fp < id._fp); }
ZT_ALWAYS_INLINE bool operator>(const Identity &id) const noexcept { return (id < *this); }
ZT_ALWAYS_INLINE bool operator<=(const Identity &id) const noexcept { return !(id < *this); }
ZT_ALWAYS_INLINE bool operator>=(const Identity &id) const noexcept { return !(*this < id); }