Bug 1539541 - Enable FIDO U2F API, and permit registrations for Google Accounts r=keeler,qdot a=pascalc
authorJ.C. Jones <jjones@mozilla.com>
Fri, 29 Mar 2019 17:16:13 +0000
changeset 525962 21acdae6bafe5ad41736fec5e14bb787622acb5d
parent 525961 985158cfb6950e416e0d4664e1aa9aad83c923ab
child 525963 233aa5cf03be6c45ed388f2a7b3b73563de06e2c
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, qdot, pascalc
bugs1539541
milestone67.0
Bug 1539541 - Enable FIDO U2F API, and permit registrations for Google Accounts r=keeler,qdot a=pascalc 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
@@ -1142,17 +1142,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
@@ -535,17 +535,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
@@ -14,17 +14,17 @@
 #include "mozilla/dom/CryptoBuffer.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/");