Tag.hpp 5.0 KB

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