Locator.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. _ts = ts;
  21. if (_endpointCount > 0)
  22. std::sort(_at,_at + _endpointCount);
  23. const unsigned int signLen = marshal(signData,true);
  24. _signatureLength = id.sign(signData, signLen, _signature, sizeof(_signature));
  25. return (_signatureLength > 0);
  26. }
  27. bool Locator::verify(const Identity &id) const noexcept
  28. {
  29. if ((_ts == 0)||(_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_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,_signature,_signatureLength);
  34. }
  35. int Locator::marshal(uint8_t data[ZT_LOCATOR_MARSHAL_SIZE_MAX],const bool excludeSignature) const noexcept
  36. {
  37. if ((_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_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,_ts);
  41. int p = 9;
  42. if (_ts > 0) {
  43. Utils::storeBigEndian(data + p,(uint16_t)_endpointCount);
  44. p += 2;
  45. for (unsigned int i = 0; i < _endpointCount; ++i) {
  46. int tmp = _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)_signatureLength);
  53. p += 2;
  54. memcpy(data + p,_signature,_signatureLength);
  55. p += (int)_signatureLength;
  56. }
  57. Utils::storeBigEndian(data + p,_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. _ts = Utils::loadBigEndian<int64_t>(data + 1);
  69. int p = 9;
  70. if (_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. _endpointCount = ec;
  76. for (unsigned int i = 0; i < ec; ++i) {
  77. int tmp = _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. _signatureLength = sl;
  89. if ((p + (int)sl) > len)
  90. return -1;
  91. memcpy(_signature,data + p,sl);
  92. p += (int)sl;
  93. if ((p + 2) > len)
  94. return -1;
  95. _flags = Utils::loadBigEndian<uint16_t>(data + p);
  96. p += 2;
  97. } else {
  98. _ts = 0;
  99. }
  100. return p;
  101. }
  102. } // namespace ZeroTier