Locator.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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. #include "Locator.hpp"
  14. namespace ZeroTier {
  15. bool Locator::sign(const int64_t ts, const Identity &id) noexcept
  16. {
  17. uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
  18. if (!id.hasPrivate())
  19. return false;
  20. m_ts = ts;
  21. if (m_endpointCount > 0)
  22. std::sort(m_at, m_at + m_endpointCount);
  23. const unsigned int signLen = marshal(signData, true);
  24. m_signatureLength = id.sign(signData, signLen, m_signature, sizeof(m_signature));
  25. return (m_signatureLength > 0);
  26. }
  27. bool Locator::verify(const Identity &id) const noexcept
  28. {
  29. if ((m_ts == 0) || (m_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS) || (m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
  30. return false;
  31. uint8_t signData[ZT_LOCATOR_MARSHAL_SIZE_MAX];
  32. const unsigned int signLen = marshal(signData, true);
  33. return id.verify(signData, signLen, m_signature, m_signatureLength);
  34. }
  35. int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX], const bool excludeSignature) const noexcept
  36. {
  37. if ((m_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS) || (m_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
  38. return -1;
  39. data[0] = 0xff; // version byte, currently 0xff to never be the same as byte 0 of an identity for legacy compatibility reasons
  40. Utils::storeBigEndian<int64_t>(data + 1, m_ts);
  41. int p = 9;
  42. if (m_ts > 0) {
  43. Utils::storeBigEndian(data + p, (uint16_t) m_endpointCount);
  44. p += 2;
  45. for (unsigned int i = 0;i < m_endpointCount;++i) {
  46. int tmp = m_at[i].marshal(data + p);
  47. if (tmp < 0)
  48. return -1;
  49. p += tmp;
  50. }
  51. if (!excludeSignature) {
  52. Utils::storeBigEndian(data + p, (uint16_t) m_signatureLength);
  53. p += 2;
  54. Utils::copy(data + p, m_signature, m_signatureLength);
  55. p += (int) m_signatureLength;
  56. }
  57. Utils::storeBigEndian(data + p, m_flags);
  58. p += 2;
  59. }
  60. return p;
  61. }
  62. int Locator::unmarshal(const uint8_t *restrict data, const int len) noexcept
  63. {
  64. if (len <= (1 + 8 + 2 + 48))
  65. return -1;
  66. if (data[0] != 0xff)
  67. return -1;
  68. m_ts = Utils::loadBigEndian<int64_t>(data + 1);
  69. int p = 9;
  70. if (m_ts > 0) {
  71. const unsigned int ec = Utils::loadBigEndian<uint16_t>(data + p);
  72. p += 2;
  73. if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
  74. return -1;
  75. m_endpointCount = ec;
  76. for (unsigned int i = 0;i < ec;++i) {
  77. int tmp = m_at[i].unmarshal(data + p, len - p);
  78. if (tmp < 0)
  79. return -1;
  80. p += tmp;
  81. }
  82. if ((p + 2) > len)
  83. return -1;
  84. const unsigned int sl = Utils::loadBigEndian<uint16_t>(data + p);
  85. p += 2;
  86. if (sl > ZT_SIGNATURE_BUFFER_SIZE)
  87. return -1;
  88. m_signatureLength = sl;
  89. if ((p + (int)sl) > len)
  90. return -1;
  91. Utils::copy(m_signature, data + p, sl);
  92. p += (int)sl;
  93. if ((p + 2) > len)
  94. return -1;
  95. m_flags = Utils::loadBigEndian<uint16_t>(data + p);
  96. p += 2;
  97. } else {
  98. m_ts = 0;
  99. }
  100. return p;
  101. }
  102. int Locator::makeRootSpecification(const Identity &id,int64_t ts,const Vector<Endpoint> &endpoints,void *rootSpecBuf,unsigned int rootSpecBufSize)
  103. {
  104. if (endpoints.size() > ZT_LOCATOR_MAX_ENDPOINTS)
  105. return -1;
  106. if (rootSpecBufSize < (ZT_IDENTITY_MARSHAL_SIZE_MAX + ZT_LOCATOR_MARSHAL_SIZE_MAX + 1))
  107. return -1;
  108. Locator loc;
  109. for (Vector<Endpoint>::const_iterator e(endpoints.begin());e!=endpoints.end();++e)
  110. loc.add(*e);
  111. if (!loc.sign(ts,id))
  112. return -1;
  113. uint8_t *buf = reinterpret_cast<uint8_t *>(rootSpecBuf);
  114. int idl = id.marshal(buf,false);
  115. if (idl <= 0)
  116. return -1;
  117. buf += idl;
  118. int locl = loc.marshal(buf);
  119. if (locl <= 0)
  120. return -1;
  121. return idl + locl;
  122. }
  123. std::pair<Identity,Locator> Locator::parseRootSpecification(const void *rootSpec,unsigned int rootSpecSize)
  124. {
  125. std::pair<Identity,Locator> rs;
  126. int l = rs.first.unmarshal(reinterpret_cast<const uint8_t *>(rootSpec),(int)rootSpecSize);
  127. if (l <= 0) {
  128. rs.first.zero();
  129. return rs;
  130. }
  131. l = rs.second.unmarshal(reinterpret_cast<const uint8_t *>(rootSpec) + l,(int)rootSpecSize - l);
  132. if (l <= 0)
  133. rs.first.zero();
  134. return rs;
  135. }
  136. } // namespace ZeroTier