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,
base::WeakPtr<Owner> weak_owner)
: profile_(profile),
is_web_only_twa_(false),
sha256_fingerprint_(base::nullopt),
callback_(std::move(callback)),
weak_owner_(weak_owner) {}
......@@ -94,6 +95,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info,
web_app_info_->open_as_window = true;
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.
// base::Unretained is safe because this object owns itself.
......@@ -107,7 +109,7 @@ void ApkWebAppInstaller::Start(arc::mojom::WebAppInfoPtr web_app_info,
void ApkWebAppInstaller::CompleteInstallation(const web_app::AppId& id,
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;
}
......
......@@ -11,6 +11,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "chrome/browser/web_applications/components/web_app_id.h"
#include "chrome/common/web_application_info.h"
#include "components/arc/mojom/app.mojom.h"
......@@ -28,9 +29,10 @@ namespace chromeos {
// within it to install as a local web app.
class ApkWebAppInstaller {
public:
using InstallFinishCallback =
base::OnceCallback<void(const web_app::AppId&,
using InstallFinishCallback = base::OnceCallback<void(
const web_app::AppId&,
const bool is_web_only_twa,
const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode)>;
// Do nothing class purely for the purpose of allowing us to specify
......@@ -83,6 +85,7 @@ class ApkWebAppInstaller {
// shorter than that of |profile_|.
Profile* profile_;
bool is_web_only_twa_;
base::Optional<std::string> sha256_fingerprint_;
InstallFinishCallback callback_;
base::WeakPtr<Owner> weak_owner_;
......
......@@ -35,12 +35,14 @@ namespace {
// <web_app_id_1> : {
// "package_name" : <apk_package_name_1>,
// "should_remove": <bool>,
// "is_web_only_twa": <bool>
// "is_web_only_twa": <bool>,
// "sha256_fingerprint": <certificate_sha256_fingerprint_2> (optional)
// },
// <web_app_id_2> : {
// "package_name" : <apk_package_name_2>,
// "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";
const char kPackageNameKey[] = "package_name";
const char kShouldRemoveKey[] = "should_remove";
const char kIsWebOnlyTwaKey[] = "is_web_only_twa";
const char kSha256FingerprintKey[] = "sha256_fingerprint";
constexpr char kLastAppId[] = "last_app_id";
constexpr char kPinIndex[] = "pin_index";
......@@ -101,6 +104,25 @@ bool ApkWebAppService::IsWebOnlyTwa(const web_app::AppId& web_app_id) {
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) {
DCHECK(prefs);
if (arc_app_list_prefs_)
......@@ -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 is_now_web_app = !package_info.web_app_info.is_null();
......@@ -390,9 +413,11 @@ void ApkWebAppService::OnDidGetWebAppIcon(
weak_ptr_factory_.GetWeakPtr());
}
void ApkWebAppService::OnDidFinishInstall(const std::string& package_name,
void ApkWebAppService::OnDidFinishInstall(
const std::string& package_name,
const web_app::AppId& web_app_id,
bool is_web_only_twa,
const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode code) {
// Do nothing: any error cancels installation.
if (code != web_app::InstallResultCode::kSuccessNewInstall)
......@@ -409,9 +434,17 @@ void ApkWebAppService::OnDidFinishInstall(const std::string& package_name,
// when the container starts up again.
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},
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.
if (web_app_installed_callback_)
std::move(web_app_installed_callback_).Run(package_name, web_app_id);
......
......@@ -49,6 +49,9 @@ class ApkWebAppService : public KeyedService,
bool IsWebOnlyTwa(const web_app::AppId& web_app_id);
base::Optional<std::string> GetCertificateSha256Fingerprint(
const web_app::AppId& web_app_id);
using WebAppCallbackForTesting =
base::OnceCallback<void(const std::string& package_name,
const web_app::AppId& web_app_id)>;
......@@ -89,6 +92,7 @@ class ApkWebAppService : public KeyedService,
void OnDidFinishInstall(const std::string& package_name,
const web_app::AppId& web_app_id,
bool is_web_only_twa,
const base::Optional<std::string> sha256_fingerprint,
web_app::InstallResultCode code);
bool IsWebAppInstalledFromArc(const web_app::AppId& web_app_id);
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Next MinVersion: 45
// Next MinVersion: 46
module arc.mojom;
......@@ -43,6 +43,9 @@ struct WebAppInfo {
// If the web app is tied to a 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.
......
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