f51743b Update macaroon library to 307f45bcd49f9e4088e622f23f3ce0e854345b93 * weave/master: Update macaroon library to 307f45bcd49f9e4088e622f23f3ce0e854345b93
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_