2
0

CAPI.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725
  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: 2025-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 "Node.hpp"
  15. #include "Identity.hpp"
  16. #include "Locator.hpp"
  17. #include "Certificate.hpp"
  18. extern "C" {
  19. /********************************************************************************************************************/
  20. // These macros make the idiom of passing buffers to outside code via the API work properly even
  21. // if the first address of Buf does not overlap with its data field, since the C++ standard does
  22. // not absolutely guarantee this.
  23. #define ZT_PTRTOBUF(p) ((ZeroTier::Buf *)( ((uintptr_t)(p)) - ((uintptr_t)&(((ZeroTier::Buf *)0)->unsafeData[0])) ))
  24. #define ZT_BUFTOPTR(b) ((void *)(&((b)->unsafeData[0])))
  25. void *ZT_getBuffer()
  26. {
  27. // When external code requests a Buf, grab one from the pool (or freshly allocated)
  28. // and return it with its reference count left at zero. It's the responsibility of
  29. // external code to bring it back via freeBuffer() or one of the processX() calls.
  30. // When this occurs it's either sent back to the pool with Buf's delete operator or
  31. // wrapped in a SharedPtr<> to be passed into the core.
  32. try {
  33. return ZT_BUFTOPTR(new ZeroTier::Buf());
  34. } catch (...) {
  35. return nullptr; // can only happen on out of memory condition
  36. }
  37. }
  38. void ZT_freeBuffer(void *b)
  39. {
  40. if (b)
  41. delete ZT_PTRTOBUF(b);
  42. }
  43. struct p_queryResultBase
  44. {
  45. void (*freeFunction)(const void *);
  46. };
  47. void ZT_freeQueryResult(const void *qr)
  48. {
  49. if ((qr) && (reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction))
  50. reinterpret_cast<const p_queryResultBase *>(qr)->freeFunction(qr);
  51. }
  52. void ZT_version(int *major, int *minor, int *revision, int *build)
  53. {
  54. if (major)
  55. *major = ZEROTIER_VERSION_MAJOR;
  56. if (minor)
  57. *minor = ZEROTIER_VERSION_MINOR;
  58. if (revision)
  59. *revision = ZEROTIER_VERSION_REVISION;
  60. if (build)
  61. *build = ZEROTIER_VERSION_BUILD;
  62. }
  63. /********************************************************************************************************************/
  64. enum ZT_ResultCode ZT_Node_new(ZT_Node **node, void *uptr, void *tptr, const struct ZT_Node_Callbacks *callbacks, int64_t now)
  65. {
  66. *node = nullptr;
  67. try {
  68. *node = reinterpret_cast<ZT_Node *>(new ZeroTier::Node(uptr, tptr, callbacks, now));
  69. return ZT_RESULT_OK;
  70. } catch (std::bad_alloc &exc) {
  71. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  72. } catch (std::runtime_error &exc) {
  73. return ZT_RESULT_FATAL_ERROR_DATA_STORE_FAILED;
  74. } catch (...) {
  75. return ZT_RESULT_ERROR_INTERNAL;
  76. }
  77. }
  78. void ZT_Node_delete(ZT_Node *node, void *tPtr)
  79. {
  80. try {
  81. reinterpret_cast<ZeroTier::Node *>(node)->shutdown(tPtr);
  82. delete (reinterpret_cast<ZeroTier::Node *>(node));
  83. } catch (...) {}
  84. }
  85. enum ZT_ResultCode ZT_Node_processWirePacket(
  86. ZT_Node *node,
  87. void *tptr,
  88. int64_t now,
  89. int64_t localSocket,
  90. const struct sockaddr_storage *remoteAddress,
  91. const void *packetData,
  92. unsigned int packetLength,
  93. int isZtBuffer,
  94. volatile int64_t *nextBackgroundTaskDeadline)
  95. {
  96. try {
  97. ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(packetData) : new ZeroTier::Buf(packetData, packetLength & ZT_BUF_MEM_MASK));
  98. return reinterpret_cast<ZeroTier::Node *>(node)->processWirePacket(tptr, now, localSocket, remoteAddress, buf, packetLength, nextBackgroundTaskDeadline);
  99. } catch (std::bad_alloc &exc) {
  100. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  101. } catch (...) {
  102. // "OK" since invalid packets are simply dropped, but the system is still up.
  103. // We should never make it here, but if we did that would be the interpretation.
  104. return ZT_RESULT_OK;
  105. }
  106. }
  107. enum ZT_ResultCode ZT_Node_processVirtualNetworkFrame(
  108. ZT_Node *node,
  109. void *tptr,
  110. int64_t now,
  111. uint64_t nwid,
  112. uint64_t sourceMac,
  113. uint64_t destMac,
  114. unsigned int etherType,
  115. unsigned int vlanId,
  116. const void *frameData,
  117. unsigned int frameLength,
  118. int isZtBuffer,
  119. volatile int64_t *nextBackgroundTaskDeadline)
  120. {
  121. try {
  122. ZeroTier::SharedPtr< ZeroTier::Buf > buf((isZtBuffer) ? ZT_PTRTOBUF(frameData) : new ZeroTier::Buf(frameData, frameLength & ZT_BUF_MEM_MASK));
  123. return reinterpret_cast<ZeroTier::Node *>(node)->processVirtualNetworkFrame(tptr, now, nwid, sourceMac, destMac, etherType, vlanId, buf, frameLength, nextBackgroundTaskDeadline);
  124. } catch (std::bad_alloc &exc) {
  125. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  126. } catch (...) {
  127. return ZT_RESULT_ERROR_INTERNAL;
  128. }
  129. }
  130. enum ZT_ResultCode ZT_Node_processBackgroundTasks(ZT_Node *node, void *tptr, int64_t now, volatile int64_t *nextBackgroundTaskDeadline)
  131. {
  132. try {
  133. return reinterpret_cast<ZeroTier::Node *>(node)->processBackgroundTasks(tptr, now, nextBackgroundTaskDeadline);
  134. } catch (std::bad_alloc &exc) {
  135. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  136. } catch (...) {
  137. return ZT_RESULT_ERROR_INTERNAL;
  138. }
  139. }
  140. enum ZT_ResultCode ZT_Node_join(ZT_Node *node, uint64_t nwid, const ZT_Fingerprint *controllerFingerprint, void *uptr, void *tptr)
  141. {
  142. try {
  143. return reinterpret_cast<ZeroTier::Node *>(node)->join(nwid, controllerFingerprint, uptr, tptr);
  144. } catch (std::bad_alloc &exc) {
  145. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  146. } catch (...) {
  147. return ZT_RESULT_ERROR_INTERNAL;
  148. }
  149. }
  150. enum ZT_ResultCode ZT_Node_leave(ZT_Node *node, uint64_t nwid, void **uptr, void *tptr)
  151. {
  152. try {
  153. return reinterpret_cast<ZeroTier::Node *>(node)->leave(nwid, uptr, tptr);
  154. } catch (std::bad_alloc &exc) {
  155. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  156. } catch (...) {
  157. return ZT_RESULT_ERROR_INTERNAL;
  158. }
  159. }
  160. enum ZT_ResultCode ZT_Node_multicastSubscribe(ZT_Node *node, void *tptr, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
  161. {
  162. try {
  163. return reinterpret_cast<ZeroTier::Node *>(node)->multicastSubscribe(tptr, nwid, multicastGroup, multicastAdi);
  164. } catch (std::bad_alloc &exc) {
  165. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  166. } catch (...) {
  167. return ZT_RESULT_ERROR_INTERNAL;
  168. }
  169. }
  170. enum ZT_ResultCode ZT_Node_multicastUnsubscribe(ZT_Node *node, uint64_t nwid, uint64_t multicastGroup, unsigned long multicastAdi)
  171. {
  172. try {
  173. return reinterpret_cast<ZeroTier::Node *>(node)->multicastUnsubscribe(nwid, multicastGroup, multicastAdi);
  174. } catch (std::bad_alloc &exc) {
  175. return ZT_RESULT_FATAL_ERROR_OUT_OF_MEMORY;
  176. } catch (...) {
  177. return ZT_RESULT_ERROR_INTERNAL;
  178. }
  179. }
  180. uint64_t ZT_Node_address(ZT_Node *node)
  181. {
  182. return reinterpret_cast<ZeroTier::Node *>(node)->address();
  183. }
  184. const ZT_Identity *ZT_Node_identity(ZT_Node *node)
  185. {
  186. return (const ZT_Identity *)(&(reinterpret_cast<ZeroTier::Node *>(node)->identity()));
  187. }
  188. void ZT_Node_status(ZT_Node *node, ZT_NodeStatus *status)
  189. {
  190. try {
  191. reinterpret_cast<ZeroTier::Node *>(node)->status(status);
  192. } catch (...) {}
  193. }
  194. ZT_PeerList *ZT_Node_peers(ZT_Node *node)
  195. {
  196. try {
  197. return reinterpret_cast<ZeroTier::Node *>(node)->peers();
  198. } catch (...) {
  199. return (ZT_PeerList *)0;
  200. }
  201. }
  202. ZT_VirtualNetworkConfig *ZT_Node_networkConfig(ZT_Node *node, uint64_t nwid)
  203. {
  204. try {
  205. return reinterpret_cast<ZeroTier::Node *>(node)->networkConfig(nwid);
  206. } catch (...) {
  207. return (ZT_VirtualNetworkConfig *)0;
  208. }
  209. }
  210. ZT_VirtualNetworkList *ZT_Node_networks(ZT_Node *node)
  211. {
  212. try {
  213. return reinterpret_cast<ZeroTier::Node *>(node)->networks();
  214. } catch (...) {
  215. return (ZT_VirtualNetworkList *)0;
  216. }
  217. }
  218. int ZT_Node_tryPeer(
  219. ZT_Node *node,
  220. void *tptr,
  221. const ZT_Fingerprint *fp,
  222. const ZT_Endpoint *endpoint,
  223. int retries)
  224. {
  225. try {
  226. return reinterpret_cast<ZeroTier::Node *>(node)->tryPeer(tptr, fp, endpoint, retries);
  227. } catch (...) {
  228. return 0;
  229. }
  230. }
  231. enum ZT_CertificateError ZT_Node_addCertificate(
  232. ZT_Node *node,
  233. void *tptr,
  234. int64_t now,
  235. unsigned int localTrust,
  236. const ZT_Certificate *cert,
  237. const void *certData,
  238. unsigned int certSize)
  239. {
  240. try {
  241. return reinterpret_cast<ZeroTier::Node *>(node)->addCertificate(tptr, now, localTrust, cert, certData, certSize);
  242. } catch (...) {
  243. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  244. }
  245. }
  246. ZT_SDK_API enum ZT_ResultCode ZT_Node_deleteCertificate(
  247. ZT_Node *node,
  248. void *tptr,
  249. const void *serialNo)
  250. {
  251. try {
  252. return reinterpret_cast<ZeroTier::Node *>(node)->deleteCertificate(tptr, serialNo);
  253. } catch (...) {
  254. return ZT_RESULT_ERROR_INTERNAL;
  255. }
  256. }
  257. ZT_SDK_API ZT_CertificateList *ZT_Node_listCertificates(ZT_Node *node)
  258. {
  259. try {
  260. return reinterpret_cast<ZeroTier::Node *>(node)->listCertificates();
  261. } catch (...) {
  262. return nullptr;
  263. }
  264. }
  265. void ZT_Node_setNetworkUserPtr(ZT_Node *node, uint64_t nwid, void *ptr)
  266. {
  267. try {
  268. reinterpret_cast<ZeroTier::Node *>(node)->setNetworkUserPtr(nwid, ptr);
  269. } catch (...) {}
  270. }
  271. void ZT_Node_setInterfaceAddresses(ZT_Node *node, const ZT_InterfaceAddress *addrs, unsigned int addrCount)
  272. {
  273. try {
  274. reinterpret_cast<ZeroTier::Node *>(node)->setInterfaceAddresses(addrs, addrCount);
  275. } catch (...) {}
  276. }
  277. enum ZT_ResultCode ZT_Node_addPeer(
  278. ZT_Node *node,
  279. void *tptr,
  280. const ZT_Identity *id)
  281. {
  282. try {
  283. return reinterpret_cast<ZeroTier::Node *>(node)->addPeer(tptr, id);
  284. } catch (...) {
  285. return ZT_RESULT_ERROR_INTERNAL;
  286. }
  287. }
  288. int ZT_Node_sendUserMessage(ZT_Node *node, void *tptr, uint64_t dest, uint64_t typeId, const void *data, unsigned int len)
  289. {
  290. try {
  291. return reinterpret_cast<ZeroTier::Node *>(node)->sendUserMessage(tptr, dest, typeId, data, len);
  292. } catch (...) {
  293. return 0;
  294. }
  295. }
  296. void ZT_Node_setController(ZT_Node *node, void *networkControllerInstance)
  297. {
  298. try {
  299. reinterpret_cast<ZeroTier::Node *>(node)->setController(networkControllerInstance);
  300. } catch (...) {}
  301. }
  302. /********************************************************************************************************************/
  303. ZT_Locator *ZT_Locator_create(
  304. int64_t ts,
  305. const ZT_Endpoint *endpoints,
  306. const ZT_EndpointAttributes *endpointAttributes, // TODO: not used yet
  307. unsigned int endpointCount,
  308. const ZT_Identity *signer)
  309. {
  310. try {
  311. if ((ts <= 0) || (!endpoints) || (endpointCount == 0) || (!signer))
  312. return nullptr;
  313. ZeroTier::Locator *loc = new ZeroTier::Locator();
  314. for (unsigned int i = 0;i < endpointCount;++i)
  315. loc->add(reinterpret_cast< const ZeroTier::Endpoint * >(endpoints)[i], ZeroTier::Locator::EndpointAttributes::DEFAULT);
  316. if (!loc->sign(ts, *reinterpret_cast< const ZeroTier::Identity * >(signer))) {
  317. delete loc;
  318. return nullptr;
  319. }
  320. return reinterpret_cast<ZT_Locator *>(loc);
  321. } catch (...) {
  322. return nullptr;
  323. }
  324. }
  325. ZT_Locator *ZT_Locator_fromString(const char *str)
  326. {
  327. try {
  328. if (!str)
  329. return nullptr;
  330. ZeroTier::Locator *loc = new ZeroTier::Locator();
  331. if (!loc->fromString(str)) {
  332. delete loc;
  333. return nullptr;
  334. }
  335. return reinterpret_cast<ZT_Locator *>(loc);
  336. } catch ( ... ) {
  337. return nullptr;
  338. }
  339. }
  340. ZT_Locator *ZT_Locator_unmarshal(
  341. const void *data,
  342. unsigned int len)
  343. {
  344. try {
  345. if ((!data) || (len == 0))
  346. return nullptr;
  347. ZeroTier::Locator *loc = new ZeroTier::Locator();
  348. if (loc->unmarshal(reinterpret_cast<const uint8_t *>(data), (int) len) <= 0) {
  349. delete loc;
  350. return nullptr;
  351. }
  352. return reinterpret_cast<ZT_Locator *>(loc);
  353. } catch (...) {
  354. return nullptr;
  355. }
  356. }
  357. int ZT_Locator_marshal(const ZT_Locator *loc, void *buf, unsigned int bufSize)
  358. {
  359. if ((!loc) || (bufSize < ZT_LOCATOR_MARSHAL_SIZE_MAX))
  360. return -1;
  361. return reinterpret_cast<const ZeroTier::Locator *>(loc)->marshal(reinterpret_cast<uint8_t *>(buf), false);
  362. }
  363. char *ZT_Locator_toString(
  364. const ZT_Locator *loc,
  365. char *buf,
  366. int capacity)
  367. {
  368. if ((!loc) || (capacity < ZT_LOCATOR_STRING_SIZE_MAX))
  369. return nullptr;
  370. return reinterpret_cast<const ZeroTier::Locator *>(loc)->toString(buf);
  371. }
  372. const ZT_Fingerprint *ZT_Locator_fingerprint(const ZT_Locator *loc)
  373. {
  374. if (!loc)
  375. return nullptr;
  376. return (ZT_Fingerprint *) (&(reinterpret_cast<const ZeroTier::Locator *>(loc)->signer()));
  377. }
  378. int64_t ZT_Locator_timestamp(const ZT_Locator *loc)
  379. {
  380. if (!loc)
  381. return 0;
  382. return reinterpret_cast<const ZeroTier::Locator *>(loc)->timestamp();
  383. }
  384. unsigned int ZT_Locator_endpointCount(const ZT_Locator *loc)
  385. {
  386. return (loc) ? (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()) : 0;
  387. }
  388. const ZT_Endpoint *ZT_Locator_endpoint(const ZT_Locator *loc, const unsigned int ep)
  389. {
  390. if (!loc)
  391. return nullptr;
  392. if (ep >= (unsigned int) (reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints().size()))
  393. return nullptr;
  394. return reinterpret_cast<const ZT_Endpoint *>(&(reinterpret_cast<const ZeroTier::Locator *>(loc)->endpoints()[ep]));
  395. }
  396. int ZT_Locator_verify(const ZT_Locator *loc, const ZT_Identity *signer)
  397. {
  398. if ((!loc) || (!signer))
  399. return 0;
  400. return reinterpret_cast<const ZeroTier::Locator *>(loc)->verify(*reinterpret_cast<const ZeroTier::Identity *>(signer)) ? 1 : 0;
  401. }
  402. void ZT_Locator_delete(ZT_Locator *loc)
  403. {
  404. if (loc)
  405. delete reinterpret_cast<ZeroTier::Locator *>(loc);
  406. }
  407. /********************************************************************************************************************/
  408. ZT_Identity *ZT_Identity_new(enum ZT_IdentityType type)
  409. {
  410. if ((type != ZT_IDENTITY_TYPE_C25519) && (type != ZT_IDENTITY_TYPE_P384))
  411. return nullptr;
  412. try {
  413. ZeroTier::Identity *const id = new ZeroTier::Identity();
  414. id->generate((ZeroTier::Identity::Type)type);
  415. return reinterpret_cast<ZT_Identity *>(id);
  416. } catch (...) {
  417. return nullptr;
  418. }
  419. }
  420. ZT_Identity *ZT_Identity_fromString(const char *idStr)
  421. {
  422. if (!idStr)
  423. return nullptr;
  424. try {
  425. ZeroTier::Identity *const id = new ZeroTier::Identity();
  426. if (!id->fromString(idStr)) {
  427. delete id;
  428. return nullptr;
  429. }
  430. return reinterpret_cast<ZT_Identity *>(id);
  431. } catch (...) {
  432. return nullptr;
  433. }
  434. }
  435. int ZT_Identity_validate(const ZT_Identity *id)
  436. {
  437. if (!id)
  438. return 0;
  439. return reinterpret_cast<const ZeroTier::Identity *>(id)->locallyValidate() ? 1 : 0;
  440. }
  441. unsigned int ZT_Identity_sign(const ZT_Identity *id, const void *data, unsigned int len, void *signature, unsigned int signatureBufferLength)
  442. {
  443. if (!id)
  444. return 0;
  445. if (signatureBufferLength < ZT_SIGNATURE_BUFFER_SIZE)
  446. return 0;
  447. return reinterpret_cast<const ZeroTier::Identity *>(id)->sign(data, len, signature, signatureBufferLength);
  448. }
  449. int ZT_Identity_verify(const ZT_Identity *id, const void *data, unsigned int len, const void *signature, unsigned int sigLen)
  450. {
  451. if ((!id) || (!signature) || (!sigLen))
  452. return 0;
  453. return reinterpret_cast<const ZeroTier::Identity *>(id)->verify(data, len, signature, sigLen) ? 1 : 0;
  454. }
  455. enum ZT_IdentityType ZT_Identity_type(const ZT_Identity *id)
  456. {
  457. if (!id)
  458. return (ZT_IdentityType)0;
  459. return (enum ZT_IdentityType)reinterpret_cast<const ZeroTier::Identity *>(id)->type();
  460. }
  461. char *ZT_Identity_toString(const ZT_Identity *id, char *buf, int capacity, int includePrivate)
  462. {
  463. if ((!id) || (!buf) || (capacity < ZT_IDENTITY_STRING_BUFFER_LENGTH))
  464. return nullptr;
  465. reinterpret_cast<const ZeroTier::Identity *>(id)->toString(includePrivate != 0, buf);
  466. return buf;
  467. }
  468. int ZT_Identity_hasPrivate(const ZT_Identity *id)
  469. {
  470. if (!id)
  471. return 0;
  472. return reinterpret_cast<const ZeroTier::Identity *>(id)->hasPrivate() ? 1 : 0;
  473. }
  474. uint64_t ZT_Identity_address(const ZT_Identity *id)
  475. {
  476. if (!id)
  477. return 0;
  478. return reinterpret_cast<const ZeroTier::Identity *>(id)->address();
  479. }
  480. const ZT_Fingerprint *ZT_Identity_fingerprint(const ZT_Identity *id)
  481. {
  482. if (!id)
  483. return nullptr;
  484. return &(reinterpret_cast<const ZeroTier::Identity *>(id)->fingerprint());
  485. }
  486. void ZT_Identity_delete(ZT_Identity *id)
  487. {
  488. if (id)
  489. delete reinterpret_cast<ZeroTier::Identity *>(id);
  490. }
  491. /********************************************************************************************************************/
  492. int ZT_Certificate_newSubjectUniqueId(
  493. enum ZT_CertificateUniqueIdType type,
  494. void *uniqueId,
  495. int *uniqueIdSize,
  496. void *uniqueIdPrivate,
  497. int *uniqueIdPrivateSize)
  498. {
  499. try {
  500. switch (type) {
  501. case ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384:
  502. if ((*uniqueIdSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE) || (*uniqueIdPrivateSize < ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE))
  503. return ZT_RESULT_ERROR_BAD_PARAMETER;
  504. *uniqueIdSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_SIZE;
  505. *uniqueIdPrivateSize = ZT_CERTIFICATE_UNIQUE_ID_TYPE_NIST_P_384_PRIVATE_SIZE;
  506. ZeroTier::Certificate::createSubjectUniqueId(reinterpret_cast<uint8_t *>(uniqueId), reinterpret_cast<uint8_t *>(uniqueIdPrivate));
  507. return ZT_RESULT_OK;
  508. }
  509. return ZT_RESULT_ERROR_BAD_PARAMETER;
  510. } catch (...) {
  511. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  512. }
  513. }
  514. int ZT_Certificate_newCSR(
  515. const ZT_Certificate_Subject *subject,
  516. const void *uniqueId,
  517. int uniqueIdSize,
  518. const void *uniqueIdPrivate,
  519. int uniqueIdPrivateSize,
  520. void *csr,
  521. int *csrSize)
  522. {
  523. try {
  524. if (!subject)
  525. return ZT_RESULT_ERROR_BAD_PARAMETER;
  526. const ZeroTier::Vector< uint8_t > csrV(ZeroTier::Certificate::createCSR(*subject, uniqueId, uniqueIdSize, uniqueIdPrivate, uniqueIdPrivateSize));
  527. if ((int)csrV.size() > *csrSize)
  528. return ZT_RESULT_ERROR_BAD_PARAMETER;
  529. ZeroTier::Utils::copy(csr, csrV.data(), (unsigned int)csrV.size());
  530. *csrSize = (int)csrV.size();
  531. return ZT_RESULT_OK;
  532. } catch (...) {
  533. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  534. }
  535. }
  536. int ZT_Certificate_sign(
  537. const ZT_Certificate *cert,
  538. const ZT_Identity *signer,
  539. void *signedCert,
  540. int *signedCertSize)
  541. {
  542. try {
  543. if (!cert)
  544. return ZT_RESULT_ERROR_BAD_PARAMETER;
  545. ZeroTier::Certificate c(*cert);
  546. if (!c.sign(*reinterpret_cast<const ZeroTier::Identity *>(signer)))
  547. return ZT_RESULT_ERROR_INTERNAL;
  548. const ZeroTier::Vector< uint8_t > enc(c.encode());
  549. if ((int)enc.size() > *signedCertSize)
  550. return ZT_RESULT_ERROR_BAD_PARAMETER;
  551. ZeroTier::Utils::copy(signedCert, enc.data(), (unsigned int)enc.size());
  552. *signedCertSize = (int)enc.size();
  553. return ZT_RESULT_OK;
  554. } catch (...) {
  555. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  556. }
  557. }
  558. enum ZT_CertificateError ZT_Certificate_decode(
  559. const ZT_Certificate **decodedCert,
  560. const void *cert,
  561. int certSize,
  562. int verify)
  563. {
  564. try {
  565. if ((!decodedCert) || (!cert) || (certSize <= 0))
  566. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  567. *decodedCert = nullptr;
  568. ZeroTier::Certificate *const c = new ZeroTier::Certificate();
  569. if (!c->decode(cert, certSize)) {
  570. delete c;
  571. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  572. }
  573. if (verify) {
  574. const ZT_CertificateError err = c->verify();
  575. if (err != ZT_CERTIFICATE_ERROR_NONE) {
  576. delete c;
  577. return err;
  578. }
  579. }
  580. *decodedCert = c;
  581. return ZT_CERTIFICATE_ERROR_NONE;
  582. } catch (...) {
  583. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  584. }
  585. }
  586. int ZT_Certificate_encode(
  587. const ZT_Certificate *cert,
  588. void *encoded,
  589. int *encodedSize)
  590. {
  591. try {
  592. if ((!cert) || (!encoded) || (!encodedSize))
  593. return ZT_RESULT_ERROR_BAD_PARAMETER;
  594. ZeroTier::Certificate c(*cert);
  595. ZeroTier::Vector< uint8_t > enc(c.encode());
  596. if ((int)enc.size() > *encodedSize)
  597. return ZT_RESULT_ERROR_BAD_PARAMETER;
  598. ZeroTier::Utils::copy(encoded, enc.data(), (unsigned int)enc.size());
  599. *encodedSize = (int)enc.size();
  600. return ZT_RESULT_OK;
  601. } catch (...) {
  602. return ZT_RESULT_FATAL_ERROR_INTERNAL;
  603. }
  604. }
  605. enum ZT_CertificateError ZT_Certificate_verify(const ZT_Certificate *cert)
  606. {
  607. try {
  608. if (!cert)
  609. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  610. return ZeroTier::Certificate(*cert).verify();
  611. } catch (...) {
  612. return ZT_CERTIFICATE_ERROR_INVALID_FORMAT;
  613. }
  614. }
  615. const ZT_Certificate *ZT_Certificate_clone(const ZT_Certificate *cert)
  616. {
  617. try {
  618. if (!cert)
  619. return nullptr;
  620. return (const ZT_Certificate *)(new ZeroTier::Certificate(*cert));
  621. } catch (...) {
  622. return nullptr;
  623. }
  624. }
  625. void ZT_Certificate_delete(const ZT_Certificate *cert)
  626. {
  627. try {
  628. if (cert)
  629. delete (const ZeroTier::Certificate *)(cert);
  630. } catch (...) {}
  631. }
  632. /********************************************************************************************************************/
  633. char *ZT_Endpoint_toString(
  634. const ZT_Endpoint *ep,
  635. char *buf,
  636. int capacity)
  637. {
  638. if ((!ep) || (!buf) || (capacity < ZT_ENDPOINT_STRING_SIZE_MAX))
  639. return nullptr;
  640. return reinterpret_cast<const ZeroTier::Endpoint *>(ep)->toString(buf);
  641. }
  642. int ZT_Endpoint_fromString(
  643. ZT_Endpoint *ep,
  644. const char *str)
  645. {
  646. if ((!ep) || (!str))
  647. return ZT_RESULT_ERROR_BAD_PARAMETER;
  648. return reinterpret_cast<ZeroTier::Endpoint *>(ep)->fromString(str) ? ZT_RESULT_OK : ZT_RESULT_ERROR_BAD_PARAMETER;
  649. }
  650. /********************************************************************************************************************/
  651. } // extern "C"