Generate Root Client Authorization Token BUG=25934385 Change-Id: Ic7d421f2c0152c7580014229c28495520d8c9981 Reviewed-on: https://weave-review.googlesource.com/1868 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc index 0864242..be7e971 100644 --- a/src/privet/auth_manager.cc +++ b/src/privet/auth_manager.cc
@@ -11,12 +11,18 @@ #include "src/privet/openssl_utils.h" #include "src/string_utils.h" +extern "C" { +#include "third_party/libuweave/src/macaroon.h" +} + namespace weave { namespace privet { namespace { const char kTokenDelimeter[] = ":"; +const size_t kCaveatBuffetSize = 32; +const size_t kMaxMacaroonSize = 1024; // Returns "scope:id:time". std::string CreateTokenData(const UserInfo& user_info, const base::Time& time) { @@ -49,6 +55,22 @@ return UserInfo{static_cast<AuthScope>(scope), id}; } +class Caveat { + public: + Caveat(UwMacaroonCaveatType type, uint32_t value) { + CHECK(uw_macaroon_caveat_create_with_uint_(type, value, buffer, + sizeof(buffer), &caveat)); + } + + const UwMacaroonCaveat& GetCaveat() const { return caveat; } + + private: + UwMacaroonCaveat caveat; + uint8_t buffer[kCaveatBuffetSize]; + + DISALLOW_COPY_AND_ASSIGN(Caveat); +}; + } // namespace AuthManager::AuthManager(const std::vector<uint8_t>& secret, @@ -84,5 +106,26 @@ return SplitTokenData(std::string(data.begin(), data.end()), time); } +std::vector<uint8_t> AuthManager::GetRootDeviceToken( + const base::Time& time) const { + Caveat scope{kUwMacaroonCaveatTypeScope, kUwMacaroonCaveatScopeTypeOwner}; + Caveat issued{kUwMacaroonCaveatTypeIssued, + static_cast<uint32_t>(time.ToTimeT())}; + + UwMacaroonCaveat caveats[] = { + scope.GetCaveat(), issued.GetCaveat(), + }; + + UwMacaroon macaroon{}; + CHECK(uw_macaroon_new_from_root_key_( + &macaroon, secret_.data(), secret_.size(), caveats, arraysize(caveats))); + + std::vector<uint8_t> token(kMaxMacaroonSize); + size_t len = 0; + CHECK(uw_macaroon_dump_(&macaroon, token.data(), token.size(), &len)); + token.resize(len); + return token; +} + } // namespace privet } // namespace weave
diff --git a/src/privet/auth_manager.h b/src/privet/auth_manager.h index 607b820..8dd6a36 100644 --- a/src/privet/auth_manager.h +++ b/src/privet/auth_manager.h
@@ -31,6 +31,7 @@ const std::vector<uint8_t>& GetCertificateFingerprint() const { return certificate_fingerprint_; } + std::vector<uint8_t> GetRootDeviceToken(const base::Time& time) const; private: std::vector<uint8_t> secret_;
diff --git a/src/privet/auth_manager_unittest.cc b/src/privet/auth_manager_unittest.cc index c3c4ddf..a022538 100644 --- a/src/privet/auth_manager_unittest.cc +++ b/src/privet/auth_manager_unittest.cc
@@ -25,6 +25,9 @@ const std::vector<uint8_t> kSecret{69, 53, 17, 37, 80, 73, 2, 5, 79, 64, 41, 57, 12, 54, 65, 63, 72, 74, 93, 81, 20, 95, 89, 3, 94, 92, 27, 21, 49, 90, 36, 6}; + const std::vector<uint8_t> kSecret2{ + 78, 40, 39, 68, 29, 19, 70, 86, 38, 61, 13, 55, 33, 32, 51, 52, + 34, 43, 97, 48, 8, 56, 11, 99, 50, 59, 24, 26, 31, 71, 76, 28}; const std::vector<uint8_t> kFingerprint{ 22, 47, 23, 77, 42, 98, 96, 25, 83, 16, 9, 14, 91, 44, 15, 75, 60, 62, 10, 18, 82, 35, 88, 100, 30, 45, 7, 46, 67, 84, 58, 85}; @@ -37,7 +40,7 @@ } TEST_F(AuthManagerTest, DifferentSecret) { - AuthManager auth{{}, {}}; + AuthManager auth{kSecret2, {}}; EXPECT_GE(auth.GetSecret().size(), 32u); EXPECT_NE(auth_.GetSecret(), auth.GetSecret()); } @@ -104,5 +107,22 @@ } } +TEST_F(AuthManagerTest, GetRootDeviceToken) { + EXPECT_EQ("UJdl3l856QHDzlohsiGpxseCQgEARgMaVArkgA==", + Base64Encode(auth_.GetRootDeviceToken(time_))); +} + +TEST_F(AuthManagerTest, GetRootDeviceTokenDifferentTime) { + EXPECT_EQ("UHwWhChuQzQ+yb8gRGURu3GCQgEARgMaVB6rAA==", + Base64Encode(auth_.GetRootDeviceToken( + time_ + base::TimeDelta::FromDays(15)))); +} + +TEST_F(AuthManagerTest, GetRootDeviceTokenDifferentSecret) { + AuthManager auth{kSecret2, {}}; + EXPECT_EQ("UJW4F3R0YMeRctcu8aC6VpyCQgEARgMaVArkgA==", + Base64Encode(auth.GetRootDeviceToken(time_))); +} + } // namespace privet } // namespace weave
diff --git a/third_party/libuweave/src/macaroon_caveat.c b/third_party/libuweave/src/macaroon_caveat.c index a04c30d..594f9de 100644 --- a/third_party/libuweave/src/macaroon_caveat.c +++ b/third_party/libuweave/src/macaroon_caveat.c
@@ -12,7 +12,7 @@ // TODO(bozhu): Find a better way to pre-allocate memory for HMACc computations? // Are C99 variable-length arrays allowed on embedded devices? -#define HMAC_STATE_BUFFER_SIZE 300 +#define HMAC_STATE_BUFFER_SIZE 1024 static bool create_caveat_(UwMacaroonCaveatType type, const void* value, size_t value_len, uint8_t* buffer,
diff --git a/third_party/libuweave/src/macaroon_caveat.h b/third_party/libuweave/src/macaroon_caveat.h index 5f2c384..78373c8 100644 --- a/third_party/libuweave/src/macaroon_caveat.h +++ b/third_party/libuweave/src/macaroon_caveat.h
@@ -24,6 +24,13 @@ kUwMacaroonCaveatTypeSessionIdentifier = 16 } UwMacaroonCaveatType; +typedef enum { + kUwMacaroonCaveatScopeTypeOwner = 0, + kUwMacaroonCaveatScopeTypeManager = 1, + kUwMacaroonCaveatScopeTypeUser = 2, + kUwMacaroonCaveatScopeTypeViewer = 3, +} UwMacaroonCaveatScopeType; + bool uw_macaroon_caveat_create_without_value_(UwMacaroonCaveatType type, uint8_t* buffer, size_t buffer_size,