Revocation.hpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (c)2019 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_REVOCATION_HPP
  14. #define ZT_REVOCATION_HPP
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <stdint.h>
  19. #include "Constants.hpp"
  20. #include "../include/ZeroTierOne.h"
  21. #include "Credential.hpp"
  22. #include "Address.hpp"
  23. #include "C25519.hpp"
  24. #include "Utils.hpp"
  25. #include "Buffer.hpp"
  26. #include "Identity.hpp"
  27. /**
  28. * Flag: fast propagation via rumor mill algorithm
  29. */
  30. #define ZT_REVOCATION_FLAG_FAST_PROPAGATE 0x1ULL
  31. namespace ZeroTier {
  32. class RuntimeEnvironment;
  33. /**
  34. * Revocation certificate to instantaneously revoke a COM, capability, or tag
  35. */
  36. class Revocation : public Credential
  37. {
  38. public:
  39. static inline Credential::Type credentialType() { return Credential::CREDENTIAL_TYPE_REVOCATION; }
  40. Revocation() :
  41. _id(0),
  42. _credentialId(0),
  43. _networkId(0),
  44. _threshold(0),
  45. _flags(0),
  46. _target(),
  47. _signedBy(),
  48. _type(Credential::CREDENTIAL_TYPE_NULL)
  49. {
  50. memset(_signature.data,0,sizeof(_signature.data));
  51. }
  52. /**
  53. * @param i ID (arbitrary for revocations, currently random)
  54. * @param nwid Network ID
  55. * @param cid Credential ID being revoked (0 for all or for COMs, which lack IDs)
  56. * @param thr Revocation time threshold before which credentials will be revoked
  57. * @param fl Flags
  58. * @param tgt Target node whose credential(s) are being revoked
  59. * @param ct Credential type being revoked
  60. */
  61. Revocation(const uint32_t i,const uint64_t nwid,const uint32_t cid,const int64_t thr,const uint64_t fl,const Address &tgt,const Credential::Type ct) :
  62. _id(i),
  63. _credentialId(cid),
  64. _networkId(nwid),
  65. _threshold(thr),
  66. _flags(fl),
  67. _target(tgt),
  68. _signedBy(),
  69. _type(ct)
  70. {
  71. memset(_signature.data,0,sizeof(_signature.data));
  72. }
  73. inline uint32_t id() const { return _id; }
  74. inline uint32_t credentialId() const { return _credentialId; }
  75. inline uint64_t networkId() const { return _networkId; }
  76. inline int64_t threshold() const { return _threshold; }
  77. inline const Address &target() const { return _target; }
  78. inline const Address &signer() const { return _signedBy; }
  79. inline Credential::Type type() const { return _type; }
  80. inline bool fastPropagate() const { return ((_flags & ZT_REVOCATION_FLAG_FAST_PROPAGATE) != 0); }
  81. /**
  82. * @param signer Signing identity, must have private key
  83. * @return True if signature was successful
  84. */
  85. inline bool sign(const Identity &signer)
  86. {
  87. if (signer.hasPrivate()) {
  88. Buffer<sizeof(Revocation) + 64> tmp;
  89. _signedBy = signer.address();
  90. this->serialize(tmp,true);
  91. _signature = signer.sign(tmp.data(),tmp.size());
  92. return true;
  93. }
  94. return false;
  95. }
  96. /**
  97. * Verify this revocation's signature
  98. *
  99. * @param RR Runtime environment to provide for peer lookup, etc.
  100. * @param tPtr Thread pointer to be handed through to any callbacks called as a result of this call
  101. * @return 0 == OK, 1 == waiting for WHOIS, -1 == BAD signature or chain
  102. */
  103. int verify(const RuntimeEnvironment *RR,void *tPtr) const;
  104. template<unsigned int C>
  105. inline void serialize(Buffer<C> &b,const bool forSign = false) const
  106. {
  107. if (forSign) {
  108. b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
  109. }
  110. b.append((uint32_t)0); // 4 unused bytes, currently set to 0
  111. b.append(_id);
  112. b.append(_networkId);
  113. b.append((uint32_t)0); // 4 unused bytes, currently set to 0
  114. b.append(_credentialId);
  115. b.append(_threshold);
  116. b.append(_flags);
  117. _target.appendTo(b);
  118. _signedBy.appendTo(b);
  119. b.append((uint8_t)_type);
  120. if (!forSign) {
  121. b.append((uint8_t)1); // 1 == Ed25519 signature
  122. b.append((uint16_t)ZT_C25519_SIGNATURE_LEN);
  123. b.append(_signature.data,ZT_C25519_SIGNATURE_LEN);
  124. }
  125. // This is the size of any additional fields, currently 0.
  126. b.append((uint16_t)0);
  127. if (forSign) {
  128. b.append((uint64_t)0x7f7f7f7f7f7f7f7fULL);
  129. }
  130. }
  131. template<unsigned int C>
  132. inline unsigned int deserialize(const Buffer<C> &b,unsigned int startAt = 0)
  133. {
  134. *this = Revocation();
  135. unsigned int p = startAt;
  136. p += 4; // 4 bytes, currently unused
  137. _id = b.template at<uint32_t>(p);
  138. p += 4;
  139. _networkId = b.template at<uint64_t>(p);
  140. p += 8;
  141. p += 4; // 4 bytes, currently unused
  142. _credentialId = b.template at<uint32_t>(p);
  143. p += 4;
  144. _threshold = (int64_t)b.template at<uint64_t>(p);
  145. p += 8;
  146. _flags = b.template at<uint64_t>(p);
  147. p += 8;
  148. _target.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
  149. p += ZT_ADDRESS_LENGTH;
  150. _signedBy.setTo(b.field(p,ZT_ADDRESS_LENGTH),ZT_ADDRESS_LENGTH);
  151. p += ZT_ADDRESS_LENGTH;
  152. _type = (Credential::Type)b[p++];
  153. if (b[p++] == 1) {
  154. if (b.template at<uint16_t>(p) == ZT_C25519_SIGNATURE_LEN) {
  155. p += 2;
  156. memcpy(_signature.data,b.field(p,ZT_C25519_SIGNATURE_LEN),ZT_C25519_SIGNATURE_LEN);
  157. p += ZT_C25519_SIGNATURE_LEN;
  158. } else {
  159. throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
  160. }
  161. } else {
  162. p += 2 + b.template at<uint16_t>(p);
  163. }
  164. p += 2 + b.template at<uint16_t>(p);
  165. if (p > b.size()) {
  166. throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_OVERFLOW;
  167. }
  168. return (p - startAt);
  169. }
  170. private:
  171. uint32_t _id;
  172. uint32_t _credentialId;
  173. uint64_t _networkId;
  174. int64_t _threshold;
  175. uint64_t _flags;
  176. Address _target;
  177. Address _signedBy;
  178. Credential::Type _type;
  179. C25519::Signature _signature;
  180. };
  181. } // namespace ZeroTier
  182. #endif