2
0

CapabilityCredential.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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 "CapabilityCredential.hpp"
  14. #include "Utils.hpp"
  15. #include "Constants.hpp"
  16. #include "MAC.hpp"
  17. namespace ZeroTier {
  18. bool CapabilityCredential::sign(const Identity &from, const Address &to) noexcept
  19. {
  20. uint8_t buf[ZT_CAPABILITY_MARSHAL_SIZE_MAX + 16];
  21. m_issuedTo = to;
  22. m_signedBy = from.address();
  23. m_signatureLength = from.sign(buf, (unsigned int) marshal(buf, true), m_signature, sizeof(m_signature));
  24. return m_signatureLength > 0;
  25. }
  26. int CapabilityCredential::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX], const bool forSign) const noexcept
  27. {
  28. int p = 0;
  29. if (forSign) {
  30. for (int k = 0;k < 8;++k)
  31. data[p++] = 0x7f;
  32. }
  33. Utils::storeBigEndian<uint64_t>(data + p, m_nwid);
  34. p += 8;
  35. Utils::storeBigEndian<uint64_t>(data + p, (uint64_t) m_ts);
  36. p += 8;
  37. Utils::storeBigEndian<uint32_t>(data + p, m_id);
  38. p += 4;
  39. Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_ruleCount);
  40. p += 2;
  41. p += CapabilityCredential::marshalVirtualNetworkRules(data + p, m_rules, m_ruleCount);
  42. // LEGACY: older versions supported multiple records with this being a maximum custody
  43. // chain length. This is deprecated so set the max chain length to one.
  44. data[p++] = (uint8_t) 1;
  45. if (!forSign) {
  46. m_issuedTo.copyTo(data + p);
  47. p += ZT_ADDRESS_LENGTH;
  48. m_signedBy.copyTo(data + 0);
  49. p += ZT_ADDRESS_LENGTH;
  50. data[p++] = 1; // LEGACY: old versions require a reserved byte here
  51. Utils::storeBigEndian<uint16_t>(data + p, (uint16_t) m_signatureLength);
  52. p += 2;
  53. Utils::copy(data + p, m_signature, m_signatureLength);
  54. p += (int) m_signatureLength;
  55. // LEGACY: older versions supported more than one record terminated by a zero address.
  56. for (int k = 0;k < ZT_ADDRESS_LENGTH;++k)
  57. data[p++] = 0;
  58. }
  59. data[p++] = 0;
  60. data[p++] = 0; // uint16_t size of additional fields, currently 0
  61. if (forSign) {
  62. for (int k = 0;k < 8;++k)
  63. data[p++] = 0x7f;
  64. }
  65. return p;
  66. }
  67. int CapabilityCredential::unmarshal(const uint8_t *data, int len) noexcept
  68. {
  69. if (len < 22)
  70. return -1;
  71. m_nwid = Utils::loadBigEndian<uint64_t>(data);
  72. m_ts = (int64_t) Utils::loadBigEndian<uint64_t>(data + 8);
  73. m_id = Utils::loadBigEndian<uint32_t>(data + 16);
  74. const unsigned int rc = Utils::loadBigEndian<uint16_t>(data + 20);
  75. if (rc > ZT_MAX_CAPABILITY_RULES)
  76. return -1;
  77. const int rulesLen = unmarshalVirtualNetworkRules(data + 22, len - 22, m_rules, m_ruleCount, rc);
  78. if (rulesLen < 0)
  79. return rulesLen;
  80. int p = 22 + rulesLen;
  81. if (p >= len)
  82. return -1;
  83. ++p; // LEGACY: skip old max record count
  84. // LEGACY: since it was once supported to have multiple records, scan them all. Since
  85. // this feature was never used, just set the signature and issued to and other related
  86. // fields each time and we should only ever see one. If there's more than one and the
  87. // last is not the controller, this credential will just fail validity check.
  88. for (unsigned int i = 0;;++i) {
  89. if ((p + ZT_ADDRESS_LENGTH) > len)
  90. return -1;
  91. const Address to(data + p);
  92. p += ZT_ADDRESS_LENGTH;
  93. if (!to)
  94. break;
  95. m_issuedTo = to;
  96. if ((p + ZT_ADDRESS_LENGTH) > len)
  97. return -1;
  98. m_signedBy.setTo(data + p);
  99. p += ZT_ADDRESS_LENGTH + 1; // LEGACY: +1 to skip reserved field
  100. if ((p + 2) > len)
  101. return -1;
  102. m_signatureLength = Utils::loadBigEndian<uint16_t>(data + p);
  103. p += 2;
  104. if ((m_signatureLength > sizeof(m_signature)) || ((p + (int) m_signatureLength) > len))
  105. return -1;
  106. Utils::copy(m_signature, data + p, m_signatureLength);
  107. p += (int) m_signatureLength;
  108. }
  109. if ((p + 2) > len)
  110. return -1;
  111. p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
  112. if (p > len)
  113. return -1;
  114. return p;
  115. }
  116. int CapabilityCredential::marshalVirtualNetworkRules(uint8_t *data, const ZT_VirtualNetworkRule *const rules, const unsigned int ruleCount) noexcept
  117. {
  118. int p = 0;
  119. for (unsigned int i = 0;i < ruleCount;++i) {
  120. data[p++] = rules[i].t;
  121. switch ((ZT_VirtualNetworkRuleType) (rules[i].t & 0x3fU)) {
  122. default:
  123. data[p++] = 0;
  124. break;
  125. case ZT_NETWORK_RULE_ACTION_TEE:
  126. case ZT_NETWORK_RULE_ACTION_WATCH:
  127. case ZT_NETWORK_RULE_ACTION_REDIRECT:
  128. data[p++] = 14;
  129. Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.fwd.address);
  130. p += 8;
  131. Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.fwd.flags);
  132. p += 4;
  133. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.fwd.length);
  134. p += 2;
  135. break;
  136. case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
  137. case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
  138. data[p++] = 5;
  139. Address(rules[i].v.zt).copyTo(data + p);
  140. p += ZT_ADDRESS_LENGTH;
  141. break;
  142. case ZT_NETWORK_RULE_MATCH_VLAN_ID:
  143. data[p++] = 2;
  144. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.vlanId);
  145. p += 2;
  146. break;
  147. case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
  148. data[p++] = 1;
  149. data[p++] = rules[i].v.vlanPcp;
  150. break;
  151. case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
  152. data[p++] = 1;
  153. data[p++] = rules[i].v.vlanDei;
  154. break;
  155. case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
  156. case ZT_NETWORK_RULE_MATCH_MAC_DEST:
  157. data[p++] = 6;
  158. MAC(rules[i].v.mac).copyTo(data + p);
  159. p += 6;
  160. break;
  161. case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
  162. case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
  163. data[p++] = 5;
  164. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[0];
  165. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[1];
  166. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[2];
  167. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[3];
  168. data[p++] = rules[i].v.ipv4.mask;
  169. break;
  170. case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
  171. case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
  172. data[p++] = 17;
  173. Utils::copy<16>(data + p, rules[i].v.ipv6.ip);
  174. p += 16;
  175. data[p++] = rules[i].v.ipv6.mask;
  176. break;
  177. case ZT_NETWORK_RULE_MATCH_IP_TOS:
  178. data[p++] = 3;
  179. data[p++] = rules[i].v.ipTos.mask;
  180. data[p++] = rules[i].v.ipTos.value[0];
  181. data[p++] = rules[i].v.ipTos.value[1];
  182. break;
  183. case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
  184. data[p++] = 1;
  185. data[p++] = rules[i].v.ipProtocol;
  186. break;
  187. case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
  188. data[p++] = 2;
  189. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.etherType);
  190. p += 2;
  191. break;
  192. case ZT_NETWORK_RULE_MATCH_ICMP:
  193. data[p++] = 3;
  194. data[p++] = rules[i].v.icmp.type;
  195. data[p++] = rules[i].v.icmp.code;
  196. data[p++] = rules[i].v.icmp.flags;
  197. break;
  198. case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
  199. case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
  200. data[p++] = 4;
  201. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.port[0]);
  202. p += 2;
  203. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.port[1]);
  204. p += 2;
  205. break;
  206. case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
  207. data[p++] = 8;
  208. Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.characteristics);
  209. p += 8;
  210. break;
  211. case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
  212. data[p++] = 4;
  213. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.frameSize[0]);
  214. p += 2;
  215. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.frameSize[1]);
  216. p += 2;
  217. break;
  218. case ZT_NETWORK_RULE_MATCH_RANDOM:
  219. data[p++] = 4;
  220. Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.randomProbability);
  221. p += 4;
  222. break;
  223. case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
  224. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
  225. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
  226. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
  227. case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
  228. case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
  229. case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
  230. data[p++] = 8;
  231. Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.tag.id);
  232. p += 4;
  233. Utils::storeBigEndian<uint32_t>(data + p, rules[i].v.tag.value);
  234. p += 4;
  235. break;
  236. case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
  237. data[p++] = 19;
  238. Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start);
  239. p += 8;
  240. Utils::storeBigEndian<uint64_t>(data + p, rules[i].v.intRange.start + (uint64_t) rules[i].v.intRange.end);
  241. p += 8;
  242. Utils::storeBigEndian<uint16_t>(data + p, rules[i].v.intRange.idx);
  243. p += 2;
  244. data[p++] = rules[i].v.intRange.format;
  245. break;
  246. }
  247. }
  248. return p;
  249. }
  250. int CapabilityCredential::unmarshalVirtualNetworkRules(const uint8_t *const data, const int len, ZT_VirtualNetworkRule *const rules, unsigned int &ruleCount, const unsigned int maxRuleCount) noexcept
  251. {
  252. int p = 0;
  253. unsigned int rc = 0;
  254. while (rc < maxRuleCount) {
  255. if (p >= len)
  256. return -1;
  257. rules[ruleCount].t = data[p++];
  258. const int fieldLen = (int) data[p++];
  259. if ((p + fieldLen) > len)
  260. return -1;
  261. switch ((ZT_VirtualNetworkRuleType) (rules[ruleCount].t & 0x3fU)) {
  262. default:
  263. break;
  264. case ZT_NETWORK_RULE_ACTION_TEE:
  265. case ZT_NETWORK_RULE_ACTION_WATCH:
  266. case ZT_NETWORK_RULE_ACTION_REDIRECT:
  267. if ((p + 14) > len) return -1;
  268. rules[ruleCount].v.fwd.address = Utils::loadBigEndian<uint64_t>(data + p);
  269. p += 8;
  270. rules[ruleCount].v.fwd.flags = Utils::loadBigEndian<uint32_t>(data + p);
  271. p += 4;
  272. rules[ruleCount].v.fwd.length = Utils::loadBigEndian<uint16_t>(data + p);
  273. p += 2;
  274. break;
  275. case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
  276. case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
  277. if ((p + ZT_ADDRESS_LENGTH) > len) return -1;
  278. rules[ruleCount].v.zt = Address(data + p).toInt();
  279. p += ZT_ADDRESS_LENGTH;
  280. break;
  281. case ZT_NETWORK_RULE_MATCH_VLAN_ID:
  282. if ((p + 2) > len) return -1;
  283. rules[ruleCount].v.vlanId = Utils::loadBigEndian<uint16_t>(data + p);
  284. p += 2;
  285. break;
  286. case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
  287. if ((p + 1) > len) return -1;
  288. rules[ruleCount].v.vlanPcp = data[p++];
  289. break;
  290. case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
  291. if ((p + 1) > len) return -1;
  292. rules[ruleCount].v.vlanDei = data[p++];
  293. break;
  294. case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
  295. case ZT_NETWORK_RULE_MATCH_MAC_DEST:
  296. if ((p + 6) > len) return -1;
  297. Utils::copy<6>(rules[ruleCount].v.mac, data + p);
  298. p += 6;
  299. break;
  300. case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
  301. case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
  302. if ((p + 5) > len) return -1;
  303. Utils::copy<4>(&(rules[ruleCount].v.ipv4.ip), data + p);
  304. p += 4;
  305. rules[ruleCount].v.ipv4.mask = data[p++];
  306. break;
  307. case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
  308. case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
  309. if ((p + 17) > len) return -1;
  310. Utils::copy<16>(rules[ruleCount].v.ipv6.ip, data + p);
  311. p += 16;
  312. rules[ruleCount].v.ipv6.mask = data[p++];
  313. break;
  314. case ZT_NETWORK_RULE_MATCH_IP_TOS:
  315. if ((p + 3) > len) return -1;
  316. rules[ruleCount].v.ipTos.mask = data[p++];
  317. rules[ruleCount].v.ipTos.value[0] = data[p++];
  318. rules[ruleCount].v.ipTos.value[1] = data[p++];
  319. break;
  320. case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
  321. if ((p + 1) > len) return -1;
  322. rules[ruleCount].v.ipProtocol = data[p++];
  323. break;
  324. case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
  325. if ((p + 2) > len) return -1;
  326. rules[ruleCount].v.etherType = Utils::loadBigEndian<uint16_t>(data + p);
  327. p += 2;
  328. break;
  329. case ZT_NETWORK_RULE_MATCH_ICMP:
  330. if ((p + 3) > len) return -1;
  331. rules[ruleCount].v.icmp.type = data[p++];
  332. rules[ruleCount].v.icmp.code = data[p++];
  333. rules[ruleCount].v.icmp.flags = data[p++];
  334. break;
  335. case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
  336. case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
  337. if ((p + 4) > len) return -1;
  338. rules[ruleCount].v.port[0] = Utils::loadBigEndian<uint16_t>(data + p);
  339. p += 2;
  340. rules[ruleCount].v.port[1] = Utils::loadBigEndian<uint16_t>(data + p);
  341. p += 2;
  342. break;
  343. case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
  344. if ((p + 8) > len) return -1;
  345. rules[ruleCount].v.characteristics = Utils::loadBigEndian<uint64_t>(data + p);
  346. p += 8;
  347. break;
  348. case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
  349. if ((p + 4) > len) return -1;
  350. rules[ruleCount].v.frameSize[0] = Utils::loadBigEndian<uint16_t>(data + p);
  351. p += 2;
  352. rules[ruleCount].v.frameSize[1] = Utils::loadBigEndian<uint16_t>(data + p);
  353. p += 2;
  354. break;
  355. case ZT_NETWORK_RULE_MATCH_RANDOM:
  356. if ((p + 4) > len) return -1;
  357. rules[ruleCount].v.randomProbability = Utils::loadBigEndian<uint32_t>(data + p);
  358. p += 4;
  359. break;
  360. case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
  361. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
  362. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
  363. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
  364. case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
  365. case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
  366. case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
  367. if ((p + 4) > len) return -1;
  368. rules[ruleCount].v.tag.id = Utils::loadBigEndian<uint32_t>(data + p);
  369. p += 4;
  370. rules[ruleCount].v.tag.value = Utils::loadBigEndian<uint32_t>(data + p);
  371. p += 4;
  372. break;
  373. case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
  374. if ((p + 19) > len) return -1;
  375. rules[ruleCount].v.intRange.start = Utils::loadBigEndian<uint64_t>(data + p);
  376. p += 8;
  377. rules[ruleCount].v.intRange.end = (uint32_t) (Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start);
  378. p += 8;
  379. rules[ruleCount].v.intRange.idx = Utils::loadBigEndian<uint16_t>(data + p);
  380. p += 2;
  381. rules[ruleCount].v.intRange.format = data[p++];
  382. break;
  383. }
  384. p += fieldLen;
  385. ++rc;
  386. }
  387. ruleCount = rc;
  388. return p;
  389. }
  390. } // namespace ZeroTier