Capability.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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. #include "Capability.hpp"
  9. #include "Identity.hpp"
  10. #include "Network.hpp"
  11. #include "Node.hpp"
  12. #include "RuntimeEnvironment.hpp"
  13. #include "Switch.hpp"
  14. #include "Topology.hpp"
  15. namespace ZeroTier {
  16. int Capability::verify(const RuntimeEnvironment* RR, void* tPtr) const
  17. {
  18. try {
  19. // There must be at least one entry, and sanity check for bad chain max length
  20. if ((_maxCustodyChainLength < 1) || (_maxCustodyChainLength > ZT_MAX_CAPABILITY_CUSTODY_CHAIN_LENGTH)) {
  21. return -1;
  22. }
  23. // Validate all entries in chain of custody
  24. Buffer<(sizeof(Capability) * 2)> tmp;
  25. this->serialize(tmp, true);
  26. for (unsigned int c = 0; c < _maxCustodyChainLength; ++c) {
  27. if (c == 0) {
  28. if ((! _custody[c].to) || (! _custody[c].from) || (_custody[c].from != Network::controllerFor(_nwid))) {
  29. return -1; // the first entry must be present and from the network's controller
  30. }
  31. }
  32. else {
  33. if (! _custody[c].to) {
  34. return 0; // all previous entries were valid, so we are valid
  35. }
  36. else if ((! _custody[c].from) || (_custody[c].from != _custody[c - 1].to)) {
  37. return -1; // otherwise if we have another entry it must be from the previous holder in the chain
  38. }
  39. }
  40. const Identity id(RR->topology->getIdentity(tPtr, _custody[c].from));
  41. if (id) {
  42. if (! id.verify(tmp.data(), tmp.size(), _custody[c].signature)) {
  43. return -1;
  44. }
  45. }
  46. else {
  47. RR->sw->requestWhois(tPtr, RR->node->now(), _custody[c].from);
  48. return 1;
  49. }
  50. }
  51. // We reached max custody chain length and everything was valid
  52. return 0;
  53. }
  54. catch (...) {
  55. }
  56. return -1;
  57. }
  58. } // namespace ZeroTier