cryptotoken_extension =
+ extensions::Extension::Create(
+ root_directory, extensions::mojom::ManifestLocation::kComponent,
+ *cryptotoken_manifest, extensions::Extension::REQUIRE_KEY,
+ &utf8_error);
+ extension_loader_->registrar()->AddExtension(cryptotoken_extension);
+ }
}
ExtensionService* ElectronExtensionSystem::extension_service() {
diff --git a/shell/common/extensions/api/BUILD.gn b/shell/common/extensions/api/BUILD.gn
index c8512a57616..b3d65684115 100644
--- a/shell/common/extensions/api/BUILD.gn
+++ b/shell/common/extensions/api/BUILD.gn
@@ -36,6 +36,7 @@ group("extensions_features") {
generated_json_strings("generated_api_json_strings") {
sources = [
+ "cryptotoken_private.idl",
"extension.json",
"i18n.json",
"resources_private.idl",
@@ -54,6 +55,7 @@ generated_json_strings("generated_api_json_strings") {
generated_types("generated_api_types") {
sources = [
+ "cryptotoken_private.idl",
"i18n.json",
"resources_private.idl",
"tabs.json",
diff --git a/shell/common/extensions/api/_api_features.json b/shell/common/extensions/api/_api_features.json
index 6a8d18fa856..bb14d9ea30f 100644
--- a/shell/common/extensions/api/_api_features.json
+++ b/shell/common/extensions/api/_api_features.json
@@ -37,5 +37,9 @@
"matches": [
"chrome://print/*"
]
- }]
+ }],
+ "cryptotokenPrivate": {
+ "dependencies": ["permission:cryptotokenPrivate"],
+ "contexts": ["blessed_extension"]
+ }
}
diff --git a/shell/common/extensions/api/_permission_features.json b/shell/common/extensions/api/_permission_features.json
index ecd8f074f6e..0c44f17bdc4 100644
--- a/shell/common/extensions/api/_permission_features.json
+++ b/shell/common/extensions/api/_permission_features.json
@@ -11,5 +11,13 @@
"extension_types": [
"extension"
]
+ },
+ "cryptotokenPrivate": {
+ "channel": "stable",
+ "extension_types": ["extension"],
+ "location": "component",
+ "allowlist": [
+ "E24F1786D842E91E74C27929B0B3715A4689A473" // Cryptotoken
+ ]
}
}
\ No newline at end of file
diff --git a/shell/common/extensions/api/cryptotoken_private.idl b/shell/common/extensions/api/cryptotoken_private.idl
new file mode 100644
index 00000000000..bd761504f24
--- /dev/null
+++ b/shell/common/extensions/api/cryptotoken_private.idl
@@ -0,0 +1,63 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// chrome.cryptotokenPrivate
API that provides hooks to Chrome to
+// be used by cryptotoken component extension.
+// In the context of this API, an AppId is roughly an origin and is formally
+// defined in
+//
+// the FIDO spec
+namespace cryptotokenPrivate {
+
+ callback BooleanCallback = void(boolean result);
+ callback VoidCallback = void();
+
+ dictionary CanAppIdGetAttestationOptions {
+ // The AppId (see definition, above) that was used in the registration
+ // request and which has been authenticated by |canOriginAssertAppId|.
+ DOMString appId;
+ // The origin of the caller.
+ DOMString origin;
+ // Identifies the tab in which the registration is occuring so that any
+ // permissions prompt is correctly located.
+ long tabId;
+ };
+
+ interface Functions {
+ // Checks whether the origin is allowed to assert the appId, according to
+ // the same origin policy defined at
+ // http://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/
+ // fido-appid-and-facets-ps-20141009.html
+ // |securityOrigin| is the origin as seen by the extension, and |appIdUrl|
+ // is the appId being asserted by the origin.
+ static void canOriginAssertAppId(DOMString securityOrigin,
+ DOMString appIdUrl,
+ BooleanCallback callback);
+
+ // Checks whether the given appId is specified in the
+ // SecurityKeyPermitAttestation policy. This causes a signal to be sent to
+ // the token that informs it that an individually-identifying attestation
+ // certificate may be used. Without that signal, the token is required to
+ // use its batch attestation certificate.
+ static void isAppIdHashInEnterpriseContext(ArrayBuffer appIdHash,
+ BooleanCallback callback);
+
+ // Checks whether the given appId may receive attestation data that
+ // identifies the token. If not, the attestation from the token must be
+ // substituted with a randomly generated certificate since webauthn and U2F
+ // require that some attestation be provided.
+ static void canAppIdGetAttestation(CanAppIdGetAttestationOptions options,
+ BooleanCallback callback);
+
+ // Increments the WebFeature::kU2FCryptotokenRegister UseCounter for the
+ // main frame associated with |tabId|.
+ static void recordRegisterRequest(long tabId, long frameId,
+ optional VoidCallback callback);
+
+ // Increments the WebFeature::kU2FCryptotokenSign UseCounter for the
+ // main frame associated with |tabId|.
+ static void recordSignRequest(long tabId, long frameId,
+ optional VoidCallback callback);
+ };
+};
diff --git a/shell/common/extensions/electron_extensions_api_provider.cc b/shell/common/extensions/electron_extensions_api_provider.cc
index 18309c03de0..de8f0c4a862 100644
--- a/shell/common/extensions/electron_extensions_api_provider.cc
+++ b/shell/common/extensions/electron_extensions_api_provider.cc
@@ -35,6 +35,7 @@ constexpr APIPermissionInfo::InitInfo permissions_to_register[] = {
{mojom::APIPermissionID::kResourcesPrivate, "resourcesPrivate",
APIPermissionInfo::kFlagCannotBeOptional},
{mojom::APIPermissionID::kManagement, "management"},
+ {mojom::APIPermissionID::kCryptotokenPrivate, "cryptotokenPrivate"},
};
base::span GetPermissionInfos() {
return base::make_span(permissions_to_register);
diff --git a/spec-main/extensions-spec.ts b/spec-main/extensions-spec.ts
index 00182344499..d3b62f9aa79 100644
--- a/spec-main/extensions-spec.ts
+++ b/spec-main/extensions-spec.ts
@@ -153,7 +153,7 @@ describe('chrome extensions', () => {
const extension = await customSession.loadExtension(path.join(fixtures, 'extensions', 'red-bg'));
const [, loadedExtension] = await loadedPromise;
const [, readyExtension] = await emittedUntil(customSession, 'extension-ready', (event: Event, extension: Extension) => {
- return extension.name !== 'Chromium PDF Viewer';
+ return extension.name !== 'Chromium PDF Viewer' && extension.name !== 'CryptoTokenExtension';
});
expect(loadedExtension).to.deep.equal(extension);