CapabilityCredential.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. #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_MARSHAL_SIZE_MAX (8 + 8 + 4 + 1 + 2 + (ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX * ZT_MAX_CAPABILITY_RULES) + 2 + (5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE))
  26. namespace ZeroTier {
  27. class RuntimeEnvironment;
  28. /**
  29. * A set of grouped and signed network flow rules for a specific member.
  30. *
  31. * On the sending side the sender does the following for each packet:
  32. *
  33. * (1) Evaluates its capabilities in ascending order of ID to determine
  34. * which capability allows it to transmit this packet.
  35. * (2) If it has not done so lately, it then sends this capability to the
  36. * receiving peer ("presents" it).
  37. * (3) The sender then sends the packet.
  38. *
  39. * On the receiving side the receiver evaluates the capabilities presented
  40. * by the sender. If any valid un-expired capability allows this packet it
  41. * is accepted.
  42. *
  43. * Note that this is after evaluation of network scope rules and only if
  44. * network scope rules do not deliver an explicit match.
  45. */
  46. class CapabilityCredential : public Credential
  47. {
  48. friend class Credential;
  49. public:
  50. static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_CAPABILITY; }
  51. ZT_INLINE CapabilityCredential() noexcept { memoryZero(this); }
  52. /**
  53. * @param id Capability ID
  54. * @param nwid Network ID
  55. * @param ts Timestamp (at controller)
  56. * @param mccl Maximum custody chain length (1 to create non-transferable capability)
  57. * @param rules Network flow rules for this capability
  58. * @param ruleCount Number of flow rules
  59. */
  60. ZT_INLINE CapabilityCredential(const uint32_t id, const uint64_t nwid, const int64_t ts, const ZT_VirtualNetworkRule *const rules, const unsigned int ruleCount) noexcept : // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
  61. m_nwid(nwid),
  62. m_ts(ts),
  63. m_id(id),
  64. m_ruleCount((ruleCount < ZT_MAX_CAPABILITY_RULES) ? ruleCount : ZT_MAX_CAPABILITY_RULES),
  65. m_signatureLength(0)
  66. {
  67. if (m_ruleCount > 0)
  68. Utils::copy(m_rules, rules, sizeof(ZT_VirtualNetworkRule) * m_ruleCount);
  69. }
  70. /**
  71. * @return Rules -- see ruleCount() for size of array
  72. */
  73. ZT_INLINE const ZT_VirtualNetworkRule *rules() const noexcept { return m_rules; }
  74. /**
  75. * @return Number of rules in rules()
  76. */
  77. ZT_INLINE unsigned int ruleCount() const noexcept { return m_ruleCount; }
  78. ZT_INLINE uint32_t id() const noexcept { return m_id; }
  79. ZT_INLINE uint64_t networkId() const noexcept { return m_nwid; }
  80. ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
  81. ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
  82. ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
  83. ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
  84. ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
  85. /**
  86. * Sign this capability and add signature to its chain of custody
  87. *
  88. * If this returns false, this object should be considered to be
  89. * in an undefined state and should be discarded. False can be returned
  90. * if there is no more room for signatures (max chain length reached)
  91. * or if the 'from' identity does not include a secret key to allow
  92. * it to sign anything.
  93. *
  94. * @param from Signing identity (must have secret)
  95. * @param to Recipient of this signature
  96. * @return True if signature successful and chain of custody appended
  97. */
  98. bool sign(const Identity &from,const Address &to) noexcept;
  99. /**
  100. * Verify this capability's chain of custody and signatures
  101. *
  102. * @param RR Runtime environment to provide for peer lookup, etc.
  103. */
  104. ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const noexcept { return _verify(RR,tPtr,*this); }
  105. static constexpr int marshalSizeMax() noexcept { return ZT_CAPABILITY_MARSHAL_SIZE_MAX; }
  106. int marshal(uint8_t data[ZT_CAPABILITY_MARSHAL_SIZE_MAX],bool forSign = false) const noexcept;
  107. int unmarshal(const uint8_t *data,int len) noexcept;
  108. /**
  109. * Marshal a set of virtual network rules
  110. *
  111. * @param data Buffer to store rules (must be at least ruleCount * ZT_VIRTUALNETWORKRULE_MARSHAL_SIZE_MAX)
  112. * @param rules Network rules
  113. * @param ruleCount Number of rules
  114. * @return Number of bytes written or -1 on error
  115. */
  116. static int marshalVirtualNetworkRules(uint8_t *data,const ZT_VirtualNetworkRule *rules,unsigned int ruleCount) noexcept;
  117. /**
  118. * Unmarshal a set of virtual network rules
  119. *
  120. * @param data Rule set to unmarshal
  121. * @param len Length of data
  122. * @param rules Buffer to store rules
  123. * @param ruleCount Result parameter to set to the number of rules decoded
  124. * @param maxRuleCount Capacity of rules buffer
  125. * @return Number of bytes unmarshaled or -1 on error
  126. */
  127. static int unmarshalVirtualNetworkRules(const uint8_t *data,int len,ZT_VirtualNetworkRule *rules,unsigned int &ruleCount,unsigned int maxRuleCount) noexcept;
  128. // Provides natural sort order by ID
  129. ZT_INLINE bool operator<(const CapabilityCredential &c) const noexcept { return (m_id < c.m_id); }
  130. ZT_INLINE bool operator==(const CapabilityCredential &c) const noexcept { return (memcmp(this, &c, sizeof(CapabilityCredential)) == 0); }
  131. ZT_INLINE bool operator!=(const CapabilityCredential &c) const noexcept { return (memcmp(this, &c, sizeof(CapabilityCredential)) != 0); }
  132. private:
  133. uint64_t m_nwid;
  134. int64_t m_ts;
  135. uint32_t m_id;
  136. unsigned int m_ruleCount;
  137. ZT_VirtualNetworkRule m_rules[ZT_MAX_CAPABILITY_RULES];
  138. Address m_issuedTo;
  139. Address m_signedBy;
  140. unsigned int m_signatureLength;
  141. uint8_t m_signature[ZT_SIGNATURE_BUFFER_SIZE];
  142. };
  143. } // namespace ZeroTier
  144. #endif