Bug 1539541 - Enable FIDO U2F API, and permit registrations for Google Accounts r=keeler,qdot
authorJ.C. Jones <jjones@mozilla.com>
Fri, 29 Mar 2019 17:16:13 +0000
changeset 466797 e27fc0c01a979c6b8a423846e0461bdebe70eef4
parent 466796 67251e93f756baf940c1ddc9a382b35b76dd4f75
child 466798 78a419376c0c38cd462c096f05d2e0fcd5924e16
push id35780
push useropoprus@mozilla.com
push dateFri, 29 Mar 2019 21:53:01 +0000
treeherdermozilla-central@414f37afbe07 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, qdot
bugs1539541
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1539541 - Enable FIDO U2F API, and permit registrations for Google Accounts r=keeler,qdot Per the thread "Intent-to-Ship: Backward-Compatibility FIDO U2F support for Google Accounts" on dev-platform [0], this bug is to: 1. Enable the security.webauth.u2f by default, to ride the trains 2. Remove the aOp == U2FOperation::Sign check from EvaluateAppID in WebAuthnUtil.cpp, permitting the Google override to work for Register as well as Sign. This would enable Firefox users to use FIDO U2F API on most all sites, subject to the algorithm limitations discussed in the section "Thorny issues in enabling our FIDO U2F API implementation" of that post. [0] https://groups.google.com/d/msg/mozilla.dev.platform/q5cj38hGTEA/lC834665BQAJ Differential Revision: https://phabricator.services.mozilla.com/D25241
dom/tests/mochitest/general/test_interfaces.js
dom/u2f/U2F.cpp
dom/webauthn/WebAuthnManager.cpp
dom/webauthn/WebAuthnUtil.cpp
dom/webauthn/WebAuthnUtil.h
security/manager/ssl/security-prefs.js
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -1143,17 +1143,17 @@ var interfaceNamesInGlobalScope =
     {name: "TouchList", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TrackEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TransitionEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "TreeWalker", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
-    {name: "U2F", insecureContext: true, disabled: true},
+    {name: "U2F", insecureContext: false},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "UIEvent", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "URL", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "URLSearchParams", insecureContext: true},
 // IMPORTANT: Do not change this list without review from a DOM peer!
     {name: "UserProximityEvent", insecureContext: true, disabled: true},
--- a/dom/u2f/U2F.cpp
+++ b/dom/u2f/U2F.cpp
@@ -202,17 +202,17 @@ void U2F::Register(const nsAString& aApp
 
   // Ensure we have a callback.
   if (NS_WARN_IF(!callback)) {
     return;
   }
 
   // Evaluate the AppID
   nsString adjustedAppId(aAppId);
-  if (!EvaluateAppID(mParent, mOrigin, U2FOperation::Register, adjustedAppId)) {
+  if (!EvaluateAppID(mParent, mOrigin, adjustedAppId)) {
     RegisterResponse response;
     response.mErrorCode.Construct(
         static_cast<uint32_t>(ErrorCode::BAD_REQUEST));
     ExecuteCallback(response, callback);
     return;
   }
 
   nsAutoString clientDataJSON;
@@ -352,17 +352,17 @@ void U2F::Sign(const nsAString& aAppId, 
 
   // Ensure we have a callback.
   if (NS_WARN_IF(!callback)) {
     return;
   }
 
   // Evaluate the AppID
   nsString adjustedAppId(aAppId);
-  if (!EvaluateAppID(mParent, mOrigin, U2FOperation::Sign, adjustedAppId)) {
+  if (!EvaluateAppID(mParent, mOrigin, adjustedAppId)) {
     SignResponse response;
     response.mErrorCode.Construct(
         static_cast<uint32_t>(ErrorCode::BAD_REQUEST));
     ExecuteCallback(response, callback);
     return;
   }
 
   // Produce the AppParam from the current AppID
--- a/dom/webauthn/WebAuthnManager.cpp
+++ b/dom/webauthn/WebAuthnManager.cpp
@@ -521,17 +521,17 @@ already_AddRefed<Promise> WebAuthnManage
   // result of this processing clientExtensions.
   nsTArray<WebAuthnExtension> extensions;
 
   // <https://w3c.github.io/webauthn/#sctn-appid-extension>
   if (aOptions.mExtensions.mAppid.WasPassed()) {
     nsString appId(aOptions.mExtensions.mAppid.Value());
 
     // Check that the appId value is allowed.
-    if (!EvaluateAppID(mParent, origin, U2FOperation::Sign, appId)) {
+    if (!EvaluateAppID(mParent, origin, appId)) {
       promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
       return promise.forget();
     }
 
     CryptoBuffer appIdHash;
     if (!appIdHash.SetLength(SHA256_LENGTH, fallible)) {
       promise->MaybeReject(NS_ERROR_OUT_OF_MEMORY);
       return promise.forget();
--- a/dom/webauthn/WebAuthnUtil.cpp
+++ b/dom/webauthn/WebAuthnUtil.cpp
@@ -18,17 +18,17 @@ NS_NAMED_LITERAL_STRING(kGoogleAccountsA
 NS_NAMED_LITERAL_STRING(
     kGoogleAccountsAppId2,
     "https://www.gstatic.com/securitykey/a/google.com/origins.json");
 
 const uint8_t FLAG_TUP = 0x01;  // Test of User Presence required
 const uint8_t FLAG_AT = 0x40;   // Authenticator Data is provided
 
 bool EvaluateAppID(nsPIDOMWindowInner* aParent, const nsString& aOrigin,
-                   const U2FOperation& aOp, /* in/out */ nsString& aAppId) {
+                   /* in/out */ nsString& aAppId) {
   // Facet is the specification's way of referring to the web origin.
   nsAutoCString facetString = NS_ConvertUTF16toUTF8(aOrigin);
   nsCOMPtr<nsIURI> facetUri;
   if (NS_FAILED(NS_NewURI(getter_AddRefs(facetUri), facetString))) {
     return false;
   }
 
   // If the facetId (origin) is not HTTPS, reject
@@ -96,18 +96,17 @@ bool EvaluateAppID(nsPIDOMWindowInner* a
   }
 
   if (html->IsRegistrableDomainSuffixOfOrEqualTo(
           NS_ConvertUTF8toUTF16(lowestFacetHost), appIdHost)) {
     return true;
   }
 
   // Bug #1436078 - Permit Google Accounts. Remove in Bug #1436085 in Jan 2023.
-  if (aOp == U2FOperation::Sign &&
-      lowestFacetHost.EqualsLiteral("google.com") &&
+  if (lowestFacetHost.EqualsLiteral("google.com") &&
       (aAppId.Equals(kGoogleAccountsAppId1) ||
        aAppId.Equals(kGoogleAccountsAppId2))) {
     return true;
   }
 
   return false;
 }
 
--- a/dom/webauthn/WebAuthnUtil.h
+++ b/dom/webauthn/WebAuthnUtil.h
@@ -15,17 +15,17 @@
 #include "mozilla/dom/WebAuthenticationBinding.h"
 
 namespace mozilla {
 namespace dom {
 
 enum class U2FOperation { Register, Sign };
 
 bool EvaluateAppID(nsPIDOMWindowInner* aParent, const nsString& aOrigin,
-                   const U2FOperation& aOp, /* in/out */ nsString& aAppId);
+                   /* in/out */ nsString& aAppId);
 
 nsresult AssembleAuthenticatorData(const CryptoBuffer& rpIdHashBuf,
                                    const uint8_t flags,
                                    const CryptoBuffer& counterBuf,
                                    const CryptoBuffer& attestationDataBuf,
                                    /* out */ CryptoBuffer& authDataBuf);
 
 nsresult AssembleAttestationObject(const CryptoBuffer& aRpIdHash,
--- a/security/manager/ssl/security-prefs.js
+++ b/security/manager/ssl/security-prefs.js
@@ -110,17 +110,17 @@ pref("security.pki.netscape_step_up_poli
 #endif
 
 // Configures Certificate Transparency support mode:
 // 0: Fully disabled.
 // 1: Only collect telemetry. CT qualification checks are not performed.
 pref("security.pki.certificate_transparency.mode", 0);
 
 // Hardware Origin-bound Second Factor Support
-pref("security.webauth.u2f", false);
+pref("security.webauth.u2f", true);
 pref("security.webauth.webauthn", true);
 // Only one of "enable_softtoken" and "enable_usbtoken" can be true
 // at a time.
 pref("security.webauth.webauthn_enable_softtoken", false);
 pref("security.webauth.webauthn_enable_usbtoken", true);
 
 pref("security.ssl.errorReporting.enabled", true);
 pref("security.ssl.errorReporting.url", "https://incoming.telemetry.mozilla.org/submit/sslreports/");