Commit ae81e524 authored by Jeevan Shikaram's avatar Jeevan Shikaram Committed by Commit Bot

[PWA-in-Play] Add certificate fingerprint to web_apps_to_apks dict.

This CL stores the certificate fingerprint from WebAppInfo in the
web_apps_to_apks dict to be used for digital asset link verification.
This is done to prevent the costly operation of converting the
fingerprint to a hash every time we need to verify the relationship.

Bug: 1026469
Change-Id: I33e2a40b46eac8da7ea865bd76523f43a3a218aa
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2198836
Commit-Queue: Jeevan Shikaram <jshikaram@chromium.org>
Reviewed-by: default avatarDominick Ng <dominickn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768580}
parent 86511b98
...@@ -52,6 +52,7 @@ ApkWebAppInstaller::ApkWebAppInstaller(Profile* profile, ...@@ -52,6 +52,7 @@ ApkWebAppInstaller::ApkWebAppInstaller(Profile* profile,
base::WeakPtr<Owner> weak_owner) base::WeakPtr<Owner> weak_owner)
: profile_(profile), : profile_(profile),
is_web_only_twa_(false), is_web_only_twa_(false),
sha256_fingerprint_(base::nullopt),
callback_(std::move(callback)), callback_(std::move(callback)),
weak_owner_(weak_owner) {} weak_owner_(weak_owner) {}
...@@ -94,6 +95,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info, ...@@ -94,6 +95,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info,
web_app_info_->open_as_window = true; web_app_info_->open_as_window = true;
is_web_only_twa_ = web_app_info->is_web_only_twa; is_web_only_twa_ = web_app_info->is_web_only_twa;
sha256_fingerprint_ = web_app_info->certificate_sha256_fingerprint;
// Decode the image in a sandboxed process off the main thread. // Decode the image in a sandboxed process off the main thread.
// base::Unretained is safe because this object owns itself. // base::Unretained is safe because this object owns itself.
...@@ -107,7 +109,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info, ...@@ -107,7 +109,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info,
void ApkWebAppInstaller::CompleteInstallation(const web_app::AppId& id, void ApkWebAppInstaller::CompleteInstallation(const web_app::AppId& id,
web_app::InstallResultCode code) { web_app::InstallResultCode code) {
std::move(callback_).Run(id, is_web_only_twa_, code); std::move(callback_).Run(id, is_web_only_twa_, sha256_fingerprint_, code);
delete this; delete this;
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "chrome/browser/web_applications/components/web_app_id.h" #include "chrome/browser/web_applications/components/web_app_id.h"
#include "chrome/common/web_application_info.h" #include "chrome/common/web_application_info.h"
#include "components/arc/mojom/app.mojom.h" #include "components/arc/mojom/app.mojom.h"
...@@ -28,10 +29,11 @@ namespace chromeos { ...@@ -28,10 +29,11 @@ namespace chromeos {
// within it to install as a local web app. // within it to install as a local web app.
class ApkWebAppInstaller { class ApkWebAppInstaller {
public: public:
using InstallFinishCallback = using InstallFinishCallback = base::OnceCallback<void(
base::OnceCallback<void(const web_app::AppId&, const web_app::AppId&,
const bool is_web_only_twa, const bool is_web_only_twa,
web_app::InstallResultCode)>; const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode)>;
// Do nothing class purely for the purpose of allowing us to specify // Do nothing class purely for the purpose of allowing us to specify
// a WeakPtr<Owner> member as a proxy for a profile lifetime observer. // a WeakPtr<Owner> member as a proxy for a profile lifetime observer.
...@@ -83,6 +85,7 @@ class ApkWebAppInstaller { ...@@ -83,6 +85,7 @@ class ApkWebAppInstaller {
// shorter than that of |profile_|. // shorter than that of |profile_|.
Profile* profile_; Profile* profile_;
bool is_web_only_twa_; bool is_web_only_twa_;
base::Optional<std::string> sha256_fingerprint_;
InstallFinishCallback callback_; InstallFinishCallback callback_;
base::WeakPtr<Owner> weak_owner_; base::WeakPtr<Owner> weak_owner_;
......
...@@ -35,12 +35,14 @@ namespace { ...@@ -35,12 +35,14 @@ namespace {
// <web_app_id_1> : { // <web_app_id_1> : {
// "package_name" : <apk_package_name_1>, // "package_name" : <apk_package_name_1>,
// "should_remove": <bool>, // "should_remove": <bool>,
// "is_web_only_twa": <bool> // "is_web_only_twa": <bool>,
// "sha256_fingerprint": <certificate_sha256_fingerprint_2> (optional)
// }, // },
// <web_app_id_2> : { // <web_app_id_2> : {
// "package_name" : <apk_package_name_2>, // "package_name" : <apk_package_name_2>,
// "should_remove": <bool>, // "should_remove": <bool>,
// "is_web_only_twa": <bool> // "is_web_only_twa": <bool>,
// "sha256_fingerprint": <certificate_sha256_fingerprint_2> (optional)
// }, // },
// ... // ...
// }, // },
...@@ -50,6 +52,7 @@ const char kWebAppToApkDictPref[] = "web_app_apks"; ...@@ -50,6 +52,7 @@ const char kWebAppToApkDictPref[] = "web_app_apks";
const char kPackageNameKey[] = "package_name"; const char kPackageNameKey[] = "package_name";
const char kShouldRemoveKey[] = "should_remove"; const char kShouldRemoveKey[] = "should_remove";
const char kIsWebOnlyTwaKey[] = "is_web_only_twa"; const char kIsWebOnlyTwaKey[] = "is_web_only_twa";
const char kSha256FingerprintKey[] = "sha256_fingerprint";
constexpr char kLastAppId[] = "last_app_id"; constexpr char kLastAppId[] = "last_app_id";
constexpr char kPinIndex[] = "pin_index"; constexpr char kPinIndex[] = "pin_index";
...@@ -101,6 +104,25 @@ bool ApkWebAppService::IsWebOnlyTwa(const web_app::AppId& web_app_id) { ...@@ -101,6 +104,25 @@ bool ApkWebAppService::IsWebOnlyTwa(const web_app::AppId& web_app_id) {
return v && v->GetBool(); return v && v->GetBool();
} }
base::Optional<std::string> ApkWebAppService::GetCertificateSha256Fingerprint(
const web_app::AppId& web_app_id) {
if (!IsWebAppInstalledFromArc(web_app_id))
return base::nullopt;
DictionaryPrefUpdate web_apps_to_apks(profile_->GetPrefs(),
kWebAppToApkDictPref);
// Find the entry associated with the provided web app id.
const base::Value* v = web_apps_to_apks->FindPathOfType(
{web_app_id, kSha256FingerprintKey}, base::Value::Type::STRING);
if (!v) {
return base::nullopt;
}
return base::Optional<std::string>(v->GetString());
}
void ApkWebAppService::SetArcAppListPrefsForTesting(ArcAppListPrefs* prefs) { void ApkWebAppService::SetArcAppListPrefsForTesting(ArcAppListPrefs* prefs) {
DCHECK(prefs); DCHECK(prefs);
if (arc_app_list_prefs_) if (arc_app_list_prefs_)
...@@ -219,6 +241,7 @@ void ApkWebAppService::OnPackageInstalled( ...@@ -219,6 +241,7 @@ void ApkWebAppService::OnPackageInstalled(
} }
} }
// TODO(crbug.com/1082547): check if fingerprint or is_twa has chagned.
bool was_previously_web_app = !web_app_id.empty(); bool was_previously_web_app = !web_app_id.empty();
bool is_now_web_app = !package_info.web_app_info.is_null(); bool is_now_web_app = !package_info.web_app_info.is_null();
...@@ -390,10 +413,12 @@ void ApkWebAppService::OnDidGetWebAppIcon( ...@@ -390,10 +413,12 @@ void ApkWebAppService::OnDidGetWebAppIcon(
weak_ptr_factory_.GetWeakPtr()); weak_ptr_factory_.GetWeakPtr());
} }
void ApkWebAppService::OnDidFinishInstall(const std::string& package_name, void ApkWebAppService::OnDidFinishInstall(
const web_app::AppId& web_app_id, const std::string& package_name,
bool is_web_only_twa, const web_app::AppId& web_app_id,
web_app::InstallResultCode code) { bool is_web_only_twa,
const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode code) {
// Do nothing: any error cancels installation. // Do nothing: any error cancels installation.
if (code != web_app::InstallResultCode::kSuccessNewInstall) if (code != web_app::InstallResultCode::kSuccessNewInstall)
return; return;
...@@ -409,9 +434,17 @@ void ApkWebAppService::OnDidFinishInstall(const std::string& package_name, ...@@ -409,9 +434,17 @@ void ApkWebAppService::OnDidFinishInstall(const std::string& package_name,
// when the container starts up again. // when the container starts up again.
dict_update->SetPath({web_app_id, kShouldRemoveKey}, base::Value(false)); dict_update->SetPath({web_app_id, kShouldRemoveKey}, base::Value(false));
// Set a pref to indicate if the |web_app_id| is a web-only TWA.
dict_update->SetPath({web_app_id, kIsWebOnlyTwaKey}, dict_update->SetPath({web_app_id, kIsWebOnlyTwaKey},
base::Value(is_web_only_twa)); base::Value(is_web_only_twa));
if (sha256_fingerprint.has_value()) {
// Set a pref to hold the APK's certificate SHA256 fingerprint to use for
// digital asset link verification.
dict_update->SetPath({web_app_id, kSha256FingerprintKey},
base::Value(sha256_fingerprint.value()));
}
// For testing. // For testing.
if (web_app_installed_callback_) if (web_app_installed_callback_)
std::move(web_app_installed_callback_).Run(package_name, web_app_id); std::move(web_app_installed_callback_).Run(package_name, web_app_id);
......
...@@ -49,6 +49,9 @@ class ApkWebAppService : public KeyedService, ...@@ -49,6 +49,9 @@ class ApkWebAppService : public KeyedService,
bool IsWebOnlyTwa(const web_app::AppId& web_app_id); bool IsWebOnlyTwa(const web_app::AppId& web_app_id);
base::Optional<std::string> GetCertificateSha256Fingerprint(
const web_app::AppId& web_app_id);
using WebAppCallbackForTesting = using WebAppCallbackForTesting =
base::OnceCallback<void(const std::string& package_name, base::OnceCallback<void(const std::string& package_name,
const web_app::AppId& web_app_id)>; const web_app::AppId& web_app_id)>;
...@@ -89,6 +92,7 @@ class ApkWebAppService : public KeyedService, ...@@ -89,6 +92,7 @@ class ApkWebAppService : public KeyedService,
void OnDidFinishInstall(const std::string& package_name, void OnDidFinishInstall(const std::string& package_name,
const web_app::AppId& web_app_id, const web_app::AppId& web_app_id,
bool is_web_only_twa, bool is_web_only_twa,
const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode code); web_app::InstallResultCode code);
bool IsWebAppInstalledFromArc(const web_app::AppId& web_app_id); bool IsWebAppInstalledFromArc(const web_app::AppId& web_app_id);
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// //
// Next MinVersion: 45 // Next MinVersion: 46
module arc.mojom; module arc.mojom;
...@@ -43,6 +43,9 @@ struct WebAppInfo { ...@@ -43,6 +43,9 @@ struct WebAppInfo {
// If the web app is tied to a web-only TWA. // If the web app is tied to a web-only TWA.
[MinVersion=44] bool is_web_only_twa; [MinVersion=44] bool is_web_only_twa;
// SHA256 fingerprint of the APK the web app belongs to.
[MinVersion=45] string? certificate_sha256_fingerprint;
}; };
// Describes ARC package. // Describes ARC package.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment