Skip to content

Commit

Permalink
Add more Client Hints
Browse files Browse the repository at this point in the history
* Google Play Services version
* Cert Scope
* Cert Scope Signature

b/348076343
b/319156683
  • Loading branch information
gbournou committed Jul 3, 2024
1 parent 3d783ce commit 9ccac82
Show file tree
Hide file tree
Showing 18 changed files with 195 additions and 21 deletions.
7 changes: 7 additions & 0 deletions cobalt/browser/client_hint_headers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,19 @@ std::vector<std::string> GetClientHintHeaders(
const UserAgentPlatformInfo& platform_info) {
std::vector<std::string> headers;

AddHeader(headers, "Cert-Scope", platform_info.cert_scope());

AddHeader(headers, "Cert-Scope-Sig", platform_info.cert_scope_sig());

AddHeader(headers, "Android-Build-Fingerprint",
platform_info.android_build_fingerprint());

AddHeader(headers, "Android-OS-Experience",
platform_info.android_os_experience());

AddHeader(headers, "Android-Play-Services-Version",
platform_info.android_play_services_version());

return headers;
}

Expand Down
8 changes: 7 additions & 1 deletion cobalt/browser/client_hint_headers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ using ::testing::UnorderedElementsAre;

TEST(ClientHintHeadersTest, GetClientHintHeaders) {
UserAgentPlatformInfo platform_info;
platform_info.set_cert_scope("testing-scope-123");
platform_info.set_cert_scope_sig("testing-scope-signature");
platform_info.set_android_build_fingerprint("abc/def:123.456/xy-z");
platform_info.set_android_os_experience("Amati");
platform_info.set_android_play_services_version("123");

std::vector<std::string> headers = GetClientHintHeaders(platform_info);
EXPECT_THAT(headers,
UnorderedElementsAre(
"Sec-CH-UA-Co-Cert-Scope:testing-scope-123",
"Sec-CH-UA-Co-Cert-Scope-Sig:testing-scope-signature",
"Sec-CH-UA-Co-Android-Build-Fingerprint:abc/def:123.456/xy-z",
"Sec-CH-UA-Co-Android-OS-Experience:Amati"));
"Sec-CH-UA-Co-Android-OS-Experience:Amati",
"Sec-CH-UA-Co-Android-Play-Services-Version:123"));
}

} // namespace
Expand Down
23 changes: 18 additions & 5 deletions cobalt/browser/device_authentication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,18 +102,31 @@ std::string GetStartTime() {

} // namespace

void GenerateCertScopeSignature(const std::string& cert_scope,
std::string* out_signature,
std::string* out_start_time) {
if (cert_scope.empty() || out_signature == nullptr) {
return;
}
std::string start_time = GetStartTime();
CHECK(!start_time.empty());
if (out_start_time != nullptr) {
*out_start_time = start_time;
}
*out_signature =
ComputeBase64Signature(ComputeMessage(cert_scope, start_time));
}

std::string GetDeviceAuthenticationSignedURLQueryString() {
std::string cert_scope = GetCertScopeFromPlatform();
if (cert_scope.empty()) {
LOG(WARNING) << "Error retrieving certification scope required for "
<< "device authentication.";
return std::string();
}
std::string start_time = GetStartTime();
CHECK(!start_time.empty());

std::string base64_signature =
ComputeBase64Signature(ComputeMessage(cert_scope, start_time));
std::string base64_signature;
std::string start_time;
GenerateCertScopeSignature(cert_scope, &base64_signature, &start_time);

return GetDeviceAuthenticationSignedURLQueryStringFromComponents(
cert_scope, start_time, base64_signature);
Expand Down
6 changes: 6 additions & 0 deletions cobalt/browser/device_authentication.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
namespace cobalt {
namespace browser {

// Generates the Cert Scope signature in the provided output parameter, and
// optionally returns the start_time used as well.
void GenerateCertScopeSignature(const std::string& cert_scope,
std::string* out_signature,
std::string* out_start_time);

// Returns a base64 encoded SHA256 hash representing the device authentication
// signature based on the device certification scope and the current time.
std::string GetDeviceAuthenticationSignedURLQueryString();
Expand Down
64 changes: 55 additions & 9 deletions cobalt/browser/user_agent_platform_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "cobalt/browser/device_authentication.h"
#include "cobalt/browser/switches.h"
#include "cobalt/configuration/configuration.h"
#include "cobalt/renderer/get_default_rasterizer_for_platform.h"
Expand Down Expand Up @@ -276,20 +277,41 @@ void InitializeUserAgentPlatformInfoFields(UserAgentPlatformInfo& info) {
}
#endif

// Cert Scope
result = SbSystemGetProperty(kSbSystemPropertyCertificationScope, value,
kSystemPropertyMaxLength);
if (result) {
info.set_cert_scope(value);
}

// Cert Scope Signature
if (!info.cert_scope().empty()) {
std::string signature;
GenerateCertScopeSignature(info.cert_scope(), &signature, nullptr);
info.set_cert_scope_sig(signature);
}

// Additional Platform Info
auto platform_info_extension =
static_cast<const CobaltExtensionPlatformInfoApi*>(
SbSystemGetExtension(kCobaltExtensionPlatformInfoName));
if (platform_info_extension &&
strcmp(platform_info_extension->name, kCobaltExtensionPlatformInfoName) ==
0 &&
platform_info_extension->version >= 1) {
result = platform_info_extension->GetFirmwareVersionDetails(
value, kSystemPropertyMaxLength);
if (result) {
info.set_android_build_fingerprint(value);
if (platform_info_extension) {
if (platform_info_extension->version >= 1) {
result = platform_info_extension->GetFirmwareVersionDetails(
value, kSystemPropertyMaxLength);
if (result) {
info.set_android_build_fingerprint(value);
}
info.set_android_os_experience(
platform_info_extension->GetOsExperience());
}
if (platform_info_extension->version >= 2) {
int64_t ver = platform_info_extension->GetCoreServicesVersion();
if (ver != 0) {
std::string sver = std::to_string(ver);
info.set_android_play_services_version(sver);
}
}
info.set_android_os_experience(platform_info_extension->GetOsExperience());
}

info.set_cobalt_version(COBALT_VERSION);
Expand Down Expand Up @@ -427,12 +449,21 @@ void InitializeUserAgentPlatformInfoFields(UserAgentPlatformInfo& info) {
} else if (!input.first.compare("evergreen_version")) {
info.set_evergreen_version(input.second);
LOG(INFO) << "Set evergreen version to " << input.second;
} else if (!input.first.compare("cert_scope")) {
info.set_cert_scope(input.second);
LOG(INFO) << "Set cert scope to " << input.second;
} else if (!input.first.compare("cert_scope_sig")) {
info.set_cert_scope_sig(input.second);
LOG(INFO) << "Set cert scope sig to " << input.second;
} else if (!input.first.compare("android_build_fingerprint")) {
info.set_android_build_fingerprint(input.second);
LOG(INFO) << "Set android build fingerprint to " << input.second;
} else if (!input.first.compare("android_os_experience")) {
info.set_android_os_experience(input.second);
LOG(INFO) << "Set android os experience to " << input.second;
} else if (!input.first.compare("android_play_services_version")) {
info.set_android_play_services_version(input.second);
LOG(INFO) << "Set android play services version to " << input.second;
} else if (!input.first.compare("cobalt_version")) {
info.set_cobalt_version(input.second);
LOG(INFO) << "Set cobalt type to " << input.second;
Expand Down Expand Up @@ -548,6 +579,15 @@ void UserAgentPlatformInfo::set_evergreen_version(
evergreen_version_ = Sanitize(evergreen_version, isTCHAR);
}

void UserAgentPlatformInfo::set_cert_scope(const std::string& cert_scope) {
cert_scope_ = Sanitize(cert_scope, isTCHAR);
}

void UserAgentPlatformInfo::set_cert_scope_sig(
const std::string& cert_scope_sig) {
cert_scope_sig_ = Sanitize(cert_scope_sig, isTCHAR);
}

void UserAgentPlatformInfo::set_android_build_fingerprint(
const std::string& android_build_fingerprint) {
android_build_fingerprint_ =
Expand All @@ -559,6 +599,12 @@ void UserAgentPlatformInfo::set_android_os_experience(
android_os_experience_ = Sanitize(android_os_experience, isTCHAR);
}

void UserAgentPlatformInfo::set_android_play_services_version(
const std::string& android_play_services_version) {
android_play_services_version_ =
Sanitize(android_play_services_version, base::IsAsciiDigit);
}

void UserAgentPlatformInfo::set_cobalt_version(
const std::string& cobalt_version) {
cobalt_version_ = Sanitize(cobalt_version, isTCHAR);
Expand Down
16 changes: 14 additions & 2 deletions cobalt/browser/user_agent_platform_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,17 @@ class UserAgentPlatformInfo : public web::UserAgentPlatformInfo {
const std::string& evergreen_version() const override {
return evergreen_version_;
}
const std::string& cert_scope() const override { return cert_scope_; }
const std::string& cert_scope_sig() const override { return cert_scope_sig_; }
const std::string& android_build_fingerprint() const override {
return android_build_fingerprint_;
}
const std::string& android_os_experience() const override {
return android_os_experience_;
}
const std::string& android_play_services_version() const override {
return android_play_services_version_;
}
const std::string& cobalt_version() const override { return cobalt_version_; }
const std::string& cobalt_build_version_number() const override {
return cobalt_build_version_number_;
Expand Down Expand Up @@ -115,9 +120,13 @@ class UserAgentPlatformInfo : public web::UserAgentPlatformInfo {
void set_evergreen_type(const std::string& evergreen_type);
void set_evergreen_file_type(const std::string& evergreen_file_type);
void set_evergreen_version(const std::string& evergreen_version);
void set_cert_scope(const std::string& cert_scope);
void set_cert_scope_sig(const std::string& cert_scope_sig);
void set_android_build_fingerprint(
const std::string& android_build_fingerprint);
void set_android_os_experience(const std::string& android_os_experience);
void set_android_play_services_version(
const std::string& android_play_services_version);
void set_cobalt_version(const std::string& cobalt_version);
void set_cobalt_build_version_number(
const std::string& cobalt_build_version_number);
Expand All @@ -142,8 +151,11 @@ class UserAgentPlatformInfo : public web::UserAgentPlatformInfo {
std::string evergreen_type_;
std::string evergreen_file_type_;
std::string evergreen_version_;
std::string android_build_fingerprint_; // Only via Client Hints
std::string android_os_experience_; // Only via Client Hints
std::string cert_scope_; // Only via Client Hints
std::string cert_scope_sig_; // Only via Client Hints
std::string android_build_fingerprint_; // Only via Client Hints
std::string android_os_experience_; // Only via Client Hints
std::string android_play_services_version_; // Only via Client Hints

std::string cobalt_version_;
std::string cobalt_build_version_number_;
Expand Down
3 changes: 3 additions & 0 deletions cobalt/web/cobalt_ua_data_values.idl
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ dictionary CobaltUADataValues : UADataValues {
DOMString evergreenType;
DOMString evergreenFileType;
DOMString evergreenVersion;
DOMString certScope;
DOMString certScopeSig;
DOMString androidBuildFingerprint;
DOMString androidOsExperience;
DOMString androidPlayServicesVersion;
DOMString starboardVersion;
DOMString originalDesignManufacturer;
DOMString deviceType;
Expand Down
9 changes: 9 additions & 0 deletions cobalt/web/cobalt_ua_data_values_interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,21 @@ CobaltUADataValuesInterface::CobaltUADataValuesInterface(
if (init_dict.has_evergreen_version()) {
evergreen_version_ = init_dict.evergreen_version();
}
if (init_dict.has_cert_scope()) {
cert_scope_ = init_dict.cert_scope();
}
if (init_dict.has_cert_scope_sig()) {
cert_scope_sig_ = init_dict.cert_scope_sig();
}
if (init_dict.has_android_build_fingerprint()) {
android_build_fingerprint_ = init_dict.android_build_fingerprint();
}
if (init_dict.has_android_os_experience()) {
android_os_experience_ = init_dict.android_os_experience();
}
if (init_dict.has_android_play_services_version()) {
android_play_services_version_ = init_dict.android_play_services_version();
}
if (init_dict.has_starboard_version()) {
starboard_version_ = init_dict.starboard_version();
}
Expand Down
8 changes: 8 additions & 0 deletions cobalt/web/cobalt_ua_data_values_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,17 @@ class CobaltUADataValuesInterface : public script::Wrappable {
return evergreen_file_type_;
}
const std::string& evergreen_version() const { return evergreen_version_; }
const std::string& cert_scope() const { return cert_scope_; }
const std::string& cert_scope_sig() const { return cert_scope_sig_; }
const std::string& android_build_fingerprint() const {
return android_build_fingerprint_;
}
const std::string& android_os_experience() const {
return android_os_experience_;
}
const std::string& android_play_services_version() const {
return android_play_services_version_;
}
const std::string& starboard_version() const { return starboard_version_; }
const std::string& original_design_manufacturer() const {
return original_design_manufacturer_;
Expand Down Expand Up @@ -85,8 +90,11 @@ class CobaltUADataValuesInterface : public script::Wrappable {
std::string evergreen_type_;
std::string evergreen_file_type_;
std::string evergreen_version_;
std::string cert_scope_;
std::string cert_scope_sig_;
std::string android_build_fingerprint_;
std::string android_os_experience_;
std::string android_play_services_version_;
std::string starboard_version_;
std::string original_design_manufacturer_;
std::string device_type_;
Expand Down
3 changes: 3 additions & 0 deletions cobalt/web/cobalt_ua_data_values_interface.idl
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ interface CobaltUADataValuesInterface {
readonly attribute DOMString evergreenType;
readonly attribute DOMString evergreenFileType;
readonly attribute DOMString evergreenVersion;
readonly attribute DOMString certScope;
readonly attribute DOMString certScopeSig;
readonly attribute DOMString androidBuildFingerprint;
readonly attribute DOMString androidOsExperience;
readonly attribute DOMString androidPlayServicesVersion;
readonly attribute DOMString starboardVersion;
readonly attribute DOMString originalDesignManufacturer;
readonly attribute DOMString deviceType;
Expand Down
4 changes: 4 additions & 0 deletions cobalt/web/navigator_ua_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ NavigatorUAData::NavigatorUAData(
platform_info->evergreen_file_type());
all_high_entropy_values_.set_evergreen_version(
platform_info->evergreen_version());
all_high_entropy_values_.set_cert_scope(platform_info->cert_scope());
all_high_entropy_values_.set_cert_scope_sig(platform_info->cert_scope_sig());
all_high_entropy_values_.set_android_build_fingerprint(
platform_info->android_build_fingerprint());
all_high_entropy_values_.set_android_os_experience(
platform_info->android_os_experience());
all_high_entropy_values_.set_android_play_services_version(
platform_info->android_play_services_version());
all_high_entropy_values_.set_starboard_version(
platform_info->starboard_version());
all_high_entropy_values_.set_original_design_manufacturer(
Expand Down
7 changes: 6 additions & 1 deletion cobalt/web/testing/mock_user_agent_platform_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace testing {
class MockUserAgentPlatformInfo : public web::UserAgentPlatformInfo {
public:
MockUserAgentPlatformInfo() {}
~MockUserAgentPlatformInfo() override{};
~MockUserAgentPlatformInfo() override {};

// From: dom:UserAgentPlatformInfo
//
Expand Down Expand Up @@ -75,12 +75,17 @@ class MockUserAgentPlatformInfo : public web::UserAgentPlatformInfo {
const std::string& evergreen_version() const override {
return empty_string_;
}
const std::string& cert_scope() const override { return empty_string_; }
const std::string& cert_scope_sig() const override { return empty_string_; }
const std::string& android_build_fingerprint() const override {
return empty_string_;
}
const std::string& android_os_experience() const override {
return empty_string_;
}
const std::string& android_play_services_version() const override {
return empty_string_;
}
const std::string& cobalt_version() const override { return empty_string_; }
const std::string& cobalt_build_version_number() const override {
return empty_string_;
Expand Down
3 changes: 3 additions & 0 deletions cobalt/web/user_agent_platform_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ class UserAgentPlatformInfo {
virtual const std::string& evergreen_type() const = 0;
virtual const std::string& evergreen_file_type() const = 0;
virtual const std::string& evergreen_version() const = 0;
virtual const std::string& cert_scope() const = 0;
virtual const std::string& cert_scope_sig() const = 0;
virtual const std::string& android_build_fingerprint() const = 0;
virtual const std::string& android_os_experience() const = 0;
virtual const std::string& android_play_services_version() const = 0;

virtual const std::string& cobalt_version() const = 0;
virtual const std::string& cobalt_build_version_number() const = 0;
Expand Down
1 change: 1 addition & 0 deletions starboard/android/apk/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ android {
applicationId "dev.cobalt.coat"
minSdkVersion 24
targetSdkVersion 34
compileSdkVersion 34
versionCode 1
versionName "${buildId}"
manifestPlaceholders = [
Expand Down
Loading

0 comments on commit 9ccac82

Please sign in to comment.