Update macaroon library to 307f45bcd49f9e4088e622f23f3ce0e854345b93
Change-Id: I5e0054c0e07878d96bad781685bf23f5ae4068e2
Reviewed-on: https://weave-review.googlesource.com/2584
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc
index c82887e..027ad5a 100644
--- a/src/privet/auth_manager.cc
+++ b/src/privet/auth_manager.cc
@@ -118,11 +118,10 @@
class ServiceCaveat : public Caveat {
public:
- explicit ServiceCaveat(const std::string& id)
- : Caveat(kUwMacaroonCaveatTypeDelegateeService, id.size()) {
+ explicit ServiceCaveat(UwMacaroonCaveatCloudServiceId service_id)
+ : Caveat(kUwMacaroonCaveatTypeDelegateeService, 0) {
CHECK(uw_macaroon_caveat_create_delegatee_service_(
- reinterpret_cast<const uint8_t*>(id.data()), id.size(), buffer_.data(),
- buffer_.size(), &caveat_));
+ service_id, buffer_.data(), buffer_.size(), &caveat_));
}
DISALLOW_COPY_AND_ASSIGN(ServiceCaveat);
@@ -168,7 +167,8 @@
CHECK_EQ(kSha256OutputSize, secret.size());
UwMacaroonContext context{};
- CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, &context));
+ CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
+ &context));
UwMacaroon macaroon{};
CHECK(uw_macaroon_create_from_root_key_(&macaroon, secret.data(),
@@ -189,7 +189,8 @@
const base::Time& time,
const std::vector<const UwMacaroonCaveat*>& caveats) {
UwMacaroonContext context{};
- CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, &context));
+ CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
+ &context));
UwMacaroon prev_macaroon = macaroon;
std::vector<uint8_t> prev_buffer(kMaxMacaroonSize);
@@ -232,7 +233,8 @@
ErrorPtr* error) {
CHECK_EQ(kSha256OutputSize, secret.size());
UwMacaroonContext context = {};
- CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, &context));
+ CHECK(uw_macaroon_context_create_(ToJ2000Time(time), nullptr, 0, nullptr, 0,
+ &context));
if (!uw_macaroon_validate_(&macaroon, secret.data(), secret.size(), &context,
result)) {
@@ -432,8 +434,9 @@
const base::Time now = Now();
TimestampCaveat issued{now};
- ServiceCaveat client{owner == RootClientTokenOwner::kCloud ? "google.com"
- : ""};
+ ServiceCaveat client{owner == RootClientTokenOwner::kCloud
+ ? kUwMacaroonCaveatCloudServiceIdGoogleWeave
+ : kUwMacaroonCaveatCloudServiceIdNotCloudRegistered};
return CreateMacaroonToken(
auth_secret_, now,
{
diff --git a/src/privet/auth_manager_unittest.cc b/src/privet/auth_manager_unittest.cc
index 294aefa..3e5aeab 100644
--- a/src/privet/auth_manager_unittest.cc
+++ b/src/privet/auth_manager_unittest.cc
@@ -190,21 +190,21 @@
}
TEST_F(AuthManagerTest, GetRootClientAuthToken) {
- EXPECT_EQ("WCCDQxkgAUYIGhudoQBCDEBQZgRhYq78I8GtFUZHNBbfGw==",
+ EXPECT_EQ("WCCDQxkgAUYIGhudoQBCDABQX3fPR5zsPnrs9aOSvS7/eQ==",
Base64Encode(
auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
}
TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentOwner) {
EXPECT_EQ(
- "WCqDQxkgAUYIGhudoQBMDEpnb29nbGUuY29tUOoLAxSUAZAAv54drarqhag=",
+ "WCCDQxkgAUYIGhudoQBCDAFQRrCQfq+g7drVwCbxpug4Ig==",
Base64Encode(auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud)));
}
TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentTime) {
auto new_time = clock_.Now() + base::TimeDelta::FromDays(15);
EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
- EXPECT_EQ("WCCDQxkgAUYIGhuxZ4BCDEBQjO+OTbjjTzZ/Dvk66nfQqg==",
+ EXPECT_EQ("WCCDQxkgAUYIGhuxZ4BCDABQ9omJ3ooMrcYUZ1DiVqNKAA==",
Base64Encode(
auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
}
@@ -212,7 +212,7 @@
TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentSecret) {
AuthManager auth{kSecret2, {}, kSecret1, &clock_};
EXPECT_EQ(
- "WCCDQxkgAUYIGhudoQBCDEBQ2MZF8YXv5pbtmMxwz9VtLA==",
+ "WCCDQxkgAUYIGhudoQBCDABQWl2CB8CiP1BiV0ksnnkQQQ==",
Base64Encode(auth.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
}
@@ -253,8 +253,8 @@
auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
UserInfo{AuthScope::kUser, TestUserId{"234"}});
EXPECT_EQ(
- "WE+IQxkgAUYIGhudoQBMDEpnb29nbGUuY29tRggaG52hAEYFGhudpOhCAQ5FCUMyMzRNEUs0"
- "NjMzMTUyMDA6MVCRVKU+0SpOoBppnwqdKMwP",
+ "WEWIQxkgAUYIGhudoQBCDAFGCBobnaEARgUaG52k6EIBDkUJQzIzNE0RSzQ2MzMxNTIwMDox"
+ "UIujtnCZlcRvJPOra5BwM6E=",
Base64Encode(extended));
EXPECT_TRUE(
auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
diff --git a/third_party/libuweave/src/macaroon.h b/third_party/libuweave/src/macaroon.h
index c739bca..5e73b28 100644
--- a/third_party/libuweave/src/macaroon.h
+++ b/third_party/libuweave/src/macaroon.h
@@ -33,9 +33,10 @@
} UwMacaroonDelegateeType;
typedef struct {
+ UwMacaroonDelegateeType type;
const uint8_t* id;
size_t id_len;
- UwMacaroonDelegateeType type;
+ UwMacaroonCaveatCloudServiceId service_id; // Only for cloud services
uint32_t timestamp;
} UwMacaroonDelegateeInfo;
@@ -71,12 +72,11 @@
* result object. Note that the resulting granted_scope will be the closest
* valid scope type (to the narrower side) defined in macaroon_caveat.h.
*/
-bool uw_macaroon_validate_(
- const UwMacaroon* macaroon,
- const uint8_t* root_key,
- size_t root_key_len,
- const UwMacaroonContext* context,
- UwMacaroonValidationResult* result);
+bool uw_macaroon_validate_(const UwMacaroon* macaroon,
+ const uint8_t* root_key,
+ size_t root_key_len,
+ const UwMacaroonContext* context,
+ UwMacaroonValidationResult* result);
/** Encode a Macaroon to a byte string. */
bool uw_macaroon_serialize_(const UwMacaroon* macaroon,
diff --git a/third_party/libuweave/src/macaroon_caveat.c b/third_party/libuweave/src/macaroon_caveat.c
index dc4ee3b..0abf7ca 100644
--- a/third_party/libuweave/src/macaroon_caveat.c
+++ b/third_party/libuweave/src/macaroon_caveat.c
@@ -26,6 +26,7 @@
case kUwMacaroonCaveatTypeDelegateeService:
case kUwMacaroonCaveatTypeBleSessionID:
case kUwMacaroonCaveatTypeLanSessionID:
+ case kUwMacaroonCaveatTypeAuthenticationChallenge:
case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
return true;
@@ -44,11 +45,20 @@
return false;
}
+static bool is_valid_service_id_(UwMacaroonCaveatCloudServiceId service_id) {
+ switch (service_id) {
+ case kUwMacaroonCaveatCloudServiceIdNotCloudRegistered:
+ case kUwMacaroonCaveatCloudServiceIdGoogleWeave:
+ return true;
+ }
+ return false;
+}
+
static bool create_caveat_no_value_(UwMacaroonCaveatType type,
uint8_t* buffer,
size_t buffer_size,
UwMacaroonCaveat* new_caveat) {
- // (buffer_size == 0 || get_buffer_size_() > buffer_size) will conver the case
+ // (buffer_size == 0 || get_buffsize_() > buffer_size) will conver the case
// that get_buffer_size_() returns 0 (for errors), so there is no need to
// check get_buffer_size_() == 0 again.
if (buffer == NULL || buffer_size == 0 || new_caveat == NULL ||
@@ -134,10 +144,12 @@
case kUwMacaroonCaveatTypeTTL24Hour:
case kUwMacaroonCaveatTypeAppCommandsOnly:
case kUwMacaroonCaveatTypeBleSessionID:
+ case kUwMacaroonCaveatTypeAuthenticationChallenge:
return UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
// Unsigned integers
case kUwMacaroonCaveatTypeScope:
+ case kUwMacaroonCaveatTypeDelegateeService:
case kUwMacaroonCaveatTypeExpirationAbsolute:
case kUwMacaroonCaveatTypeDelegationTimestamp:
return 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
@@ -146,11 +158,10 @@
case kUwMacaroonCaveatTypeNonce:
case kUwMacaroonCaveatTypeDelegateeUser:
case kUwMacaroonCaveatTypeDelegateeApp:
- case kUwMacaroonCaveatTypeDelegateeService:
case kUwMacaroonCaveatTypeLanSessionID:
case kUwMacaroonCaveatTypeClientAuthorizationTokenV1:
case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
- return str_len + UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
+ return str_len + 2 * UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN;
default:
return 0; // For errors
@@ -238,13 +249,16 @@
}
bool uw_macaroon_caveat_create_delegatee_service_(
- const uint8_t* id_str,
- size_t id_str_len,
+ UwMacaroonCaveatCloudServiceId service_id,
uint8_t* buffer,
size_t buffer_size,
UwMacaroonCaveat* new_caveat) {
- return create_caveat_bstr_value_(kUwMacaroonCaveatTypeDelegateeService,
- id_str, id_str_len, buffer, buffer_size,
+ if (!is_valid_service_id_(service_id)) {
+ return false;
+ }
+
+ return create_caveat_uint_value_(kUwMacaroonCaveatTypeDelegateeService,
+ (uint32_t)service_id, buffer, buffer_size,
new_caveat);
}
@@ -265,6 +279,14 @@
buffer_size, new_caveat);
}
+bool uw_macaroon_caveat_create_authentication_challenge_(
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat) {
+ return create_caveat_no_value_(kUwMacaroonCaveatTypeAuthenticationChallenge,
+ buffer, buffer_size, new_caveat);
+}
+
bool uw_macaroon_caveat_create_client_authorization_token_(
const uint8_t* str,
size_t str_len,
@@ -336,17 +358,18 @@
// If there is no additional value from the context, just compute the HMAC on
// the current byte string.
- uint8_t bstr_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
- size_t bstr_cbor_prefix_len = 0;
- if (caveat_type != kUwMacaroonCaveatTypeBleSessionID) {
+ uint8_t caveat_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
+ size_t caveat_cbor_prefix_len = 0;
+ if (caveat_type != kUwMacaroonCaveatTypeBleSessionID &&
+ caveat_type != kUwMacaroonCaveatTypeAuthenticationChallenge) {
if (!uw_macaroon_encoding_encode_byte_str_len_(
- (uint32_t)(caveat->num_bytes), bstr_cbor_prefix,
- sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
+ (uint32_t)(caveat->num_bytes), caveat_cbor_prefix,
+ sizeof(caveat_cbor_prefix), &caveat_cbor_prefix_len)) {
return false;
}
UwCryptoHmacMsg messages[] = {
- {bstr_cbor_prefix, bstr_cbor_prefix_len},
+ {caveat_cbor_prefix, caveat_cbor_prefix_len},
{caveat->bytes, caveat->num_bytes},
};
@@ -356,30 +379,48 @@
}
// If there is additional value from the context.
- if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
- return false;
- }
+ const uint8_t* additional_value_str = NULL;
+ size_t additional_value_str_len = 0;
+ if (caveat_type == kUwMacaroonCaveatTypeBleSessionID) {
+ if (context->ble_session_id == NULL || context->ble_session_id_len == 0) {
+ return false;
+ }
- // The length here includes the length of the BLE session ID string.
- if (!uw_macaroon_encoding_encode_byte_str_len_(
- (uint32_t)(context->ble_session_id_len + caveat->num_bytes),
- bstr_cbor_prefix, sizeof(bstr_cbor_prefix), &bstr_cbor_prefix_len)) {
- return false;
+ additional_value_str = context->ble_session_id;
+ additional_value_str_len = context->ble_session_id_len;
+ } else { // kUwMacaroonCaveatTypeAuthenticationChallenge
+ if (context->auth_challenge_str == NULL ||
+ context->auth_challenge_str_len == 0) {
+ return false;
+ }
+
+ additional_value_str = context->auth_challenge_str;
+ additional_value_str_len = context->auth_challenge_str_len;
}
uint8_t value_cbor_prefix[UW_MACAROON_ENCODING_MAX_UINT_CBOR_LEN] = {0};
size_t value_cbor_prefix_len = 0;
if (!uw_macaroon_encoding_encode_byte_str_len_(
- (uint32_t)(context->ble_session_id_len), value_cbor_prefix,
+ (uint32_t)additional_value_str_len, value_cbor_prefix,
sizeof(value_cbor_prefix), &value_cbor_prefix_len)) {
return false;
}
+ // The length here includes: 1. the header for the whole byte string; 2. the
+ // header for the addtional value part; 3. the additional value part.
+ size_t total_length =
+ caveat->num_bytes + value_cbor_prefix_len + additional_value_str_len;
+ if (!uw_macaroon_encoding_encode_byte_str_len_(
+ (uint32_t)total_length, caveat_cbor_prefix,
+ sizeof(caveat_cbor_prefix), &caveat_cbor_prefix_len)) {
+ return false;
+ }
+
UwCryptoHmacMsg messages[] = {
- {bstr_cbor_prefix, bstr_cbor_prefix_len},
+ {caveat_cbor_prefix, caveat_cbor_prefix_len},
{caveat->bytes, caveat->num_bytes},
{value_cbor_prefix, value_cbor_prefix_len},
- {context->ble_session_id, context->ble_session_id_len},
+ {additional_value_str, additional_value_str_len},
};
return uw_crypto_hmac_(key, key_len, messages,
@@ -433,11 +474,29 @@
}
}
- if (!uw_macaroon_caveat_get_value_bstr_(
- caveat, &(result->delegatees[result->num_delegatees].id),
- &(result->delegatees[result->num_delegatees].id_len))) {
- return false;
+ if (caveat_type != kUwMacaroonCaveatTypeDelegateeService) {
+ if (!uw_macaroon_caveat_get_value_bstr_(
+ caveat, &(result->delegatees[result->num_delegatees].id),
+ &(result->delegatees[result->num_delegatees].id_len))) {
+ return false;
+ }
+ result->delegatees[result->num_delegatees].service_id =
+ kUwMacaroonCaveatCloudServiceIdNotCloudRegistered; // Default value
+
+ } else {
+ uint32_t service_id = 0;
+ if (!uw_macaroon_caveat_get_value_uint_(caveat, &service_id)) {
+ return false;
+ }
+ if (!is_valid_service_id_((UwMacaroonCaveatCloudServiceId)service_id)) {
+ return false;
+ }
+ result->delegatees[result->num_delegatees].service_id =
+ (UwMacaroonCaveatCloudServiceId)service_id;
+ result->delegatees[result->num_delegatees].id = NULL;
+ result->delegatees[result->num_delegatees].id_len = 0;
}
+
result->delegatees[result->num_delegatees].type = delegatee_type;
result->delegatees[result->num_delegatees].timestamp = issued_time;
result->num_delegatees++;
@@ -467,6 +526,7 @@
case kUwMacaroonCaveatTypeServerAuthenticationTokenV1:
case kUwMacaroonCaveatTypeNonce:
case kUwMacaroonCaveatTypeBleSessionID:
+ case kUwMacaroonCaveatTypeAuthenticationChallenge:
return true;
case kUwMacaroonCaveatTypeDelegationTimestamp:
@@ -541,6 +601,7 @@
return false;
}
if (type != kUwMacaroonCaveatTypeScope &&
+ type != kUwMacaroonCaveatTypeDelegateeService &&
type != kUwMacaroonCaveatTypeExpirationAbsolute &&
type != kUwMacaroonCaveatTypeDelegationTimestamp) {
// Wrong type
@@ -572,7 +633,6 @@
if (type != kUwMacaroonCaveatTypeNonce &&
type != kUwMacaroonCaveatTypeDelegateeUser &&
type != kUwMacaroonCaveatTypeDelegateeApp &&
- type != kUwMacaroonCaveatTypeDelegateeService &&
type != kUwMacaroonCaveatTypeLanSessionID &&
type != kUwMacaroonCaveatTypeClientAuthorizationTokenV1 &&
type != kUwMacaroonCaveatTypeServerAuthenticationTokenV1) {
diff --git a/third_party/libuweave/src/macaroon_caveat.h b/third_party/libuweave/src/macaroon_caveat.h
index 4905667..5250ac1 100644
--- a/third_party/libuweave/src/macaroon_caveat.h
+++ b/third_party/libuweave/src/macaroon_caveat.h
@@ -24,11 +24,14 @@
kUwMacaroonCaveatTypeDelegateeUser = 9, // bstr
kUwMacaroonCaveatTypeDelegateeApp = 10, // bstr
- kUwMacaroonCaveatTypeDelegateeService = 12, // bstr
+ kUwMacaroonCaveatTypeDelegateeService = 12, // uint
- kUwMacaroonCaveatTypeAppCommandsOnly = 11, // no value
- kUwMacaroonCaveatTypeBleSessionID = 16, // no value
- kUwMacaroonCaveatTypeLanSessionID = 17, // bstr
+ kUwMacaroonCaveatTypeAppCommandsOnly = 11, // no value
+ kUwMacaroonCaveatTypeBleSessionID = 16, // no value
+ kUwMacaroonCaveatTypeLanSessionID = 17, // bstr
+
+ kUwMacaroonCaveatTypeAuthenticationChallenge = 20, // no value
+
kUwMacaroonCaveatTypeClientAuthorizationTokenV1 = 8193, // bstr (0x2001)
kUwMacaroonCaveatTypeServerAuthenticationTokenV1 = 12289, // bstr (0x3001)
} UwMacaroonCaveatType;
@@ -40,6 +43,11 @@
kUwMacaroonCaveatScopeTypeViewer = 20,
} UwMacaroonCaveatScopeType;
+typedef enum {
+ kUwMacaroonCaveatCloudServiceIdNotCloudRegistered = 0,
+ kUwMacaroonCaveatCloudServiceIdGoogleWeave = 1,
+} UwMacaroonCaveatCloudServiceId;
+
// For security sanity checks
#define UW_MACAROON_CAVEAT_SCOPE_LOWEST_POSSIBLE 127
@@ -83,11 +91,13 @@
uint8_t* buffer,
size_t buffer_size,
UwMacaroonCaveat* new_caveat);
-bool uw_macaroon_caveat_create_delegatee_service_(const uint8_t* id_str,
- size_t id_str_len,
- uint8_t* buffer,
- size_t buffer_size,
- UwMacaroonCaveat* new_caveat);
+
+bool uw_macaroon_caveat_create_delegatee_service_(
+ UwMacaroonCaveatCloudServiceId service_id,
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+
bool uw_macaroon_caveat_create_app_commands_only_(uint8_t* buffer,
size_t buffer_size,
UwMacaroonCaveat* new_caveat);
@@ -100,6 +110,11 @@
size_t buffer_size,
UwMacaroonCaveat* new_caveat);
+bool uw_macaroon_caveat_create_authentication_challenge_(
+ uint8_t* buffer,
+ size_t buffer_size,
+ UwMacaroonCaveat* new_caveat);
+
// The string values for these two token types are optional.
// Use str_len = 0 to indicate creating the caveats without string values.
bool uw_macaroon_caveat_create_client_authorization_token_(
diff --git a/third_party/libuweave/src/macaroon_context.c b/third_party/libuweave/src/macaroon_context.c
index 2f1685d..e33bdd5 100644
--- a/third_party/libuweave/src/macaroon_context.c
+++ b/third_party/libuweave/src/macaroon_context.c
@@ -7,16 +7,22 @@
bool uw_macaroon_context_create_(uint32_t current_time,
const uint8_t* ble_session_id,
size_t ble_session_id_len,
+ const uint8_t* auth_challenge_str,
+ size_t auth_challenge_str_len,
UwMacaroonContext* new_context) {
- if (ble_session_id == NULL && ble_session_id_len != 0) {
+ if ((ble_session_id == NULL && ble_session_id_len != 0) ||
+ (auth_challenge_str == NULL && auth_challenge_str_len != 0)) {
return false;
}
if (new_context == NULL) {
return false;
}
+ *new_context = (UwMacaroonContext){};
new_context->current_time = current_time;
new_context->ble_session_id = ble_session_id;
new_context->ble_session_id_len = ble_session_id_len;
+ new_context->auth_challenge_str = auth_challenge_str;
+ new_context->auth_challenge_str_len = auth_challenge_str_len;
return true;
}
diff --git a/third_party/libuweave/src/macaroon_context.h b/third_party/libuweave/src/macaroon_context.h
index c230eb7..762f232 100644
--- a/third_party/libuweave/src/macaroon_context.h
+++ b/third_party/libuweave/src/macaroon_context.h
@@ -15,11 +15,15 @@
uint32_t current_time; // In number of seconds since Jan 1st 2000 00:00:00
const uint8_t* ble_session_id; // Only for BLE
size_t ble_session_id_len;
+ const uint8_t* auth_challenge_str;
+ size_t auth_challenge_str_len;
} UwMacaroonContext;
bool uw_macaroon_context_create_(uint32_t current_time,
const uint8_t* ble_session_id,
size_t ble_session_id_len,
+ const uint8_t* auth_challenge_str,
+ size_t auth_challenge_str_len,
UwMacaroonContext* new_context);
#endif // LIBUWEAVE_SRC_MACAROON_CONTEXT_