Capability.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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)
  19. {
  20. uint8_t buf[ZT_CAPABILITY_MARSHAL_SIZE_MAX + 16];
  21. try {
  22. for(unsigned int i=0;((i<_maxCustodyChainLength)&&(i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH));++i) {
  23. if (!(_custody[i].to)) {
  24. _custody[i].to = to;
  25. _custody[i].from = from.address();
  26. _custody[i].signatureLength = from.sign(buf,(unsigned int)marshal(buf,true),_custody[i].signature,sizeof(_custody[i].signature));
  27. return true;
  28. }
  29. }
  30. } catch ( ... ) {}
  31. return false;
  32. }
  33. int Capability::marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],const bool forSign) const
  34. {
  35. int p = 0;
  36. if (forSign) {
  37. for(int k=0;k<8;++k)
  38. data[p++] = 0x7f;
  39. }
  40. Utils::storeBigEndian<uint64_t>(data + p,_nwid); p += 8;
  41. Utils::storeBigEndian<uint64_t>(data + p,(uint64_t)_ts); p += 8;
  42. Utils::storeBigEndian<uint32_t>(data + p,_id); p += 4;
  43. Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_ruleCount); p += 2;
  44. p += Capability::marshalVirtualNetworkRules(data + 22,_rules,_ruleCount);
  45. data[p++] = (uint8_t)_maxCustodyChainLength;
  46. if (!forSign) {
  47. for(unsigned int i=0;;++i) {
  48. if ((i < _maxCustodyChainLength)&&(i < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)&&(_custody[i].to)) {
  49. _custody[i].to.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
  50. _custody[i].from.copyTo(data + p); p += ZT_ADDRESS_LENGTH;
  51. data[p++] = 1;
  52. Utils::storeBigEndian<uint16_t>(data + p,(uint16_t)_custody[i].signatureLength); p += 2;
  53. for(unsigned int k=0;k<_custody[i].signatureLength;++k)
  54. data[p++] = _custody[i].signature[k];
  55. } else {
  56. for(int k=0;k<ZT_ADDRESS_LENGTH;++k)
  57. data[p++] = 0;
  58. break;
  59. }
  60. }
  61. }
  62. data[p++] = 0;
  63. data[p++] = 0; // uint16_t size of additional fields, currently 0
  64. if (forSign) {
  65. for(int k=0;k<8;++k)
  66. data[p++] = 0x7f;
  67. }
  68. return p;
  69. }
  70. int Capability::unmarshal(const uint8_t *data,int len)
  71. {
  72. if (len < 22)
  73. return -1;
  74. _nwid = Utils::loadBigEndian<uint64_t>(data);
  75. _ts = (int64_t)Utils::loadBigEndian<uint64_t>(data + 8);
  76. _id = Utils::loadBigEndian<uint32_t>(data + 16);
  77. const unsigned int rc = Utils::loadBigEndian<uint16_t>(data + 20);;
  78. if (rc > ZT_MAX_CAPABILITY_RULES)
  79. return -1;
  80. const int rulesLen = unmarshalVirtualNetworkRules(data + 22,len - 22,_rules,_ruleCount,rc);
  81. if (rulesLen < 0)
  82. return rulesLen;
  83. int p = 22 + rulesLen;
  84. if (p >= len)
  85. return -1;
  86. _maxCustodyChainLength = data[p++];
  87. for(unsigned int i=0;;++i) {
  88. if ((p + ZT_ADDRESS_LENGTH) > len)
  89. return -1;
  90. const Address to(data + p); p += ZT_ADDRESS_LENGTH;
  91. if (!to) break;
  92. if ((i >= _maxCustodyChainLength)||(i >= ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH))
  93. return -1;
  94. _custody[i].to = to;
  95. if ((p + ZT_ADDRESS_LENGTH) > len)
  96. return -1;
  97. _custody[i].from.setTo(data + p); p += ZT_ADDRESS_LENGTH + 1;
  98. if ((p + 2) > len)
  99. return -1;
  100. const unsigned int sl = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  101. _custody[i].signatureLength = sl;
  102. if ((sl > sizeof(_custody[i].signature))||((p + (int)sl) > len))
  103. return -1;
  104. memcpy(_custody[i].signature,data + p,sl); p += (int)sl;
  105. }
  106. if ((p + 2) > len)
  107. return -1;
  108. p += 2 + Utils::loadBigEndian<uint16_t>(data + p);
  109. if (p > len)
  110. return -1;
  111. return p;
  112. }
  113. int Capability::marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *const rules,const unsigned int ruleCount)
  114. {
  115. int p = 0;
  116. for(unsigned int i=0;i<ruleCount;++i) {
  117. data[p++] = rules[i].t;
  118. switch((ZT_VirtualNetworkRuleType)(rules[i].t & 0x3fU)) {
  119. default:
  120. data[p++] = 0;
  121. break;
  122. case ZT_NETWORK_RULE_ACTION_TEE:
  123. case ZT_NETWORK_RULE_ACTION_WATCH:
  124. case ZT_NETWORK_RULE_ACTION_REDIRECT:
  125. data[p++] = 14;
  126. Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.fwd.address); p += 8;
  127. Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.fwd.flags); p += 4;
  128. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.fwd.length); p += 2;
  129. break;
  130. case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
  131. case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
  132. data[p++] = 5;
  133. Address(rules[i].v.zt).copyTo(data + p); p += ZT_ADDRESS_LENGTH;
  134. break;
  135. case ZT_NETWORK_RULE_MATCH_VLAN_ID:
  136. data[p++] = 2;
  137. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.vlanId); p += 2;
  138. break;
  139. case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
  140. data[p++] = 1;
  141. data[p++] = rules[i].v.vlanPcp;
  142. break;
  143. case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
  144. data[p++] = 1;
  145. data[p++] = rules[i].v.vlanDei;
  146. break;
  147. case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
  148. case ZT_NETWORK_RULE_MATCH_MAC_DEST:
  149. data[p++] = 6;
  150. MAC(rules[i].v.mac).copyTo(data + p); p += 6;
  151. break;
  152. case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
  153. case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
  154. data[p++] = 5;
  155. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[0];
  156. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[1];
  157. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[2];
  158. data[p++] = reinterpret_cast<const uint8_t *>(&(rules[i].v.ipv4.ip))[3];
  159. data[p++] = rules[i].v.ipv4.mask;
  160. break;
  161. case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
  162. case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
  163. data[p++] = 17;
  164. for(int k=0;k<16;++k)
  165. data[p++] = rules[i].v.ipv6.ip[k];
  166. data[p++] = rules[i].v.ipv6.mask;
  167. break;
  168. case ZT_NETWORK_RULE_MATCH_IP_TOS:
  169. data[p++] = 3;
  170. data[p++] = rules[i].v.ipTos.mask;
  171. data[p++] = rules[i].v.ipTos.value[0];
  172. data[p++] = rules[i].v.ipTos.value[1];
  173. break;
  174. case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
  175. data[p++] = 1;
  176. data[p++] = rules[i].v.ipProtocol;
  177. break;
  178. case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
  179. data[p++] = 2;
  180. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.etherType); p += 2;
  181. break;
  182. case ZT_NETWORK_RULE_MATCH_ICMP:
  183. data[p++] = 3;
  184. data[p++] = rules[i].v.icmp.type;
  185. data[p++] = rules[i].v.icmp.code;
  186. data[p++] = rules[i].v.icmp.flags;
  187. break;
  188. case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
  189. case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
  190. data[p++] = 4;
  191. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.port[0]); p += 2;
  192. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.port[1]); p += 2;
  193. break;
  194. case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
  195. data[p++] = 8;
  196. Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.characteristics); p += 8;
  197. break;
  198. case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
  199. data[p++] = 4;
  200. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.frameSize[0]); p += 2;
  201. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.frameSize[1]); p += 2;
  202. break;
  203. case ZT_NETWORK_RULE_MATCH_RANDOM:
  204. data[p++] = 4;
  205. Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.randomProbability); p += 4;
  206. break;
  207. case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
  208. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
  209. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
  210. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
  211. case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
  212. case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
  213. case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
  214. data[p++] = 8;
  215. Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.tag.id); p += 4;
  216. Utils::storeBigEndian<uint32_t>(data + p,rules[i].v.tag.value); p += 4;
  217. break;
  218. case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
  219. data[p++] = 19;
  220. Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.intRange.start); p += 8;
  221. Utils::storeBigEndian<uint64_t>(data + p,rules[i].v.intRange.start + (uint64_t)rules[i].v.intRange.end); p += 8;
  222. Utils::storeBigEndian<uint16_t>(data + p,rules[i].v.intRange.idx); p += 2;
  223. data[p++] = rules[i].v.intRange.format;
  224. break;
  225. }
  226. }
  227. return p;
  228. }
  229. int Capability::unmarshalVirtualNetworkRules(const uint8_t *const data,const int len,ZT_VirtualNetworkRule *const rules,unsigned int &ruleCount,const unsigned int maxRuleCount)
  230. {
  231. int p = 0;
  232. unsigned int rc = 0;
  233. while (rc < maxRuleCount) {
  234. if (p >= len)
  235. return -1;
  236. rules[ruleCount].t = data[p++];
  237. const int fieldLen = (int)data[p++];
  238. if ((p + fieldLen) > len)
  239. return -1;
  240. switch((ZT_VirtualNetworkRuleType)(rules[ruleCount].t & 0x3f)) {
  241. default:
  242. break;
  243. case ZT_NETWORK_RULE_ACTION_TEE:
  244. case ZT_NETWORK_RULE_ACTION_WATCH:
  245. case ZT_NETWORK_RULE_ACTION_REDIRECT:
  246. if ((p + 14) > len) return -1;
  247. rules[ruleCount].v.fwd.address = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
  248. rules[ruleCount].v.fwd.flags = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
  249. rules[ruleCount].v.fwd.length = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  250. break;
  251. case ZT_NETWORK_RULE_MATCH_SOURCE_ZEROTIER_ADDRESS:
  252. case ZT_NETWORK_RULE_MATCH_DEST_ZEROTIER_ADDRESS:
  253. if ((p + ZT_ADDRESS_LENGTH) > len) return -1;
  254. rules[ruleCount].v.zt = Address(data + p).toInt(); p += ZT_ADDRESS_LENGTH;
  255. break;
  256. case ZT_NETWORK_RULE_MATCH_VLAN_ID:
  257. if ((p + 2) > len) return -1;
  258. rules[ruleCount].v.vlanId = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  259. break;
  260. case ZT_NETWORK_RULE_MATCH_VLAN_PCP:
  261. if ((p + 1) > len) return -1;
  262. rules[ruleCount].v.vlanPcp = data[p++];
  263. break;
  264. case ZT_NETWORK_RULE_MATCH_VLAN_DEI:
  265. if ((p + 1) > len) return -1;
  266. rules[ruleCount].v.vlanDei = data[p++];
  267. break;
  268. case ZT_NETWORK_RULE_MATCH_MAC_SOURCE:
  269. case ZT_NETWORK_RULE_MATCH_MAC_DEST:
  270. if ((p + 6) > len) return -1;
  271. memcpy(rules[ruleCount].v.mac,data + p,6); p += 6;
  272. break;
  273. case ZT_NETWORK_RULE_MATCH_IPV4_SOURCE:
  274. case ZT_NETWORK_RULE_MATCH_IPV4_DEST:
  275. if ((p + 5) > len) return -1;
  276. memcpy(&(rules[ruleCount].v.ipv4.ip),data + p,4); p += 4;
  277. rules[ruleCount].v.ipv4.mask = data[p++];
  278. break;
  279. case ZT_NETWORK_RULE_MATCH_IPV6_SOURCE:
  280. case ZT_NETWORK_RULE_MATCH_IPV6_DEST:
  281. if ((p + 17) > len) return -1;
  282. memcpy(rules[ruleCount].v.ipv6.ip,data + p,16); p += 16;
  283. rules[ruleCount].v.ipv6.mask = data[p++];
  284. break;
  285. case ZT_NETWORK_RULE_MATCH_IP_TOS:
  286. if ((p + 3) > len) return -1;
  287. rules[ruleCount].v.ipTos.mask = data[p++];
  288. rules[ruleCount].v.ipTos.value[0] = data[p++];
  289. rules[ruleCount].v.ipTos.value[1] = data[p++];
  290. break;
  291. case ZT_NETWORK_RULE_MATCH_IP_PROTOCOL:
  292. if ((p + 1) > len) return -1;
  293. rules[ruleCount].v.ipProtocol = data[p++];
  294. break;
  295. case ZT_NETWORK_RULE_MATCH_ETHERTYPE:
  296. if ((p + 2) > len) return -1;
  297. rules[ruleCount].v.etherType = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  298. break;
  299. case ZT_NETWORK_RULE_MATCH_ICMP:
  300. if ((p + 3) > len) return -1;
  301. rules[ruleCount].v.icmp.type = data[p++];
  302. rules[ruleCount].v.icmp.code = data[p++];
  303. rules[ruleCount].v.icmp.flags = data[p++];
  304. break;
  305. case ZT_NETWORK_RULE_MATCH_IP_SOURCE_PORT_RANGE:
  306. case ZT_NETWORK_RULE_MATCH_IP_DEST_PORT_RANGE:
  307. if ((p + 4) > len) return -1;
  308. rules[ruleCount].v.port[0] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  309. rules[ruleCount].v.port[1] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  310. break;
  311. case ZT_NETWORK_RULE_MATCH_CHARACTERISTICS:
  312. if ((p + 8) > len) return -1;
  313. rules[ruleCount].v.characteristics = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
  314. break;
  315. case ZT_NETWORK_RULE_MATCH_FRAME_SIZE_RANGE:
  316. if ((p + 4) > len) return -1;
  317. rules[ruleCount].v.frameSize[0] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  318. rules[ruleCount].v.frameSize[1] = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  319. break;
  320. case ZT_NETWORK_RULE_MATCH_RANDOM:
  321. if ((p + 4) > len) return -1;
  322. rules[ruleCount].v.randomProbability = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
  323. break;
  324. case ZT_NETWORK_RULE_MATCH_TAGS_DIFFERENCE:
  325. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_AND:
  326. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_OR:
  327. case ZT_NETWORK_RULE_MATCH_TAGS_BITWISE_XOR:
  328. case ZT_NETWORK_RULE_MATCH_TAGS_EQUAL:
  329. case ZT_NETWORK_RULE_MATCH_TAG_SENDER:
  330. case ZT_NETWORK_RULE_MATCH_TAG_RECEIVER:
  331. if ((p + 4) > len) return -1;
  332. rules[ruleCount].v.tag.id = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
  333. rules[ruleCount].v.tag.value = Utils::loadBigEndian<uint32_t>(data + p); p += 4;
  334. break;
  335. case ZT_NETWORK_RULE_MATCH_INTEGER_RANGE:
  336. if ((p + 19) > len) return -1;
  337. rules[ruleCount].v.intRange.start = Utils::loadBigEndian<uint64_t>(data + p); p += 8;
  338. rules[ruleCount].v.intRange.end = (uint32_t)(Utils::loadBigEndian<uint64_t>(data + p) - rules[ruleCount].v.intRange.start); p += 8;
  339. rules[ruleCount].v.intRange.idx = Utils::loadBigEndian<uint16_t>(data + p); p += 2;
  340. rules[ruleCount].v.intRange.format = data[p++];
  341. break;
  342. }
  343. p += fieldLen;
  344. ++rc;
  345. }
  346. ruleCount = rc;
  347. return p;
  348. }
  349. } // namespace ZeroTier