Tag.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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 ZT_ALWAYS_INLINE ZT_CredentialType credentialType() { return ZT_CREDENTIAL_TYPE_TAG; }
  49. ZT_ALWAYS_INLINE Tag() :
  50. _id(0),
  51. _value(0),
  52. _networkId(0),
  53. _ts(0),
  54. _signatureLength(0)
  55. {
  56. }
  57. /**
  58. * @param nwid Network ID
  59. * @param ts Timestamp
  60. * @param issuedTo Address to which this tag was issued
  61. * @param id Tag ID
  62. * @param value Tag value
  63. */
  64. ZT_ALWAYS_INLINE Tag(const uint64_t nwid,const int64_t ts,const Address &issuedTo,const uint32_t id,const uint32_t value) :
  65. _id(id),
  66. _value(value),
  67. _networkId(nwid),
  68. _ts(ts),
  69. _issuedTo(issuedTo),
  70. _signedBy(),
  71. _signatureLength(0)
  72. {
  73. }
  74. ZT_ALWAYS_INLINE uint32_t id() const { return _id; }
  75. ZT_ALWAYS_INLINE const uint32_t &value() const { return _value; }
  76. ZT_ALWAYS_INLINE uint64_t networkId() const { return _networkId; }
  77. ZT_ALWAYS_INLINE int64_t timestamp() const { return _ts; }
  78. ZT_ALWAYS_INLINE const Address &issuedTo() const { return _issuedTo; }
  79. ZT_ALWAYS_INLINE const Address &signer() const { return _signedBy; }
  80. ZT_ALWAYS_INLINE const uint8_t *signature() const { return _signature; }
  81. ZT_ALWAYS_INLINE unsigned int signatureLength() const { return _signatureLength; }
  82. /**
  83. * Sign this tag
  84. *
  85. * @param signer Signing identity, must have private key
  86. * @return True if signature was successful
  87. */
  88. bool sign(const Identity &signer);
  89. /**
  90. * Check this tag's signature
  91. *
  92. * @param RR Runtime environment to allow identity lookup for signedBy
  93. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  94. */
  95. ZT_ALWAYS_INLINE Credential::VerifyResult verify(const RuntimeEnvironment *RR,void *tPtr) const { return _verify(RR,tPtr,*this); }
  96. static ZT_ALWAYS_INLINE int marshalSizeMax() { return ZT_TAG_MARSHAL_SIZE_MAX; }
  97. int marshal(uint8_t data[ZT_TAG_MARSHAL_SIZE_MAX],bool forSign = false) const;
  98. int unmarshal(const uint8_t *data,int len);
  99. // Provides natural sort order by ID
  100. ZT_ALWAYS_INLINE bool operator<(const Tag &t) const { return (_id < t._id); }
  101. ZT_ALWAYS_INLINE bool operator==(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) == 0); }
  102. ZT_ALWAYS_INLINE bool operator!=(const Tag &t) const { return (memcmp(this,&t,sizeof(Tag)) != 0); }
  103. // For searching sorted arrays or lists of Tags by ID
  104. struct IdComparePredicate
  105. {
  106. ZT_ALWAYS_INLINE bool operator()(const Tag &a,const Tag &b) const { return (a.id() < b.id()); }
  107. ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const Tag &b) const { return (a < b.id()); }
  108. ZT_ALWAYS_INLINE bool operator()(const Tag &a,const uint32_t b) const { return (a.id() < b); }
  109. ZT_ALWAYS_INLINE bool operator()(const Tag *a,const Tag *b) const { return (a->id() < b->id()); }
  110. ZT_ALWAYS_INLINE bool operator()(const Tag *a,const Tag &b) const { return (a->id() < b.id()); }
  111. ZT_ALWAYS_INLINE bool operator()(const Tag &a,const Tag *b) const { return (a.id() < b->id()); }
  112. ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const Tag *b) const { return (a < b->id()); }
  113. ZT_ALWAYS_INLINE bool operator()(const Tag *a,const uint32_t b) const { return (a->id() < b); }
  114. ZT_ALWAYS_INLINE bool operator()(const uint32_t a,const uint32_t b) const { return (a < b); }
  115. };
  116. private:
  117. uint32_t _id;
  118. uint32_t _value;
  119. uint64_t _networkId;
  120. int64_t _ts;
  121. Address _issuedTo;
  122. Address _signedBy;
  123. unsigned int _signatureLength;
  124. uint8_t _signature[ZT_SIGNATURE_BUFFER_SIZE];
  125. };
  126. } // namespace ZeroTier
  127. #endif