Identity.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. /*
  2. * Copyright (c)2013-2020 ZeroTier, Inc.
  3. *
  4. * Use of this software is governed by the Business Source License included
  5. * in the LICENSE.TXT file in the project's root directory.
  6. *
  7. * Change Date: 2024-01-01
  8. *
  9. * On the date above, in accordance with the Business Source License, use
  10. * of this software will be governed by version 2.0 of the Apache License.
  11. */
  12. /****/
  13. #include "Constants.hpp"
  14. #include "Identity.hpp"
  15. #include "SHA512.hpp"
  16. #include "Salsa20.hpp"
  17. #include "Utils.hpp"
  18. #include "Speck128.hpp"
  19. #include <cstring>
  20. #include <cstdint>
  21. #include <algorithm>
  22. namespace ZeroTier {
  23. namespace {
  24. // This is the memory-intensive hash function used to compute v0 identities from v0 public keys.
  25. #define ZT_V0_IDENTITY_GEN_MEMORY 2097152
  26. void identityV0ProofOfWorkFrankenhash(const void *const publicKey,unsigned int publicKeyBytes,void *const digest,void *const genmem) noexcept
  27. {
  28. // Digest publicKey[] to obtain initial digest
  29. SHA512(digest,publicKey,publicKeyBytes);
  30. // Initialize genmem[] using Salsa20 in a CBC-like configuration since
  31. // ordinary Salsa20 is randomly seek-able. This is good for a cipher
  32. // but is not what we want for sequential memory-hardness.
  33. Utils::zero<ZT_V0_IDENTITY_GEN_MEMORY>(genmem);
  34. Salsa20 s20(digest,(char *)digest + 32);
  35. s20.crypt20((char *)genmem,(char *)genmem,64);
  36. for(unsigned long i=64;i<ZT_V0_IDENTITY_GEN_MEMORY;i+=64) {
  37. unsigned long k = i - 64;
  38. *((uint64_t *)((char *)genmem + i)) = *((uint64_t *)((char *)genmem + k));
  39. *((uint64_t *)((char *)genmem + i + 8)) = *((uint64_t *)((char *)genmem + k + 8));
  40. *((uint64_t *)((char *)genmem + i + 16)) = *((uint64_t *)((char *)genmem + k + 16));
  41. *((uint64_t *)((char *)genmem + i + 24)) = *((uint64_t *)((char *)genmem + k + 24));
  42. *((uint64_t *)((char *)genmem + i + 32)) = *((uint64_t *)((char *)genmem + k + 32));
  43. *((uint64_t *)((char *)genmem + i + 40)) = *((uint64_t *)((char *)genmem + k + 40));
  44. *((uint64_t *)((char *)genmem + i + 48)) = *((uint64_t *)((char *)genmem + k + 48));
  45. *((uint64_t *)((char *)genmem + i + 56)) = *((uint64_t *)((char *)genmem + k + 56));
  46. s20.crypt20((char *)genmem + i,(char *)genmem + i,64);
  47. }
  48. // Render final digest using genmem as a lookup table
  49. for(unsigned long i=0;i<(ZT_V0_IDENTITY_GEN_MEMORY / sizeof(uint64_t));) {
  50. unsigned long idx1 = (unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (64 / sizeof(uint64_t))); // NOLINT(hicpp-use-auto,modernize-use-auto)
  51. unsigned long idx2 = (unsigned long)(Utils::ntoh(((uint64_t *)genmem)[i++]) % (ZT_V0_IDENTITY_GEN_MEMORY / sizeof(uint64_t))); // NOLINT(hicpp-use-auto,modernize-use-auto)
  52. uint64_t tmp = ((uint64_t *)genmem)[idx2];
  53. ((uint64_t *)genmem)[idx2] = ((uint64_t *)digest)[idx1];
  54. ((uint64_t *)digest)[idx1] = tmp;
  55. s20.crypt20(digest,digest,64);
  56. }
  57. }
  58. struct identityV0ProofOfWorkCriteria
  59. {
  60. ZT_INLINE identityV0ProofOfWorkCriteria(unsigned char *sb,char *gm) noexcept : digest(sb),genmem(gm) {}
  61. ZT_INLINE bool operator()(const uint8_t pub[ZT_C25519_COMBINED_PUBLIC_KEY_SIZE]) const noexcept
  62. {
  63. identityV0ProofOfWorkFrankenhash(pub,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,digest,genmem);
  64. return (digest[0] < 17);
  65. }
  66. unsigned char *digest;
  67. char *genmem;
  68. };
  69. // This is a simpler memory-intensive hash function for V1 identity generation.
  70. // It's not quite as intensive as the V0 frankenhash, is a little more orderly in
  71. // its design, but remains relatively resistant to GPU acceleration due to memory
  72. // requirements for efficient computation.
  73. #define ZT_IDENTITY_V1_POW_MEMORY_SIZE 98304
  74. bool identityV1ProofOfWorkCriteria(const void *in,const unsigned int len,uint64_t *const b)
  75. {
  76. SHA512(b,in,len);
  77. // This treats hash output as little-endian, so swap on BE machines.
  78. #if __BYTE_ORDER == __BIG_ENDIAN
  79. b[0] = Utils::swapBytes(b[0]);
  80. b[1] = Utils::swapBytes(b[1]);
  81. b[2] = Utils::swapBytes(b[2]);
  82. b[3] = Utils::swapBytes(b[3]);
  83. b[4] = Utils::swapBytes(b[4]);
  84. b[5] = Utils::swapBytes(b[5]);
  85. b[6] = Utils::swapBytes(b[6]);
  86. b[7] = Utils::swapBytes(b[7]);
  87. #endif
  88. // Memory-intensive work: fill 'b' with pseudo-random bits generated from
  89. // a reduced-round instance of Speck128 using a CBC-like construction.
  90. // Then sort the resulting integer array in ascending numerical order.
  91. // The sort requires that we compute and cache the whole data set, or at
  92. // least that this is the most efficient implementation.
  93. Speck128<24> s16;
  94. s16.initXY(b[4],b[5]);
  95. for(unsigned long i=0;i<(ZT_IDENTITY_V1_POW_MEMORY_SIZE-8);) {
  96. // Load four 128-bit blocks.
  97. uint64_t x0 = b[i];
  98. uint64_t y0 = b[i + 1];
  99. uint64_t x1 = b[i + 2];
  100. uint64_t y1 = b[i + 3];
  101. uint64_t x2 = b[i + 4];
  102. uint64_t y2 = b[i + 5];
  103. uint64_t x3 = b[i + 6];
  104. uint64_t y3 = b[i + 7];
  105. // Advance by 512 bits / 64 bytes (its a uint64_t array).
  106. i += 8;
  107. // Ensure that mixing happens across blocks.
  108. x0 += x1;
  109. x1 += x2;
  110. x2 += x3;
  111. x3 += y0;
  112. // Encrypt 4X blocks. Speck is used for this PoW function because
  113. // its performance is similar on all architectures while AES is much
  114. // faster on some than others.
  115. s16.encryptXYXYXYXY(x0,y0,x1,y1,x2,y2,x3,y3);
  116. // Store four 128-bit blocks at new position.
  117. b[i] = x0;
  118. b[i + 1] = y0;
  119. b[i + 2] = x1;
  120. b[i + 3] = y1;
  121. b[i + 4] = x2;
  122. b[i + 5] = y2;
  123. b[i + 6] = x3;
  124. b[i + 7] = y3;
  125. }
  126. // Sort array, something that can't efficiently be done unless we have
  127. // computed the whole array and have it in memory. This also involves
  128. // branching which is less efficient on GPUs.
  129. std::sort(b,b + ZT_IDENTITY_V1_POW_MEMORY_SIZE);
  130. // Swap byte order back on BE machines.
  131. #if __BYTE_ORDER == __BIG_ENDIAN
  132. for(unsigned int i=0;i<98304;i+=8) {
  133. b[i] = Utils::swapBytes(b[i]);
  134. b[i + 1] = Utils::swapBytes(b[i + 1]);
  135. b[i + 2] = Utils::swapBytes(b[i + 2]);
  136. b[i + 3] = Utils::swapBytes(b[i + 3]);
  137. b[i + 4] = Utils::swapBytes(b[i + 4]);
  138. b[i + 5] = Utils::swapBytes(b[i + 5]);
  139. b[i + 6] = Utils::swapBytes(b[i + 6]);
  140. b[i + 7] = Utils::swapBytes(b[i + 7]);
  141. }
  142. #endif
  143. // Hash resulting sorted array to get final result for PoW criteria test.
  144. SHA384(b,b,sizeof(b),in,len);
  145. // PoW passes if sum of first two 64-bit integers (treated as little-endian) mod 180 is 0.
  146. // This value was picked to yield about 1-2s total on typical desktop and server cores in 2020.
  147. #if __BYTE_ORDER == __BIG_ENDIAN
  148. const uint64_t finalHash = Utils::swapBytes(b[0]) + Utils::swapBytes(b[1]);
  149. #else
  150. const uint64_t finalHash = b[0] + b[1];
  151. #endif
  152. return (finalHash % 180U) == 0;
  153. }
  154. } // anonymous namespace
  155. const Identity Identity::NIL;
  156. bool Identity::generate(const Type t)
  157. {
  158. _type = t;
  159. _hasPrivate = true;
  160. switch(t) {
  161. case C25519: {
  162. // Generate C25519/Ed25519 key pair whose hash satisfies a "hashcash" criterion and generate the
  163. // address from the last 40 bits of this hash. This is different from the fingerprint hash for V0.
  164. uint8_t digest[64];
  165. char *const genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
  166. do {
  167. C25519::generateSatisfying(identityV0ProofOfWorkCriteria(digest,genmem),_pub.c25519,_priv.c25519);
  168. _address.setTo(digest + 59);
  169. } while (_address.isReserved());
  170. delete[] genmem;
  171. _computeHash();
  172. } break;
  173. case P384: {
  174. uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE * 8); // NOLINT(hicpp-use-auto,modernize-use-auto)
  175. if (!b)
  176. return false;
  177. for(;;) {
  178. // Loop until we pass the PoW criteria. The nonce is only 8 bits, so generate
  179. // some new key material every time it wraps. The ECC384 generator is slightly
  180. // faster so use that one.
  181. _pub.nonce = 0;
  182. C25519::generateCombined(_pub.c25519,_priv.c25519);
  183. ECC384GenerateKey(_pub.p384,_priv.p384);
  184. for(;;) {
  185. if (identityV1ProofOfWorkCriteria(&_pub,sizeof(_pub),b))
  186. break;
  187. if (++_pub.nonce == 0)
  188. ECC384GenerateKey(_pub.p384,_priv.p384);
  189. }
  190. // If we passed PoW then check that the address is valid, otherwise loop
  191. // back around and run the whole process again.
  192. _computeHash();
  193. _address.setTo(_fp.hash());
  194. if (!_address.isReserved())
  195. break;
  196. }
  197. free(b);
  198. } break;
  199. default:
  200. return false;
  201. }
  202. return true;
  203. }
  204. bool Identity::locallyValidate() const noexcept
  205. {
  206. try {
  207. if ((!_address.isReserved()) && (_address)) {
  208. switch (_type) {
  209. case C25519: {
  210. uint8_t digest[64];
  211. char *genmem = new char[ZT_V0_IDENTITY_GEN_MEMORY];
  212. identityV0ProofOfWorkFrankenhash(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,digest,genmem);
  213. delete[] genmem;
  214. return ((_address == Address(digest + 59)) && (digest[0] < 17));
  215. }
  216. case P384: {
  217. if (_address != Address(_fp.hash()))
  218. return false;
  219. uint64_t *const b = (uint64_t *)malloc(ZT_IDENTITY_V1_POW_MEMORY_SIZE * 8); // NOLINT(hicpp-use-auto,modernize-use-auto)
  220. if (!b)
  221. return false;
  222. const bool ok = identityV1ProofOfWorkCriteria(&_pub,sizeof(_pub),b);
  223. free(b);
  224. return ok;
  225. }
  226. }
  227. }
  228. } catch ( ... ) {}
  229. return false;
  230. }
  231. void Identity::hashWithPrivate(uint8_t h[ZT_FINGERPRINT_HASH_SIZE]) const
  232. {
  233. if (_hasPrivate) {
  234. switch (_type) {
  235. case C25519:
  236. SHA384(h,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE);
  237. break;
  238. case P384:
  239. SHA384(h,&_pub,sizeof(_pub),&_priv,sizeof(_priv));
  240. break;
  241. }
  242. return;
  243. }
  244. Utils::zero<48>(h);
  245. }
  246. unsigned int Identity::sign(const void *data,unsigned int len,void *sig,unsigned int siglen) const
  247. {
  248. if (_hasPrivate) {
  249. switch(_type) {
  250. case C25519:
  251. if (siglen >= ZT_C25519_SIGNATURE_LEN) {
  252. C25519::sign(_priv.c25519,_pub.c25519,data,len,sig);
  253. return ZT_C25519_SIGNATURE_LEN;
  254. }
  255. case P384:
  256. if (siglen >= ZT_ECC384_SIGNATURE_SIZE) {
  257. uint8_t h[48];
  258. SHA384(h,data,len,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE); // include C25519 public key in hash
  259. ECC384ECDSASign(_priv.p384,h,(uint8_t *)sig);
  260. return ZT_ECC384_SIGNATURE_SIZE;
  261. }
  262. }
  263. }
  264. return 0;
  265. }
  266. bool Identity::verify(const void *data,unsigned int len,const void *sig,unsigned int siglen) const
  267. {
  268. switch(_type) {
  269. case C25519:
  270. return C25519::verify(_pub.c25519,data,len,sig,siglen);
  271. case P384:
  272. if (siglen == ZT_ECC384_SIGNATURE_SIZE) {
  273. uint8_t h[48];
  274. SHA384(h,data,len,&_pub,ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE);
  275. return ECC384ECDSAVerify(_pub.p384,h,(const uint8_t *)sig);
  276. }
  277. break;
  278. }
  279. return false;
  280. }
  281. bool Identity::agree(const Identity &id,uint8_t key[ZT_SYMMETRIC_KEY_SIZE]) const
  282. {
  283. uint8_t rawkey[128];
  284. uint8_t h[64];
  285. if (_hasPrivate) {
  286. if (_type == C25519) {
  287. if ((id._type == C25519)||(id._type == P384)) {
  288. // If we are a C25519 key we can agree with another C25519 key or with only the
  289. // C25519 portion of a type 1 P-384 key.
  290. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  291. SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
  292. Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
  293. return true;
  294. }
  295. } else if (_type == P384) {
  296. if (id._type == P384) {
  297. // For another P384 identity we execute DH agreement with BOTH keys and then
  298. // hash the results together. For those (cough FIPS cough) who only consider
  299. // P384 to be kosher, the C25519 secret can be considered a "salt"
  300. // or something. For those who don't trust P384 this means the privacy of
  301. // your traffic is also protected by C25519.
  302. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  303. ECC384ECDH(id._pub.p384,_priv.p384,rawkey + ZT_C25519_ECDH_SHARED_SECRET_SIZE);
  304. SHA384(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE + ZT_ECC384_SHARED_SECRET_SIZE);
  305. Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
  306. return true;
  307. } else if (id._type == C25519) {
  308. // If the other identity is a C25519 identity we can agree using only that type.
  309. C25519::agree(_priv.c25519,id._pub.c25519,rawkey);
  310. SHA512(h,rawkey,ZT_C25519_ECDH_SHARED_SECRET_SIZE);
  311. Utils::copy<ZT_SYMMETRIC_KEY_SIZE>(key,h);
  312. return true;
  313. }
  314. }
  315. }
  316. return false;
  317. }
  318. char *Identity::toString(bool includePrivate,char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const
  319. {
  320. char *p = buf;
  321. _address.toString(p);
  322. p += 10;
  323. *(p++) = ':';
  324. switch(_type) {
  325. case C25519: {
  326. *(p++) = '0';
  327. *(p++) = ':';
  328. Utils::hex(_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE,p);
  329. p += ZT_C25519_COMBINED_PUBLIC_KEY_SIZE * 2;
  330. if ((_hasPrivate)&&(includePrivate)) {
  331. *(p++) = ':';
  332. Utils::hex(_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE,p);
  333. p += ZT_C25519_COMBINED_PRIVATE_KEY_SIZE * 2;
  334. }
  335. *p = (char)0;
  336. return buf;
  337. }
  338. case P384: {
  339. *(p++) = '1';
  340. *(p++) = ':';
  341. int el = Utils::b32e((const uint8_t *)(&_pub),sizeof(_pub),p,(int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
  342. if (el <= 0) return nullptr;
  343. p += el;
  344. if ((_hasPrivate)&&(includePrivate)) {
  345. *(p++) = ':';
  346. el = Utils::b32e((const uint8_t *)(&_priv),sizeof(_priv),p,(int)(ZT_IDENTITY_STRING_BUFFER_LENGTH - (uintptr_t)(p - buf)));
  347. if (el <= 0) return nullptr;
  348. p += el;
  349. }
  350. *p = (char)0;
  351. return buf;
  352. }
  353. }
  354. return nullptr;
  355. }
  356. bool Identity::fromString(const char *str)
  357. {
  358. _fp.zero();
  359. _hasPrivate = false;
  360. if (!str) {
  361. _address.zero();
  362. return false;
  363. }
  364. char tmp[ZT_IDENTITY_STRING_BUFFER_LENGTH];
  365. if (!Utils::scopy(tmp,sizeof(tmp),str)) {
  366. _address.zero();
  367. return false;
  368. }
  369. int fno = 0;
  370. char *saveptr = nullptr;
  371. for(char *f=Utils::stok(tmp,":",&saveptr);((f)&&(fno < 4));f=Utils::stok(nullptr,":",&saveptr)) {
  372. switch(fno++) {
  373. case 0:
  374. _address = Address(Utils::hexStrToU64(f));
  375. if (_address.isReserved()) {
  376. _address.zero();
  377. return false;
  378. }
  379. break;
  380. case 1:
  381. if ((f[0] == '0')&&(!f[1])) {
  382. _type = C25519;
  383. } else if ((f[0] == '1')&&(!f[1])) {
  384. _type = P384;
  385. } else {
  386. _address.zero();
  387. return false;
  388. }
  389. break;
  390. case 2:
  391. switch(_type) {
  392. case C25519:
  393. if (Utils::unhex(f,strlen(f),_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) != ZT_C25519_COMBINED_PUBLIC_KEY_SIZE) {
  394. _address.zero();
  395. return false;
  396. }
  397. break;
  398. case P384:
  399. if (Utils::b32d(f,(uint8_t *)(&_pub),sizeof(_pub)) != sizeof(_pub)) {
  400. _address.zero();
  401. return false;
  402. }
  403. break;
  404. }
  405. break;
  406. case 3:
  407. if (strlen(f) > 1) {
  408. switch(_type) {
  409. case C25519:
  410. if (Utils::unhex(f,strlen(f),_priv.c25519,ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) != ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
  411. _address.zero();
  412. return false;
  413. } else {
  414. _hasPrivate = true;
  415. }
  416. break;
  417. case P384:
  418. if (Utils::b32d(f,(uint8_t *)(&_priv),sizeof(_priv)) != sizeof(_priv)) {
  419. _address.zero();
  420. return false;
  421. } else {
  422. _hasPrivate = true;
  423. }
  424. break;
  425. }
  426. break;
  427. }
  428. }
  429. }
  430. if (fno < 3) {
  431. _address.zero();
  432. return false;
  433. }
  434. _computeHash();
  435. if ((_type == P384)&&(_address != Address(_fp.hash()))) {
  436. _address.zero();
  437. return false;
  438. }
  439. return true;
  440. }
  441. int Identity::marshal(uint8_t data[ZT_IDENTITY_MARSHAL_SIZE_MAX],const bool includePrivate) const noexcept
  442. {
  443. _address.copyTo(data);
  444. switch(_type) {
  445. case C25519:
  446. data[ZT_ADDRESS_LENGTH] = (uint8_t)C25519;
  447. Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,_pub.c25519);
  448. if ((includePrivate)&&(_hasPrivate)) {
  449. data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
  450. Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1,_priv.c25519);
  451. return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
  452. } else {
  453. data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE] = 0;
  454. return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
  455. }
  456. case P384:
  457. data[ZT_ADDRESS_LENGTH] = (uint8_t)P384;
  458. Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1,&_pub);
  459. if ((includePrivate)&&(_hasPrivate)) {
  460. data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
  461. Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1,&_priv);
  462. return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
  463. } else {
  464. data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE] = 0;
  465. return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
  466. }
  467. }
  468. return -1;
  469. }
  470. int Identity::unmarshal(const uint8_t *data,const int len) noexcept
  471. {
  472. _fp.zero();
  473. _hasPrivate = false;
  474. if (len < (1 + ZT_ADDRESS_LENGTH))
  475. return -1;
  476. _address.setTo(data);
  477. unsigned int privlen;
  478. switch((_type = (Type)data[ZT_ADDRESS_LENGTH])) {
  479. case C25519:
  480. if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1))
  481. return -1;
  482. Utils::copy<ZT_C25519_COMBINED_PUBLIC_KEY_SIZE>(_pub.c25519,data + ZT_ADDRESS_LENGTH + 1);
  483. _computeHash();
  484. privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE];
  485. if (privlen == ZT_C25519_COMBINED_PRIVATE_KEY_SIZE) {
  486. if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE))
  487. return -1;
  488. _hasPrivate = true;
  489. Utils::copy<ZT_C25519_COMBINED_PRIVATE_KEY_SIZE>(_priv.c25519,data + ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1);
  490. return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1 + ZT_C25519_COMBINED_PRIVATE_KEY_SIZE;
  491. } else if (privlen == 0) {
  492. _hasPrivate = false;
  493. return ZT_ADDRESS_LENGTH + 1 + ZT_C25519_COMBINED_PUBLIC_KEY_SIZE + 1;
  494. }
  495. break;
  496. case P384:
  497. if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1))
  498. return -1;
  499. Utils::copy<ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE>(&_pub,data + ZT_ADDRESS_LENGTH + 1);
  500. _computeHash(); // this sets the address for P384
  501. if (_address != Address(_fp.hash())) // this sanity check is possible with V1 identities
  502. return -1;
  503. privlen = data[ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE];
  504. if (privlen == ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE) {
  505. if (len < (ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE))
  506. return -1;
  507. _hasPrivate = true;
  508. Utils::copy<ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE>(&_priv,data + ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1);
  509. return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1 + ZT_IDENTITY_P384_COMPOUND_PRIVATE_KEY_SIZE;
  510. } else if (privlen == 0) {
  511. _hasPrivate = false;
  512. return ZT_ADDRESS_LENGTH + 1 + ZT_IDENTITY_P384_COMPOUND_PUBLIC_KEY_SIZE + 1;
  513. }
  514. break;
  515. }
  516. return -1;
  517. }
  518. void Identity::_computeHash()
  519. {
  520. switch(_type) {
  521. default:
  522. _fp.zero();
  523. break;
  524. case C25519:
  525. _fp._fp.address = _address.toInt();
  526. SHA384(_fp._fp.hash,_pub.c25519,ZT_C25519_COMBINED_PUBLIC_KEY_SIZE);
  527. break;
  528. case P384:
  529. SHA384(_fp._fp.hash,&_pub,sizeof(_pub));
  530. _fp._fp.address = _address.toInt();
  531. break;
  532. }
  533. }
  534. } // namespace ZeroTier
  535. extern "C" {
  536. ZT_Identity *ZT_Identity_new(enum ZT_Identity_Type type)
  537. {
  538. if ((type != ZT_IDENTITY_TYPE_C25519)&&(type != ZT_IDENTITY_TYPE_P384))
  539. return nullptr;
  540. try {
  541. ZeroTier::Identity *const id = new ZeroTier::Identity(); // NOLINT(hicpp-use-auto,modernize-use-auto)
  542. id->generate((ZeroTier::Identity::Type)type);
  543. return reinterpret_cast<ZT_Identity *>(id);
  544. } catch ( ... ) {
  545. return nullptr;
  546. }
  547. }
  548. ZT_Identity *ZT_Identity_fromString(const char *idStr)
  549. {
  550. if (!idStr)
  551. return nullptr;
  552. try {
  553. ZeroTier::Identity *const id = new ZeroTier::Identity(); // NOLINT(hicpp-use-auto,modernize-use-auto)
  554. if (!id->fromString(idStr)) {
  555. delete id;
  556. return nullptr;
  557. }
  558. return reinterpret_cast<ZT_Identity *>(id);
  559. } catch ( ... ) {
  560. return nullptr;
  561. }
  562. }
  563. int ZT_Identity_validate(const ZT_Identity *id)
  564. {
  565. if (!id)
  566. return 0;
  567. return reinterpret_cast<const ZeroTier::Identity *>(id)->locallyValidate() ? 1 : 0;
  568. }
  569. unsigned int ZT_Identity_sign(const ZT_Identity *id,const void *data,unsigned int len,void *signature,unsigned int signatureBufferLength)
  570. {
  571. if (!id)
  572. return 0;
  573. if (signatureBufferLength < ZT_SIGNATURE_BUFFER_SIZE)
  574. return 0;
  575. return reinterpret_cast<const ZeroTier::Identity *>(id)->sign(data,len,signature,signatureBufferLength);
  576. }
  577. int ZT_Identity_verify(const ZT_Identity *id,const void *data,unsigned int len,const void *signature,unsigned int sigLen)
  578. {
  579. if ((!id)||(!signature)||(!sigLen))
  580. return 0;
  581. return reinterpret_cast<const ZeroTier::Identity *>(id)->verify(data,len,signature,sigLen) ? 1 : 0;
  582. }
  583. enum ZT_Identity_Type ZT_Identity_type(const ZT_Identity *id)
  584. {
  585. if (!id)
  586. return (ZT_Identity_Type)0;
  587. return (enum ZT_Identity_Type)reinterpret_cast<const ZeroTier::Identity *>(id)->type();
  588. }
  589. char *ZT_Identity_toString(const ZT_Identity *id,char *buf,int capacity,int includePrivate)
  590. {
  591. if ((!id)||(!buf)||(capacity < ZT_IDENTITY_STRING_BUFFER_LENGTH))
  592. return nullptr;
  593. reinterpret_cast<const ZeroTier::Identity *>(id)->toString(includePrivate != 0,buf);
  594. return buf;
  595. }
  596. int ZT_Identity_hasPrivate(const ZT_Identity *id)
  597. {
  598. if (!id)
  599. return 0;
  600. return reinterpret_cast<const ZeroTier::Identity *>(id)->hasPrivate() ? 1 : 0;
  601. }
  602. uint64_t ZT_Identity_address(const ZT_Identity *id)
  603. {
  604. if (!id)
  605. return 0;
  606. return reinterpret_cast<const ZeroTier::Identity *>(id)->address().toInt();
  607. }
  608. const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
  609. {
  610. if (!id)
  611. return nullptr;
  612. return reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint().apiFingerprint();
  613. }
  614. ZT_SDK_API void ZT_Identity_delete(ZT_Identity *id)
  615. {
  616. if (id)
  617. delete reinterpret_cast<ZeroTier::Identity *>(id);
  618. }
  619. }