Tag.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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_TAG_HPP
  14. #define ZT_TAG_HPP
  15. #include "Constants.hpp"
  16. #include "Credential.hpp"
  17. #include "C25519.hpp"
  18. #include "Address.hpp"
  19. #include "Identity.hpp"
  20. #define ZT_TAG_MARSHAL_SIZE_MAX (8 + 8 + 4 + 4 + 5 + 5 + 1 + 2 + ZT_SIGNATURE_BUFFER_SIZE + 2)
  21. namespace ZeroTier {
  22. class RuntimeEnvironment;
  23. /**
  24. * A tag that can be associated with members and matched in rules
  25. *
  26. * Capabilities group rules, while tags group members subject to those
  27. * rules. Tag values can be matched in rules, and tags relevant to a
  28. * capability are presented along with it.
  29. *
  30. * E.g. a capability might be "can speak Samba/CIFS within your
  31. * department." This cap might have a rule to allow TCP/137 but
  32. * only if a given tag ID's value matches between two peers. The
  33. * capability is what members can do, while the tag is who they are.
  34. * Different departments might have tags with the same ID but different
  35. * values.
  36. *
  37. * Unlike capabilities tags are signed only by the issuer and are never
  38. * transferable.
  39. */
  40. class Tag : public Credential
  41. {
  42. friend class Credential;
  43. public:
  44. static constexpr ZT_CredentialType credentialType() noexcept { return ZT_CREDENTIAL_TYPE_TAG; }
  45. ZT_INLINE Tag() noexcept { memoryZero(this); }
  46. /**
  47. * @param nwid Network ID
  48. * @param ts Timestamp
  49. * @param issuedTo Address to which this tag was issued
  50. * @param id Tag ID
  51. * @param value Tag value
  52. */
  53. ZT_INLINE Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) noexcept :
  54. m_id(id),
  55. m_value(value),
  56. m_networkId(nwid),
  57. m_ts(ts),
  58. m_issuedTo(issuedTo),
  59. m_signedBy(),
  60. m_signatureLength(0)
  61. {
  62. }
  63. ZT_INLINE uint32_t id() const noexcept { return m_id; }
  64. ZT_INLINE const uint32_t &value() const noexcept { return m_value; }
  65. ZT_INLINE uint64_t networkId() const noexcept { return m_networkId; }
  66. ZT_INLINE int64_t timestamp() const noexcept { return m_ts; }
  67. ZT_INLINE const Address &issuedTo() const noexcept { return m_issuedTo; }
  68. ZT_INLINE const Address &signer() const noexcept { return m_signedBy; }
  69. ZT_INLINE const uint8_t *signature() const noexcept { return m_signature; }
  70. ZT_INLINE unsigned int signatureLength() const noexcept { return m_signatureLength; }
  71. /**
  72. * Sign this tag
  73. *
  74. * @param signer Signing identity, must have private key
  75. * @return True if signature was successful
  76. */
  77. bool sign(const Identity &signer) noexcept;
  78. /**
  79. * Check this tag's signature
  80. *
  81. * @param RR Runtime environment to allow identity lookup for signedBy
  82. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  83. */
  84. ZT_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const noexcept { return _verify(RR,tPtr,*this); }
  85. static constexpr int marshalSizeMax() noexcept { return ZT_TAG_MARSHAL_SIZE_MAX; }
  86. int marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign = false) const noexcept;
  87. int unmarshal(const uint8_t *data,int len) noexcept;
  88. // Provides natural sort order by ID
  89. ZT_INLINE bool operator<(const Tag &t) const noexcept { return (m_id < t.m_id); }
  90. ZT_INLINE bool operator==(const Tag &t) const noexcept { return (memcmp(this,&t,sizeof(Tag)) == 0); }
  91. ZT_INLINE bool operator!=(const Tag &t) const noexcept { return (memcmp(this,&t,sizeof(Tag)) != 0); }
  92. // For searching sorted arrays or lists of Tags by ID
  93. struct IdComparePredicate
  94. {
  95. ZT_INLINE bool operator()(const Tag &a,const Tag &b) const noexcept { return (a.id() < b.id()); }
  96. ZT_INLINE bool operator()(const uint32_t a,const Tag &b) const noexcept { return (a < b.id()); }
  97. ZT_INLINE bool operator()(const Tag &a,const uint32_t b) const noexcept { return (a.id() < b); }
  98. ZT_INLINE bool operator()(const Tag *a,const Tag *b) const noexcept { return (a->id() < b->id()); }
  99. ZT_INLINE bool operator()(const Tag *a,const Tag &b) const noexcept { return (a->id() < b.id()); }
  100. ZT_INLINE bool operator()(const Tag &a,const Tag *b) const noexcept { return (a.id() < b->id()); }
  101. ZT_INLINE bool operator()(const uint32_t a,const Tag *b) const noexcept { return (a < b->id()); }
  102. ZT_INLINE bool operator()(const Tag *a,const uint32_t b) const noexcept { return (a->id() < b); }
  103. ZT_INLINE bool operator()(const uint32_t a,const uint32_t b) const noexcept { return (a < b); }
  104. };
  105. private:
  106. uint32_t m_id;
  107. uint32_t m_value;
  108. uint64_t m_networkId;
  109. int64_t m_ts;
  110. Address m_issuedTo;
  111. Address m_signedBy;
  112. unsigned int m_signatureLength;
  113. uint8_t m_signature[ZT_SIGNATURE_BUFFER_SIZE];
  114. };
  115. } // namespace ZeroTier
  116. #endif