Identity.hpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  4. *
  5. * (c) ZeroTier, Inc.
  6. * https://www.zerotier.com/
  7. */
  8. #ifndef ZT_IDENTITY_HPP
  9. #define ZT_IDENTITY_HPP
  10. #include "Address.hpp"
  11. #include "Buffer.hpp"
  12. #include "Constants.hpp"
  13. #include "ECC.hpp"
  14. #include "SHA512.hpp"
  15. #include "Utils.hpp"
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #define ZT_IDENTITY_STRING_BUFFER_LENGTH 384
  19. namespace ZeroTier {
  20. /**
  21. * A ZeroTier identity
  22. *
  23. * An identity consists of a public key, a 40-bit ZeroTier address computed
  24. * from that key in a collision-resistant fashion, and a self-signature.
  25. *
  26. * The address derivation algorithm makes it computationally very expensive to
  27. * search for a different public key that duplicates an existing address. (See
  28. * code for deriveAddress() for this algorithm.)
  29. */
  30. class Identity {
  31. public:
  32. Identity() : _privateKey((ECC::Private*)0)
  33. {
  34. }
  35. Identity(const Identity& id) : _address(id._address), _publicKey(id._publicKey), _privateKey((id._privateKey) ? new ECC::Private(*(id._privateKey)) : (ECC::Private*)0)
  36. {
  37. }
  38. Identity(const char* str) : _privateKey((ECC::Private*)0)
  39. {
  40. if (! fromString(str)) {
  41. throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
  42. }
  43. }
  44. template <unsigned int C> Identity(const Buffer<C>& b, unsigned int startAt = 0) : _privateKey((ECC::Private*)0)
  45. {
  46. deserialize(b, startAt);
  47. }
  48. ~Identity()
  49. {
  50. if (_privateKey) {
  51. Utils::burn(_privateKey, sizeof(ECC::Private));
  52. delete _privateKey;
  53. }
  54. }
  55. inline Identity& operator=(const Identity& id)
  56. {
  57. _address = id._address;
  58. _publicKey = id._publicKey;
  59. if (id._privateKey) {
  60. if (! _privateKey) {
  61. _privateKey = new ECC::Private();
  62. }
  63. *_privateKey = *(id._privateKey);
  64. }
  65. else {
  66. delete _privateKey;
  67. _privateKey = (ECC::Private*)0;
  68. }
  69. return *this;
  70. }
  71. /**
  72. * Generate a new identity (address, key pair)
  73. *
  74. * This is a time consuming operation.
  75. */
  76. void generate();
  77. /**
  78. * Check the validity of this identity's pairing of key to address
  79. *
  80. * @return True if validation check passes
  81. */
  82. bool locallyValidate() const;
  83. /**
  84. * @return True if this identity contains a private key
  85. */
  86. inline bool hasPrivate() const
  87. {
  88. return (_privateKey != (ECC::Private*)0);
  89. }
  90. /**
  91. * Compute a SHA384 hash of this identity's address and public key(s).
  92. *
  93. * @param sha384buf Buffer with 48 bytes of space to receive hash
  94. */
  95. inline void publicKeyHash(void* sha384buf) const
  96. {
  97. uint8_t address[ZT_ADDRESS_LENGTH];
  98. _address.copyTo(address, ZT_ADDRESS_LENGTH);
  99. SHA384(sha384buf, address, ZT_ADDRESS_LENGTH, _publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN);
  100. }
  101. /**
  102. * Compute the SHA512 hash of our private key (if we have one)
  103. *
  104. * @param sha Buffer to receive SHA512 (MUST be ZT_SHA512_DIGEST_LEN (64) bytes in length)
  105. * @return True on success, false if no private key
  106. */
  107. inline bool sha512PrivateKey(void* sha) const
  108. {
  109. if (_privateKey) {
  110. SHA512(sha, _privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN);
  111. return true;
  112. }
  113. return false;
  114. }
  115. /**
  116. * Sign a message with this identity (private key required)
  117. *
  118. * @param data Data to sign
  119. * @param len Length of data
  120. */
  121. inline ECC::Signature sign(const void* data, unsigned int len) const
  122. {
  123. if (_privateKey) {
  124. return ECC::sign(*_privateKey, _publicKey, data, len);
  125. }
  126. throw ZT_EXCEPTION_PRIVATE_KEY_REQUIRED;
  127. }
  128. /**
  129. * Verify a message signature against this identity
  130. *
  131. * @param data Data to check
  132. * @param len Length of data
  133. * @param signature Signature bytes
  134. * @param siglen Length of signature in bytes
  135. * @return True if signature validates and data integrity checks
  136. */
  137. inline bool verify(const void* data, unsigned int len, const void* signature, unsigned int siglen) const
  138. {
  139. if (siglen != ZT_ECC_SIGNATURE_LEN) {
  140. return false;
  141. }
  142. return ECC::verify(_publicKey, data, len, signature);
  143. }
  144. /**
  145. * Verify a message signature against this identity
  146. *
  147. * @param data Data to check
  148. * @param len Length of data
  149. * @param signature Signature
  150. * @return True if signature validates and data integrity checks
  151. */
  152. inline bool verify(const void* data, unsigned int len, const ECC::Signature& signature) const
  153. {
  154. return ECC::verify(_publicKey, data, len, signature);
  155. }
  156. /**
  157. * Shortcut method to perform key agreement with another identity
  158. *
  159. * This identity must have a private key. (Check hasPrivate())
  160. *
  161. * @param id Identity to agree with
  162. * @param key Result parameter to fill with key bytes
  163. * @return Was agreement successful?
  164. */
  165. inline bool agree(const Identity& id, void* const key) const
  166. {
  167. if (_privateKey) {
  168. ECC::agree(*_privateKey, id._publicKey, key, ZT_SYMMETRIC_KEY_SIZE);
  169. return true;
  170. }
  171. return false;
  172. }
  173. /**
  174. * @return This identity's address
  175. */
  176. inline const Address& address() const
  177. {
  178. return _address;
  179. }
  180. /**
  181. * Serialize this identity (binary)
  182. *
  183. * @param b Destination buffer to append to
  184. * @param includePrivate If true, include private key component (if present) (default: false)
  185. * @throws std::out_of_range Buffer too small
  186. */
  187. template <unsigned int C> inline void serialize(Buffer<C>& b, bool includePrivate = false) const
  188. {
  189. _address.appendTo(b);
  190. b.append((uint8_t)0); // C25519/Ed25519 identity type
  191. b.append(_publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN);
  192. if ((_privateKey) && (includePrivate)) {
  193. b.append((unsigned char)ZT_ECC_PRIVATE_KEY_SET_LEN);
  194. b.append(_privateKey->data, ZT_ECC_PRIVATE_KEY_SET_LEN);
  195. }
  196. else {
  197. b.append((unsigned char)0);
  198. }
  199. }
  200. /**
  201. * Deserialize a binary serialized identity
  202. *
  203. * If an exception is thrown, the Identity object is left in an undefined
  204. * state and should not be used.
  205. *
  206. * @param b Buffer containing serialized data
  207. * @param startAt Index within buffer of serialized data (default: 0)
  208. * @return Length of serialized data read from buffer
  209. * @throws std::out_of_range Serialized data invalid
  210. * @throws std::invalid_argument Serialized data invalid
  211. */
  212. template <unsigned int C> inline unsigned int deserialize(const Buffer<C>& b, unsigned int startAt = 0)
  213. {
  214. delete _privateKey;
  215. _privateKey = (ECC::Private*)0;
  216. unsigned int p = startAt;
  217. _address.setTo(b.field(p, ZT_ADDRESS_LENGTH), ZT_ADDRESS_LENGTH);
  218. p += ZT_ADDRESS_LENGTH;
  219. if (b[p++] != 0) {
  220. throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_TYPE;
  221. }
  222. memcpy(_publicKey.data, b.field(p, ZT_ECC_PUBLIC_KEY_SET_LEN), ZT_ECC_PUBLIC_KEY_SET_LEN);
  223. p += ZT_ECC_PUBLIC_KEY_SET_LEN;
  224. unsigned int privateKeyLength = (unsigned int)b[p++];
  225. if (privateKeyLength) {
  226. if (privateKeyLength != ZT_ECC_PRIVATE_KEY_SET_LEN) {
  227. throw ZT_EXCEPTION_INVALID_SERIALIZED_DATA_INVALID_CRYPTOGRAPHIC_TOKEN;
  228. }
  229. _privateKey = new ECC::Private();
  230. memcpy(_privateKey->data, b.field(p, ZT_ECC_PRIVATE_KEY_SET_LEN), ZT_ECC_PRIVATE_KEY_SET_LEN);
  231. p += ZT_ECC_PRIVATE_KEY_SET_LEN;
  232. }
  233. return (p - startAt);
  234. }
  235. /**
  236. * Serialize to a more human-friendly string
  237. *
  238. * @param includePrivate If true, include private key (if it exists)
  239. * @param buf Buffer to store string
  240. * @return ASCII string representation of identity
  241. */
  242. char* toString(bool includePrivate, char buf[ZT_IDENTITY_STRING_BUFFER_LENGTH]) const;
  243. /**
  244. * Deserialize a human-friendly string
  245. *
  246. * Note: validation is for the format only. The locallyValidate() method
  247. * must be used to check signature and address/key correspondence.
  248. *
  249. * @param str String to deserialize
  250. * @return True if deserialization appears successful
  251. */
  252. bool fromString(const char* str);
  253. /**
  254. * @return C25519 public key
  255. */
  256. inline const ECC::Public& publicKey() const
  257. {
  258. return _publicKey;
  259. }
  260. /**
  261. * @return C25519 key pair (only returns valid pair if private key is present in this Identity object)
  262. */
  263. inline const ECC::Pair privateKeyPair() const
  264. {
  265. ECC::Pair pair;
  266. pair.pub = _publicKey;
  267. if (_privateKey) {
  268. pair.priv = *_privateKey;
  269. }
  270. else {
  271. memset(pair.priv.data, 0, ZT_ECC_PRIVATE_KEY_SET_LEN);
  272. }
  273. return pair;
  274. }
  275. /**
  276. * @return True if this identity contains something
  277. */
  278. inline operator bool() const
  279. {
  280. return (_address);
  281. }
  282. inline bool operator==(const Identity& id) const
  283. {
  284. return ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) == 0));
  285. }
  286. inline bool operator<(const Identity& id) const
  287. {
  288. return ((_address < id._address) || ((_address == id._address) && (memcmp(_publicKey.data, id._publicKey.data, ZT_ECC_PUBLIC_KEY_SET_LEN) < 0)));
  289. }
  290. inline bool operator!=(const Identity& id) const
  291. {
  292. return ! (*this == id);
  293. }
  294. inline bool operator>(const Identity& id) const
  295. {
  296. return (id < *this);
  297. }
  298. inline bool operator<=(const Identity& id) const
  299. {
  300. return ! (id < *this);
  301. }
  302. inline bool operator>=(const Identity& id) const
  303. {
  304. return ! (*this < id);
  305. }
  306. private:
  307. Address _address;
  308. ECC::Public _publicKey;
  309. ECC::Private* _privateKey;
  310. };
  311. } // namespace ZeroTier
  312. #endif