Certificate.hpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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_CERTIFICATE_HPP
  14. #define ZT_CERTIFICATE_HPP
  15. #include "Constants.hpp"
  16. #include "SHA512.hpp"
  17. #include "C25519.hpp"
  18. #include "ECC384.hpp"
  19. #include "SharedPtr.hpp"
  20. #include "Identity.hpp"
  21. #include "Locator.hpp"
  22. #include "Dictionary.hpp"
  23. #include "Utils.hpp"
  24. #include "Blob.hpp"
  25. #include "Containers.hpp"
  26. namespace ZeroTier {
  27. /**
  28. * Certificate describing and grouping a set of objects.
  29. *
  30. * This is a wrapper around the straight C ZT_IdentificationCertificate and
  31. * handles allocating memory for objects added via addXXX() and disposing of
  32. * them on delete. If pointers in the underlying C struct are set manually,
  33. * their memory is not freed on delete. Use the addXXX() methods to fill
  34. * out this structure in C++ code.
  35. *
  36. * The serialNo field is filled in automatically by sign() and decode(), so
  37. * it can be left undefined when building certificates. It contains a SHA384
  38. * hash of the certificate marshalled without the signature field.
  39. *
  40. * The hashCode() method and comparison operators compare the serial number
  41. * field, so these will not work correctly before sign() or decode() is
  42. * called.
  43. */
  44. class Certificate : public ZT_Certificate
  45. {
  46. friend class SharedPtr< Certificate >;
  47. friend class SharedPtr< const Certificate >;
  48. public:
  49. ZT_INLINE Certificate() noexcept
  50. { this->clear(); }
  51. ZT_INLINE Certificate(const ZT_Certificate &apiCert)
  52. { *this = apiCert; }
  53. ZT_INLINE Certificate(const Certificate &cert)
  54. { *this = cert; }
  55. /**
  56. * Zero all fields and release all extra memory
  57. */
  58. void clear();
  59. Certificate &operator=(const ZT_Certificate &apiCert);
  60. Certificate &operator=(const Certificate &cert);
  61. /**
  62. * Add a subject node/identity without a locator
  63. *
  64. * @param id Identity
  65. * @return Pointer to C struct
  66. */
  67. ZT_Certificate_Identity *addSubjectIdentity(const Identity &id);
  68. /**
  69. * Add a subject node/identity with a locator
  70. *
  71. * @param id Identity
  72. * @param loc Locator signed by identity (signature is NOT checked here)
  73. * @return Pointer to C struct
  74. */
  75. ZT_Certificate_Identity *addSubjectIdentity(const Identity &id, const Locator &loc);
  76. /**
  77. * Add a subject network
  78. *
  79. * @param id Network ID
  80. * @param controller Network controller's full fingerprint
  81. * @return Pointer to C struct
  82. */
  83. ZT_Certificate_Network *addSubjectNetwork(const uint64_t id, const ZT_Fingerprint &controller);
  84. /**
  85. * Add a subject certificate (by its serial number)
  86. *
  87. * @param serialNo 384-bit serial number
  88. */
  89. void addSubjectCertificate(const uint8_t serialNo[ZT_SHA384_DIGEST_SIZE]);
  90. /**
  91. * Add an update URL to the updateUrls list
  92. *
  93. * @param url Update URL
  94. */
  95. void addSubjectUpdateUrl(const char *url);
  96. /**
  97. * Set the extended attributes of this certificate
  98. *
  99. * @param x Extended attributes (set by issuer)
  100. */
  101. ZT_INLINE void setExtendedAttributes(const Dictionary &x)
  102. {
  103. m_extendedAttributes.clear();
  104. x.encode(m_extendedAttributes);
  105. this->extendedAttributes = m_extendedAttributes.data();
  106. this->extendedAttributesSize = (unsigned int)m_extendedAttributes.size();
  107. }
  108. /**
  109. * Marshal this certificate in binary form
  110. *
  111. * The internal encoding used here is Dictionary to permit easy
  112. * extensibility.
  113. *
  114. * @param omitSignature If true omit the signature field (for signing and verification, default is false)
  115. * @return Marshaled certificate
  116. */
  117. Vector< uint8_t > encode(bool omitSignature = false) const;
  118. /**
  119. * Decode this certificate from marshaled bytes.
  120. *
  121. * @param data Marshalled certificate
  122. * @return True if input is valid and was unmarshalled (signature is NOT checked)
  123. */
  124. bool decode(const Vector< uint8_t > &data);
  125. /**
  126. * Sign this certificate (and also fill in serialNo).
  127. *
  128. * @param issuer Issuer identity (must have secret key)
  129. * @return True on success
  130. */
  131. bool sign(const Identity &issuer);
  132. /**
  133. * Verify self-contained signatures and validity of certificate structure
  134. *
  135. * This doesn't check the entire certificate chain, just the validity of
  136. * the certificate's internal signature and fields.
  137. *
  138. * @return OK (0) or error code indicating why certificate failed verification.
  139. */
  140. ZT_CertificateError verify() const;
  141. /**
  142. * Set the unique ID of this certificate's subject
  143. *
  144. * This must be done after all other fields in the subject are set.
  145. *
  146. * @param uniqueId Unique ID
  147. * @param uniqueIdPrivate Private key associated with unique ID to prove ownership of it
  148. * @return True if successful
  149. */
  150. bool setSubjectUniqueId(const uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_SIZE_TYPE_NIST_P_384], const uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_PRIVATE_KEY_SIZE_TYPE_NIST_P_384]);
  151. /**
  152. * Create a subject unique ID and corresponding private key required for use
  153. *
  154. * @param uniqueId Buffer to receive unique ID
  155. * @param uniqueIdPrivate Buffer to receive private key
  156. */
  157. static ZT_INLINE void createSubjectUniqueId(uint8_t uniqueId[ZT_CERTIFICATE_UNIQUE_ID_SIZE_TYPE_NIST_P_384], uint8_t uniqueIdPrivate[ZT_CERTIFICATE_UNIQUE_ID_PRIVATE_KEY_SIZE_TYPE_NIST_P_384])
  158. {
  159. uniqueId[0] = ZT_CERTIFICATE_UNIQUE_ID_PUBLIC_KEY_TYPE_NIST_P_384;
  160. ECC384GenerateKey(uniqueId + 1, uniqueIdPrivate);
  161. }
  162. ZT_INLINE unsigned long hashCode() const noexcept
  163. { return (unsigned long)Utils::loadAsIsEndian< uint32_t >(this->serialNo); }
  164. ZT_INLINE bool operator==(const ZT_Certificate &c) const noexcept
  165. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) == 0; }
  166. ZT_INLINE bool operator!=(const ZT_Certificate &c) const noexcept
  167. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) != 0; }
  168. ZT_INLINE bool operator<(const ZT_Certificate &c) const noexcept
  169. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) < 0; }
  170. ZT_INLINE bool operator<=(const ZT_Certificate &c) const noexcept
  171. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) <= 0; }
  172. ZT_INLINE bool operator>(const ZT_Certificate &c) const noexcept
  173. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) > 0; }
  174. ZT_INLINE bool operator>=(const ZT_Certificate &c) const noexcept
  175. { return memcmp(this->serialNo, c.serialNo, ZT_SHA384_DIGEST_SIZE) >= 0; }
  176. private:
  177. static void m_encodeSubject(const ZT_Certificate_Subject &s, Dictionary &d, bool omitUniqueIdProofSignature);
  178. // These hold any identity or locator objects that are owned by and should
  179. // be deleted with this certificate. Lists are used so the pointers never
  180. // change.
  181. List< Identity > m_identities;
  182. List< Locator > m_locators;
  183. List< String > m_strings;
  184. List< SHA384Hash > m_serials;
  185. // These are stored in a vector because the memory needs to be contiguous.
  186. Vector< ZT_Certificate_Identity > m_subjectIdentities;
  187. Vector< ZT_Certificate_Network > m_subjectNetworks;
  188. Vector< const uint8_t * > m_subjectCertificates;
  189. Vector< const char * > m_updateUrls;
  190. Vector< uint8_t > m_extendedAttributes;
  191. Vector< uint8_t > m_subjectUniqueId;
  192. Vector< uint8_t > m_subjectUniqueIdProofSignature;
  193. Vector< uint8_t > m_signature;
  194. std::atomic<int> __refCount;
  195. };
  196. } // namespace ZeroTier
  197. #endif