Locator.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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)
  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
  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
  36. {
  37. if ((_endpointCount > ZT_LOCATOR_MAX_ENDPOINTS)||(_signatureLength > ZT_SIGNATURE_BUFFER_SIZE))
  38. return -1;
  39. Utils::storeBigEndian<int64_t>(data,_ts);
  40. int p = 8;
  41. if (_ts > 0) {
  42. data[p++] = (uint8_t)(_endpointCount >> 8U);
  43. data[p++] = (uint8_t)_endpointCount;
  44. for (unsigned int i = 0; i < _endpointCount; ++i) {
  45. int tmp = _at[i].marshal(data + p);
  46. if (tmp < 0)
  47. return -1;
  48. p += tmp;
  49. }
  50. if (!excludeSignature) {
  51. data[p++] = (uint8_t)(_signatureLength >> 8U);
  52. data[p++] = (uint8_t)_signatureLength;
  53. memcpy(data + p,_signature,_signatureLength);
  54. p += (int)_signatureLength;
  55. }
  56. }
  57. return p;
  58. }
  59. int Locator::unmarshal(const uint8_t *restrict data,const int len)
  60. {
  61. if (len <= (8 + 2 + 48))
  62. return -1;
  63. _ts = Utils::loadBigEndian<int64_t>(data);
  64. int p = 8;
  65. if (_ts > 0) {
  66. unsigned int ec = (int)data[p++];
  67. ec <<= 8U;
  68. ec |= data[p++];
  69. if (ec > ZT_LOCATOR_MAX_ENDPOINTS)
  70. return -1;
  71. _endpointCount = ec;
  72. for (int i = 0; i < ec; ++i) {
  73. int tmp = _at[i].unmarshal(data + p,len - p);
  74. if (tmp < 0)
  75. return -1;
  76. p += tmp;
  77. }
  78. if ((p + 2) > len)
  79. return -1;
  80. unsigned int sl = data[p++];
  81. sl <<= 8U;
  82. sl |= data[p++];
  83. if (sl > ZT_SIGNATURE_BUFFER_SIZE)
  84. return -1;
  85. _signatureLength = sl;
  86. if ((p + sl) > len)
  87. return -1;
  88. memcpy(_signature,data + p,sl);
  89. p += (int)sl;
  90. } else {
  91. _ts = 0;
  92. }
  93. return p;
  94. }
  95. } // namespace ZeroTier