Capability.cpp 13 KB

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