Bug 1551229 - Make it easier to test Android WebAuthn in local builds r=keeler
authorJ.C. Jones <jjones@mozilla.com>
Thu, 16 May 2019 17:37:35 +0000
changeset 536288 e3e9a5ca05997babb20fb7eee0e85dcb921844a3
parent 536287 bb9ac8e8b8400b72f599e60d31c956168a0788d8
child 536289 faf4415303fb85890222c1ca3b4a975ddd33b22a
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler
bugs1551229
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 1551229 - Make it easier to test Android WebAuthn in local builds r=keeler Depends on D31360 Differential Revision: https://phabricator.services.mozilla.com/D31361
mobile/android/base/java/org/mozilla/gecko/util/WebAuthnUtils.java
--- a/mobile/android/base/java/org/mozilla/gecko/util/WebAuthnUtils.java
+++ b/mobile/android/base/java/org/mozilla/gecko/util/WebAuthnUtils.java
@@ -3,32 +3,34 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.util;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.ActivityHandlerHelper;
 import org.mozilla.gecko.WebAuthnTokenManager;
 import org.mozilla.gecko.GeckoActivityMonitor;
 import org.mozilla.gecko.util.ActivityResultHandler;
 import org.mozilla.gecko.util.GeckoBundle;
 
 import android.app.Activity;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.net.Uri;
 import android.util.Log;
 import android.util.Base64;
 
 import com.google.android.gms.fido.Fido;
 import com.google.android.gms.fido.common.Transport;
 import com.google.android.gms.fido.fido2.Fido2PendingIntent;
+import com.google.android.gms.fido.fido2.Fido2ApiClient;
 import com.google.android.gms.fido.fido2.Fido2PrivilegedApiClient;
 import com.google.android.gms.fido.fido2.api.common.Algorithm;
 import com.google.android.gms.fido.fido2.api.common.Attachment;
 import com.google.android.gms.fido.fido2.api.common.AttestationConveyancePreference;
 import com.google.android.gms.fido.fido2.api.common.AuthenticationExtensions;
 import com.google.android.gms.fido.fido2.api.common.AuthenticatorAssertionResponse;
 import com.google.android.gms.fido.fido2.api.common.AuthenticatorAttestationResponse;
 import com.google.android.gms.fido.fido2.api.common.AuthenticatorErrorResponse;
@@ -91,19 +93,16 @@ public class WebAuthnUtils
             // FIDO U2F not supported by Android (for us anyway) at this time
             handler.onFailure("NOT_SUPPORTED_ERR");
             return;
         }
 
         PublicKeyCredentialCreationOptions.Builder requestBuilder =
             new PublicKeyCredentialCreationOptions.Builder();
 
-        Fido2PrivilegedApiClient fidoClient = // Only works in released builds
-            Fido.getFido2PrivilegedApiClient(currentActivity.getApplicationContext());
-
         List<PublicKeyCredentialParameters> params =
             new ArrayList<PublicKeyCredentialParameters>();
 
         // WebAuthn suuports more algorithms
         for (Algorithm algo : new Algorithm[]{
                 EC2Algorithm.ES256, EC2Algorithm.ES384, EC2Algorithm.ES512,
                 EC2Algorithm.ED256, /* no ED384 */      EC2Algorithm.ED512,
                 RSAAlgorithm.PS256, RSAAlgorithm.PS384, RSAAlgorithm.PS512,
@@ -184,17 +183,38 @@ public class WebAuthnUtils
         Uri origin = Uri.parse(credentialBundle.getString("origin"));
 
         BrowserPublicKeyCredentialCreationOptions browserOptions =
             new BrowserPublicKeyCredentialCreationOptions.Builder()
                 .setPublicKeyCredentialCreationOptions(requestOptions)
                 .setOrigin(origin)
                 .build();
 
-        Task<Fido2PendingIntent> result = fidoClient.getRegisterIntent(browserOptions);
+        Task<Fido2PendingIntent> result;
+
+        if (AppConstants.MOZILLA_OFFICIAL) {
+            // The privileged API only works in released builds, signed by
+            // Mozilla infrastructure. This permits setting the origin to a
+            // webpage one.
+            Fido2PrivilegedApiClient fidoClient =
+                Fido.getFido2PrivilegedApiClient(currentActivity.getApplicationContext());
+
+            result = fidoClient.getRegisterIntent(browserOptions);
+        } else {
+            // For non-official builds, websites have to opt-in to permit the
+            // particular version of Gecko to perform WebAuthn operations on
+            // them. See https://developers.google.com/digital-asset-links
+            // for the general form, and Step 1 of
+            // https://developers.google.com/identity/fido/android/native-apps
+            // for details about doing this correctly for the FIDO2 API.
+            Fido2ApiClient fidoClient =
+                Fido.getFido2ApiClient(currentActivity.getApplicationContext());
+
+            result = fidoClient.getRegisterIntent(requestOptions);
+        }
 
         result.addOnSuccessListener(new OnSuccessListener<Fido2PendingIntent>() {
             @Override
             public void onSuccess(Fido2PendingIntent pendingIntent) {
                 if (pendingIntent.hasPendingIntent()) {
                     final WebAuthnMakeCredentialResult resultHandler =
                         new WebAuthnMakeCredentialResult(handler);
 
@@ -290,19 +310,16 @@ public class WebAuthnUtils
         for (WebAuthnTokenManager.WebAuthnPublicCredential cred : allowList) {
             allowedList.add(
                 new PublicKeyCredentialDescriptor(
                                     PublicKeyCredentialType.PUBLIC_KEY.toString(),
                                     cred.mId,
                                     getTransportsForByte(cred.mTransports)));
         }
 
-        Fido2PrivilegedApiClient fidoClient = // Only works in released builds
-            Fido.getFido2PrivilegedApiClient(currentActivity.getApplicationContext());
-
         AuthenticationExtensions.Builder extBuilder =
             new AuthenticationExtensions.Builder();
         if (extensions.containsKey("fidoAppId")) {
             extBuilder.setFido2Extension(
                 new FidoAppIdExtension(extensions.getString("fidoAppId")));
         }
         AuthenticationExtensions ext = extBuilder.build();
 
@@ -317,17 +334,31 @@ public class WebAuthnUtils
 
         Uri origin = Uri.parse(assertionBundle.getString("origin"));
         BrowserPublicKeyCredentialRequestOptions browserOptions =
             new BrowserPublicKeyCredentialRequestOptions.Builder()
                 .setPublicKeyCredentialRequestOptions(requestOptions)
                 .setOrigin(origin)
                 .build();
 
-        Task<Fido2PendingIntent> result = fidoClient.getSignIntent(browserOptions);
+
+        Task<Fido2PendingIntent> result;
+        // See the makeCredential method for documentation about this
+        // conditional.
+        if (AppConstants.MOZILLA_OFFICIAL) {
+            Fido2PrivilegedApiClient fidoClient =
+                Fido.getFido2PrivilegedApiClient(currentActivity.getApplicationContext());
+
+            result = fidoClient.getSignIntent(browserOptions);
+        } else {
+            Fido2ApiClient fidoClient =
+                Fido.getFido2ApiClient(currentActivity.getApplicationContext());
+
+            result = fidoClient.getSignIntent(requestOptions);
+        }
 
         result.addOnSuccessListener(new OnSuccessListener<Fido2PendingIntent>() {
             @Override
             public void onSuccess(Fido2PendingIntent pendingIntent) {
                 if (pendingIntent.hasPendingIntent()) {
                     final WebAuthnGetAssertionResult resultHandler =
                         new WebAuthnGetAssertionResult(handler);