Capability.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. #ifndef ZT_CAPABILITY_HPP
  14. #define ZT_CAPABILITY_HPP
  15. #include <cstdio>
  16. #include <cstdlib>
  17. #include <cstring>
  18. #include "Constants.hpp"
  19. #include "Credential.hpp"
  20. #include "Address.hpp"
  21. #include "C25519.hpp"
  22. #include "Utils.hpp"
  23. #include "Identity.hpp"
  24. #define ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX 21
  25. #define ZT_CAPABILITY__CUSTODY_CHAIN_ITEM_MARSHAL_SIZE_MAX (5 + 5 + 2 + ZT_SIGNATURE_BUFFER_SIZE)
  26. #define ZT_CAPABILITY_MARSHAL_SIZE_MAX (8 + 8 + 4 + 1 + 2 + (ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX * ZT_MAX_CAPABILITY_RULES) + 2 + (ZT_CAPABILITY__CUSTODY_CHAIN_ITEM_MARSHAL_SIZE_MAX * ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH))
  27. namespace ZeroTier {
  28. class RuntimeEnvironment;
  29. /**
  30. * A set of grouped and signed network flow rules
  31. *
  32. * On the sending side the sender does the following for each packet:
  33. *
  34. * (1) Evaluates its capabilities in ascending order of ID to determine
  35. * which capability allows it to transmit this packet.
  36. * (2) If it has not done so lately, it then sends this capability to the
  37. * receiving peer ("presents" it).
  38. * (3) The sender then sends the packet.
  39. *
  40. * On the receiving side the receiver evaluates the capabilities presented
  41. * by the sender. If any valid un-expired capability allows this packet it
  42. * is accepted.
  43. *
  44. * Note that this is after evaluation of network scope rules and only if
  45. * network scope rules do not deliver an explicit match.
  46. *
  47. * Capabilities support a chain of custody. This is currently unused but
  48. * in the future would allow the publication of capabilities that can be
  49. * handed off between nodes. Limited transferability of capabilities is
  50. * a feature of true capability based security.
  51. */
  52. class Capability : public Credential
  53. {
  54. friend class Credential;
  55. public:
  56. static ZT_ALWAYS_INLINE ZT_CredentialType credentialType() { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
  57. ZT_ALWAYS_INLINE Capability() :
  58. _nwid(0),
  59. _ts(0),
  60. _id(0),
  61. _maxCustodyChainLength(0),
  62. _ruleCount(0)
  63. {
  64. memset(_rules,0,sizeof(_rules));
  65. memset(_custody,0,sizeof(_custody));
  66. }
  67. /**
  68. * @param id Capability ID
  69. * @param nwid Network ID
  70. * @param ts Timestamp (at controller)
  71. * @param mccl Maximum custody chain length (1 to create non-transferable capability)
  72. * @param rules Network flow rules for this capability
  73. * @param ruleCount Number of flow rules
  74. */
  75. ZT_ALWAYS_INLINE Capability(const uint32_t id,const uint64_t nwid,const int64_t ts,const unsigned int mccl,const ZT_VirtualNetworkRule *const rules,const unsigned int ruleCount) :
  76. _nwid(nwid),
  77. _ts(ts),
  78. _id(id),
  79. _maxCustodyChainLength((mccl > 0) ? ((mccl < ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) ? mccl : (unsigned int)ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH) : 1),
  80. _ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES)
  81. {
  82. if (_ruleCount > 0)
  83. memcpy(_rules,rules,sizeof(ZT_VirtualNetworkRule) * _ruleCount);
  84. }
  85. /**
  86. * @return Rules -- see ruleCount() for size of array
  87. */
  88. ZT_ALWAYS_INLINE const ZT_VirtualNetworkRule *rules() const { return _rules; }
  89. /**
  90. * @return Number of rules in rules()
  91. */
  92. ZT_ALWAYS_INLINE unsigned int ruleCount() const { return _ruleCount; }
  93. /**
  94. * @return ID and evaluation order of this capability in network
  95. */
  96. ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
  97. /**
  98. * @return Network ID for which this capability was issued
  99. */
  100. ZT_ALWAYS_INLINE uint64_t networkId() const { return _nwid; }
  101. /**
  102. * @return Timestamp
  103. */
  104. ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
  105. /**
  106. * @return Last 'to' address in chain of custody
  107. */
  108. ZT_ALWAYS_INLINE Address issuedTo() const
  109. {
  110. Address i2;
  111. for(int i=0;i<ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH;++i) {
  112. if (!_custody[i].to)
  113. return i2;
  114. else i2 = _custody[i].to;
  115. }
  116. return i2;
  117. }
  118. /**
  119. * Sign this capability and add signature to its chain of custody
  120. *
  121. * If this returns false, this object should be considered to be
  122. * in an undefined state and should be discarded. False can be returned
  123. * if there is no more room for signatures (max chain length reached)
  124. * or if the 'from' identity does not include a secret key to allow
  125. * it to sign anything.
  126. *
  127. * @param from Signing identity (must have secret)
  128. * @param to Recipient of this signature
  129. * @return True if signature successful and chain of custody appended
  130. */
  131. bool sign(const Identity &from,const Address &to);
  132. /**
  133. * Verify this capability's chain of custody and signatures
  134. *
  135. * @param RR Runtime environment to provide for peer lookup, etc.
  136. */
  137. ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
  138. static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }
  139. int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],bool forSign = false) const;
  140. int unmarshal(const uint8_t *data,int len);
  141. static int marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount);
  142. static int unmarshalVirtualNetworkRules(const uint8_t *data,int len,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,unsigned int maxRuleCount);
  143. // Provides natural sort order by ID
  144. ZT_ALWAYS_INLINE bool operator<(const Capability &c) const { return (_id < c._id); }
  145. ZT_ALWAYS_INLINE bool operator==(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) == 0); }
  146. ZT_ALWAYS_INLINE bool operator!=(const Capability &c) const { return (memcmp(this,&c,sizeof(Capability)) != 0); }
  147. private:
  148. uint64_t _nwid;
  149. int64_t _ts;
  150. uint32_t _id;
  151. unsigned int _maxCustodyChainLength;
  152. unsigned int _ruleCount;
  153. ZT_VirtualNetworkRule _rules[ZT_MAX_CAPABILITY_RULES];
  154. struct {
  155. Address to;
  156. Address from;
  157. unsigned int signatureLength;
  158. uint8_t signature[ZT_SIGNATURE_BUFFER_SIZE];
  159. } _custody[ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH];
  160. };
  161. } // namespace ZeroTier
  162. #endif