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,