Extract macaroon reading and verifying into separate functions Change-Id: I3d5156b5bfebb330587090a8deb9d154b13bc7d8 Reviewed-on: https://weave-review.googlesource.com/2083 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc index bb4c3c4..7306e20 100644 --- a/src/privet/auth_manager.cc +++ b/src/privet/auth_manager.cc
@@ -4,6 +4,8 @@ #include "src/privet/auth_manager.h" +#include <algorithm> + #include <base/guid.h> #include <base/rand_util.h> #include <base/strings/string_number_conversions.h> @@ -24,9 +26,9 @@ namespace { const char kTokenDelimeter[] = ":"; -const size_t kCaveatBuffetSize = 32; const size_t kMaxMacaroonSize = 1024; const size_t kMaxPendingClaims = 10; +const char kInvalidTokenError[] = "invalid_token"; template <class T> void AppendToArray(T value, std::vector<uint8_t>* array) { @@ -66,16 +68,25 @@ class Caveat { public: - Caveat(UwMacaroonCaveatType type, uint32_t value) { - CHECK(uw_macaroon_caveat_create_with_uint_(type, value, buffer, - sizeof(buffer), &caveat)); + // TODO(vitalybuka): Use _get_buffer_size_ when available. + Caveat(UwMacaroonCaveatType type, uint32_t value) : buffer(8) { + CHECK(uw_macaroon_caveat_create_with_uint_(type, value, buffer.data(), + buffer.size(), &caveat)); + } + + // TODO(vitalybuka): Use _get_buffer_size_ when available. + Caveat(UwMacaroonCaveatType type, const std::string& value) + : buffer(std::max<size_t>(value.size(), 32u) * 2) { + CHECK(uw_macaroon_caveat_create_with_str_( + type, reinterpret_cast<const uint8_t*>(value.data()), value.size(), + buffer.data(), buffer.size(), &caveat)); } const UwMacaroonCaveat& GetCaveat() const { return caveat; } private: UwMacaroonCaveat caveat; - uint8_t buffer[kCaveatBuffetSize]; + std::vector<uint8_t> buffer; DISALLOW_COPY_AND_ASSIGN(Caveat); }; @@ -106,6 +117,32 @@ return token; } +bool LoadMacaroon(const std::vector<uint8_t>& token, + std::vector<uint8_t>* buffer, + UwMacaroon* macaroon, + ErrorPtr* error) { + buffer->resize(kMaxMacaroonSize); + if (!uw_macaroon_load_(token.data(), token.size(), buffer->data(), + buffer->size(), macaroon)) { + Error::AddTo(error, FROM_HERE, errors::kDomain, kInvalidTokenError, + "Invalid token format"); + return false; + } + return true; +} + +bool VerifyMacaroon(const std::vector<uint8_t>& secret, + const UwMacaroon& macaroon, + ErrorPtr* error) { + CHECK_EQ(kSha256OutputSize, secret.size()); + if (!uw_macaroon_verify_(&macaroon, secret.data(), secret.size())) { + Error::AddTo(error, FROM_HERE, errors::kDomain, "invalid_signature", + "Invalid token signature"); + return false; + } + return true; +} + } // namespace AuthManager::AuthManager(Config* config, @@ -264,20 +301,12 @@ bool AuthManager::IsValidAuthToken(const std::vector<uint8_t>& token, ErrorPtr* error) const { - std::vector<uint8_t> buffer(kMaxMacaroonSize); + std::vector<uint8_t> buffer; UwMacaroon macaroon{}; - if (!uw_macaroon_load_(token.data(), token.size(), buffer.data(), - buffer.size(), &macaroon)) { + if (!LoadMacaroon(token, &buffer, &macaroon, error) || + !VerifyMacaroon(auth_secret_, macaroon, error)) { Error::AddTo(error, FROM_HERE, errors::kDomain, errors::kInvalidAuthCode, - "Invalid token format"); - return false; - } - - CHECK_EQ(kSha256OutputSize, auth_secret_.size()); - if (!uw_macaroon_verify_(&macaroon, auth_secret_.data(), - auth_secret_.size())) { - Error::AddTo(error, FROM_HERE, errors::kDomain, errors::kInvalidAuthCode, - "Invalid token signature"); + "Invalid token"); return false; } return true;