Bug 1862132 - Part 1. Move data class to WebAuthnUtils. r=jschanck,geckoview-reviewers,owlish

I would like to move data class from WebAuthnTokenManager to new class
since WebAuthnTokenManager may becomes complex when we add Credential
Manager support.

Differential Revision: https://phabricator.services.mozilla.com/D207500
This commit is contained in:
Makoto Kato 2024-05-16 04:14:55 +00:00
parent afaf41dcef
commit e067299302
5 changed files with 314 additions and 209 deletions

View File

@ -14,9 +14,8 @@ namespace mozilla::jni {
template <>
RefPtr<dom::WebAuthnRegisterResult> Java2Native(
mozilla::jni::Object::Param aData, JNIEnv* aEnv) {
MOZ_ASSERT(
aData.IsInstanceOf<java::WebAuthnTokenManager::MakeCredentialResponse>());
java::WebAuthnTokenManager::MakeCredentialResponse::LocalRef response(aData);
MOZ_ASSERT(aData.IsInstanceOf<java::WebAuthnUtils::MakeCredentialResponse>());
java::WebAuthnUtils::MakeCredentialResponse::LocalRef response(aData);
RefPtr<dom::WebAuthnRegisterResult> result =
new dom::WebAuthnRegisterResult(response);
return result;
@ -25,9 +24,8 @@ RefPtr<dom::WebAuthnRegisterResult> Java2Native(
template <>
RefPtr<dom::WebAuthnSignResult> Java2Native(mozilla::jni::Object::Param aData,
JNIEnv* aEnv) {
MOZ_ASSERT(
aData.IsInstanceOf<java::WebAuthnTokenManager::GetAssertionResponse>());
java::WebAuthnTokenManager::GetAssertionResponse::LocalRef response(aData);
MOZ_ASSERT(aData.IsInstanceOf<java::WebAuthnUtils::GetAssertionResponse>());
java::WebAuthnUtils::GetAssertionResponse::LocalRef response(aData);
RefPtr<dom::WebAuthnSignResult> result =
new dom::WebAuthnSignResult(response);
return result;

View File

@ -13,7 +13,7 @@
#include "nsString.h"
#ifdef MOZ_WIDGET_ANDROID
# include "mozilla/java/WebAuthnTokenManagerNatives.h"
# include "mozilla/java/WebAuthnUtilsNatives.h"
#endif
#ifdef XP_WIN
@ -44,8 +44,7 @@ class WebAuthnRegisterResult final : public nsIWebAuthnRegisterResult {
#ifdef MOZ_WIDGET_ANDROID
explicit WebAuthnRegisterResult(
const java::WebAuthnTokenManager::MakeCredentialResponse::LocalRef&
aResponse) {
const java::WebAuthnUtils::MakeCredentialResponse::LocalRef& aResponse) {
mAttestationObject.AppendElements(
reinterpret_cast<uint8_t*>(
aResponse->AttestationObject()->GetElements().Elements()),
@ -167,8 +166,7 @@ class WebAuthnSignResult final : public nsIWebAuthnSignResult {
#ifdef MOZ_WIDGET_ANDROID
explicit WebAuthnSignResult(
const java::WebAuthnTokenManager::GetAssertionResponse::LocalRef&
aResponse) {
const java::WebAuthnUtils::GetAssertionResponse::LocalRef& aResponse) {
mAuthenticatorData.AppendElements(
reinterpret_cast<uint8_t*>(
aResponse->AuthData()->GetElements().Elements()),

View File

@ -0,0 +1,263 @@
/* -*- Mode: Java; c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil; -*- */
/* vim: set ts=2 et sw=2 tw=100: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 android.util.Base64;
import com.google.android.gms.fido.common.Transport;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.mozilla.gecko.annotation.WrapForJNI;
public class WebAuthnUtils {
private static final String LOGTAG = "WebAuthnUtils";
private static final boolean DEBUG = false;
// from dom/webauthn/WebAuthnTransportIdentifiers.h
private static final byte AUTHENTICATOR_TRANSPORT_USB = 1;
private static final byte AUTHENTICATOR_TRANSPORT_NFC = 2;
private static final byte AUTHENTICATOR_TRANSPORT_BLE = 4;
private static final byte AUTHENTICATOR_TRANSPORT_INTERNAL = 8;
// From WebAuthentication.webidl
public enum AttestationPreference {
NONE,
INDIRECT,
DIRECT,
}
public static List<Transport> getTransportsForByte(final byte transports) {
final ArrayList<Transport> result = new ArrayList<Transport>();
if ((transports & AUTHENTICATOR_TRANSPORT_USB) == AUTHENTICATOR_TRANSPORT_USB) {
result.add(Transport.USB);
}
if ((transports & AUTHENTICATOR_TRANSPORT_NFC) == AUTHENTICATOR_TRANSPORT_NFC) {
result.add(Transport.NFC);
}
if ((transports & AUTHENTICATOR_TRANSPORT_BLE) == AUTHENTICATOR_TRANSPORT_BLE) {
result.add(Transport.BLUETOOTH_LOW_ENERGY);
}
if ((transports & AUTHENTICATOR_TRANSPORT_INTERNAL) == AUTHENTICATOR_TRANSPORT_INTERNAL) {
result.add(Transport.INTERNAL);
}
return result;
}
public static class WebAuthnPublicCredential {
public final byte[] id;
public final byte transports;
public WebAuthnPublicCredential(final byte[] aId, final byte aTransports) {
this.id = aId;
this.transports = aTransports;
}
public static ArrayList<WebAuthnPublicCredential> CombineBuffers(
final Object[] idObjectList, final ByteBuffer transportList) {
if (idObjectList.length != transportList.remaining()) {
throw new RuntimeException("Couldn't extract allowed list!");
}
final ArrayList<WebAuthnPublicCredential> credList =
new ArrayList<WebAuthnPublicCredential>();
final byte[] transportBytes = new byte[transportList.remaining()];
transportList.get(transportBytes);
for (int i = 0; i < idObjectList.length; i++) {
final ByteBuffer id = (ByteBuffer) idObjectList[i];
final byte[] idBytes = new byte[id.remaining()];
id.get(idBytes);
credList.add(new WebAuthnPublicCredential(idBytes, transportBytes[i]));
}
return credList;
}
}
@WrapForJNI
public static class MakeCredentialResponse {
public final byte[] clientDataJson;
public final byte[] keyHandle;
public final byte[] attestationObject;
public final String[] transports;
public final String authenticatorAttachment;
public static final class Builder {
private byte[] mClientDataJson;
private byte[] mKeyHandle;
private byte[] mAttestationObject;
private String[] mTransports;
private String mAuthenticatorAttachment;
public Builder() {}
public Builder setClientDataJson(final byte[] clientDataJson) {
this.mClientDataJson = clientDataJson;
return this;
}
public Builder setKeyHandle(final byte[] keyHandle) {
this.mKeyHandle = keyHandle;
return this;
}
public Builder setAttestationObject(final byte[] attestationObject) {
this.mAttestationObject = attestationObject;
return this;
}
public Builder setTransports(final String[] transports) {
this.mTransports = transports;
return this;
}
public Builder setAuthenticatorAttachment(final String authenticatorAttachment) {
this.mAuthenticatorAttachment = authenticatorAttachment;
return this;
}
public MakeCredentialResponse build() {
return new MakeCredentialResponse(this);
}
}
@WrapForJNI(skip = true)
protected MakeCredentialResponse(final Builder builder) {
this.clientDataJson = builder.mClientDataJson;
this.keyHandle = builder.mKeyHandle;
this.attestationObject = builder.mAttestationObject;
this.transports = builder.mTransports;
this.authenticatorAttachment = builder.mAuthenticatorAttachment;
}
@WrapForJNI(skip = true)
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("clientDataJson=")
.append(
Base64.encodeToString(
this.clientDataJson, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", keyHandle=")
.append(
Base64.encodeToString(
this.keyHandle, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", attestationObject=")
.append(
Base64.encodeToString(
this.attestationObject, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", transports=")
.append(String.join(", ", this.transports))
.append(", authenticatorAttachment=")
.append(this.authenticatorAttachment)
.append("}");
return sb.toString();
}
}
@WrapForJNI
public static class GetAssertionResponse {
public final byte[] clientDataJson;
public final byte[] keyHandle;
public final byte[] authData;
public final byte[] signature;
public final byte[] userHandle;
public final String authenticatorAttachment;
public static final class Builder {
private byte[] mClientDataJson;
private byte[] mKeyHandle;
private byte[] mAuthData;
private byte[] mSignature;
private byte[] mUserHandle;
private String mAuthenticatorAttachment;
public Builder() {}
public Builder setClientDataJson(final byte[] clientDataJson) {
this.mClientDataJson = clientDataJson;
return this;
}
public Builder setKeyHandle(final byte[] keyHandle) {
this.mKeyHandle = keyHandle;
return this;
}
public Builder setAuthData(final byte[] authData) {
this.mAuthData = authData;
return this;
}
public Builder setSignature(final byte[] signature) {
this.mSignature = signature;
return this;
}
public Builder setUserHandle(final byte[] userHandle) {
this.mUserHandle = userHandle;
return this;
}
public Builder setAuthenticatorAttachment(final String authenticatorAttachment) {
this.mAuthenticatorAttachment = authenticatorAttachment;
return this;
}
public GetAssertionResponse build() {
return new GetAssertionResponse(this);
}
}
@WrapForJNI(skip = true)
protected GetAssertionResponse(final Builder builder) {
this.clientDataJson = builder.mClientDataJson;
this.keyHandle = builder.mKeyHandle;
this.authData = builder.mAuthData;
this.signature = builder.mSignature;
if (builder.mUserHandle == null) {
this.userHandle = new byte[0];
} else {
this.userHandle = builder.mUserHandle;
}
this.authenticatorAttachment = builder.mAuthenticatorAttachment;
}
@WrapForJNI(skip = true)
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("{");
sb.append("clientDataJson=")
.append(
Base64.encodeToString(
this.clientDataJson, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", keyHandle=")
.append(
Base64.encodeToString(
this.keyHandle, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", authData=")
.append(
Base64.encodeToString(
this.authData, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", signature=")
.append(
Base64.encodeToString(
this.signature, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING))
.append(", userHandle=")
.append(
userHandle.length > 0
? Base64.encodeToString(
this.userHandle, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING)
: "(empty)")
.append(", authenticatorAttachment=")
.append(this.authenticatorAttachment)
.append("}");
return sb.toString();
}
}
}

View File

@ -7,10 +7,8 @@ package org.mozilla.geckoview;
import android.app.PendingIntent;
import android.net.Uri;
import android.util.Base64;
import android.util.Log;
import com.google.android.gms.fido.Fido;
import com.google.android.gms.fido.common.Transport;
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;
@ -43,16 +41,11 @@ import java.util.List;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.WebAuthnUtils;
/* package */ class WebAuthnTokenManager {
private static final String LOGTAG = "WebAuthnTokenManager";
// from dom/webauthn/WebAuthnTransportIdentifiers.h
private static final byte AUTHENTICATOR_TRANSPORT_USB = 1;
private static final byte AUTHENTICATOR_TRANSPORT_NFC = 2;
private static final byte AUTHENTICATOR_TRANSPORT_BLE = 4;
private static final byte AUTHENTICATOR_TRANSPORT_INTERNAL = 8;
private static final Algorithm[] SUPPORTED_ALGORITHMS = {
EC2Algorithm.ES256,
EC2Algorithm.ES384,
@ -67,95 +60,17 @@ import org.mozilla.gecko.util.GeckoBundle;
RSAAlgorithm.RS512
};
private static List<Transport> getTransportsForByte(final byte transports) {
final ArrayList<Transport> result = new ArrayList<Transport>();
if ((transports & AUTHENTICATOR_TRANSPORT_USB) == AUTHENTICATOR_TRANSPORT_USB) {
result.add(Transport.USB);
}
if ((transports & AUTHENTICATOR_TRANSPORT_NFC) == AUTHENTICATOR_TRANSPORT_NFC) {
result.add(Transport.NFC);
}
if ((transports & AUTHENTICATOR_TRANSPORT_BLE) == AUTHENTICATOR_TRANSPORT_BLE) {
result.add(Transport.BLUETOOTH_LOW_ENERGY);
}
if ((transports & AUTHENTICATOR_TRANSPORT_INTERNAL) == AUTHENTICATOR_TRANSPORT_INTERNAL) {
result.add(Transport.INTERNAL);
}
return result;
}
public static class WebAuthnPublicCredential {
public final byte[] id;
public final byte transports;
public WebAuthnPublicCredential(final byte[] aId, final byte aTransports) {
this.id = aId;
this.transports = aTransports;
}
static ArrayList<WebAuthnPublicCredential> CombineBuffers(
final Object[] idObjectList, final ByteBuffer transportList) {
if (idObjectList.length != transportList.remaining()) {
throw new RuntimeException("Couldn't extract allowed list!");
}
final ArrayList<WebAuthnPublicCredential> credList =
new ArrayList<WebAuthnPublicCredential>();
final byte[] transportBytes = new byte[transportList.remaining()];
transportList.get(transportBytes);
for (int i = 0; i < idObjectList.length; i++) {
final ByteBuffer id = (ByteBuffer) idObjectList[i];
final byte[] idBytes = new byte[id.remaining()];
id.get(idBytes);
credList.add(new WebAuthnPublicCredential(idBytes, transportBytes[i]));
}
return credList;
}
}
// From WebAuthentication.webidl
public enum AttestationPreference {
NONE,
INDIRECT,
DIRECT,
}
@WrapForJNI
public static class MakeCredentialResponse {
public final byte[] clientDataJson;
public final byte[] keyHandle;
public final byte[] attestationObject;
public final String[] transports;
public final String authenticatorAttachment;
public MakeCredentialResponse(
final byte[] clientDataJson,
final byte[] keyHandle,
final byte[] attestationObject,
final String[] transports,
final String authenticatorAttachment) {
this.clientDataJson = clientDataJson;
this.keyHandle = keyHandle;
this.attestationObject = attestationObject;
this.transports = transports;
this.authenticatorAttachment = authenticatorAttachment;
}
}
public static class Exception extends RuntimeException {
public Exception(final String error) {
super(error);
}
}
public static GeckoResult<MakeCredentialResponse> makeCredential(
public static GeckoResult<WebAuthnUtils.MakeCredentialResponse> makeCredential(
final GeckoBundle credentialBundle,
final byte[] userId,
final byte[] challenge,
final WebAuthnTokenManager.WebAuthnPublicCredential[] excludeList,
final WebAuthnUtils.WebAuthnPublicCredential[] excludeList,
final GeckoBundle authenticatorSelection,
final GeckoBundle extensions) {
if (!credentialBundle.containsKey("isWebAuthn")) {
@ -227,12 +142,12 @@ import org.mozilla.gecko.util.GeckoBundle;
final List<PublicKeyCredentialDescriptor> excludedList =
new ArrayList<PublicKeyCredentialDescriptor>();
for (final WebAuthnTokenManager.WebAuthnPublicCredential cred : excludeList) {
for (final WebAuthnUtils.WebAuthnPublicCredential cred : excludeList) {
excludedList.add(
new PublicKeyCredentialDescriptor(
PublicKeyCredentialType.PUBLIC_KEY.toString(),
cred.id,
getTransportsForByte(cred.transports)));
WebAuthnUtils.getTransportsForByte(cred.transports)));
}
final PublicKeyCredentialRpEntity rp =
@ -286,7 +201,7 @@ import org.mozilla.gecko.util.GeckoBundle;
intentTask = fidoClient.getRegisterPendingIntent(requestOptions);
}
final GeckoResult<MakeCredentialResponse> result = new GeckoResult<>();
final GeckoResult<WebAuthnUtils.MakeCredentialResponse> result = new GeckoResult<>();
intentTask.addOnSuccessListener(
pendingIntent -> {
@ -321,36 +236,18 @@ import org.mozilla.gecko.util.GeckoBundle;
final AuthenticatorAttestationResponse responseData =
(AuthenticatorAttestationResponse) response;
final WebAuthnUtils.MakeCredentialResponse credentialResponse =
new WebAuthnUtils.MakeCredentialResponse.Builder()
.setKeyHandle(publicKeyCredentialData.getRawId())
.setAuthenticatorAttachment(
publicKeyCredentialData.getAuthenticatorAttachment())
.setClientDataJson(responseData.getClientDataJSON())
.setAttestationObject(responseData.getAttestationObject())
.setTransports(responseData.getTransports())
.build();
Log.d(
LOGTAG,
"key handle: "
+ Base64.encodeToString(
publicKeyCredentialData.getRawId(), Base64.DEFAULT));
Log.d(
LOGTAG,
"clientDataJSON: "
+ Base64.encodeToString(
responseData.getClientDataJSON(), Base64.DEFAULT));
Log.d(
LOGTAG,
"attestation Object: "
+ Base64.encodeToString(
responseData.getAttestationObject(), Base64.DEFAULT));
Log.d(LOGTAG, "transports: " + String.join(", ", responseData.getTransports()));
Log.d(
LOGTAG,
"authenticatorAttachment :"
+ publicKeyCredentialData.getAuthenticatorAttachment());
result.complete(
new WebAuthnTokenManager.MakeCredentialResponse(
responseData.getClientDataJSON(),
publicKeyCredentialData.getRawId(),
responseData.getAttestationObject(),
responseData.getTransports(),
publicKeyCredentialData.getAuthenticatorAttachment()));
Log.d(LOGTAG, "MakeCredentialResponse: " + credentialResponse.toString());
result.complete(credentialResponse);
},
e -> {
Log.w(LOGTAG, "Failed to launch activity: ", e);
@ -368,7 +265,7 @@ import org.mozilla.gecko.util.GeckoBundle;
}
@WrapForJNI(calledFrom = "gecko")
private static GeckoResult<MakeCredentialResponse> webAuthnMakeCredential(
private static GeckoResult<WebAuthnUtils.MakeCredentialResponse> webAuthnMakeCredential(
final GeckoBundle credentialBundle,
final ByteBuffer userId,
final ByteBuffer challenge,
@ -376,7 +273,7 @@ import org.mozilla.gecko.util.GeckoBundle;
final ByteBuffer transportList,
final GeckoBundle authenticatorSelection,
final GeckoBundle extensions) {
final ArrayList<WebAuthnPublicCredential> excludeList;
final ArrayList<WebAuthnUtils.WebAuthnPublicCredential> excludeList;
final byte[] challBytes = new byte[challenge.remaining()];
final byte[] userBytes = new byte[userId.remaining()];
@ -384,7 +281,7 @@ import org.mozilla.gecko.util.GeckoBundle;
challenge.get(challBytes);
userId.get(userBytes);
excludeList = WebAuthnPublicCredential.CombineBuffers(idList, transportList);
excludeList = WebAuthnUtils.WebAuthnPublicCredential.CombineBuffers(idList, transportList);
} catch (final RuntimeException e) {
Log.w(LOGTAG, "Couldn't extract nio byte arrays!", e);
return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR"));
@ -395,7 +292,7 @@ import org.mozilla.gecko.util.GeckoBundle;
credentialBundle,
userBytes,
challBytes,
excludeList.toArray(new WebAuthnPublicCredential[0]),
excludeList.toArray(new WebAuthnUtils.WebAuthnPublicCredential[0]),
authenticatorSelection,
extensions);
} catch (final Exception e) {
@ -408,31 +305,6 @@ import org.mozilla.gecko.util.GeckoBundle;
}
}
@WrapForJNI
public static class GetAssertionResponse {
public final byte[] clientDataJson;
public final byte[] keyHandle;
public final byte[] authData;
public final byte[] signature;
public final byte[] userHandle;
public final String authenticatorAttachment;
public GetAssertionResponse(
final byte[] clientDataJson,
final byte[] keyHandle,
final byte[] authData,
final byte[] signature,
final byte[] userHandle,
final String authenticatorAttachment) {
this.clientDataJson = clientDataJson;
this.keyHandle = keyHandle;
this.authData = authData;
this.signature = signature;
this.userHandle = userHandle;
this.authenticatorAttachment = authenticatorAttachment;
}
}
private static WebAuthnTokenManager.Exception parseErrorResponse(
final AuthenticatorResponse response) {
if (!(response instanceof AuthenticatorErrorResponse)) {
@ -447,9 +319,9 @@ import org.mozilla.gecko.util.GeckoBundle;
return new WebAuthnTokenManager.Exception(responseData.getErrorCode().name());
}
private static GeckoResult<GetAssertionResponse> getAssertion(
private static GeckoResult<WebAuthnUtils.GetAssertionResponse> getAssertion(
final byte[] challenge,
final WebAuthnTokenManager.WebAuthnPublicCredential[] allowList,
final WebAuthnUtils.WebAuthnPublicCredential[] allowList,
final GeckoBundle assertionBundle,
final GeckoBundle extensions) {
@ -460,12 +332,12 @@ import org.mozilla.gecko.util.GeckoBundle;
final List<PublicKeyCredentialDescriptor> allowedList =
new ArrayList<PublicKeyCredentialDescriptor>();
for (final WebAuthnTokenManager.WebAuthnPublicCredential cred : allowList) {
for (final WebAuthnUtils.WebAuthnPublicCredential cred : allowList) {
allowedList.add(
new PublicKeyCredentialDescriptor(
PublicKeyCredentialType.PUBLIC_KEY.toString(),
cred.id,
getTransportsForByte(cred.transports)));
WebAuthnUtils.getTransportsForByte(cred.transports)));
}
final AuthenticationExtensions.Builder extBuilder = new AuthenticationExtensions.Builder();
@ -505,7 +377,7 @@ import org.mozilla.gecko.util.GeckoBundle;
intentTask = fidoClient.getSignPendingIntent(requestOptions);
}
final GeckoResult<GetAssertionResponse> result = new GeckoResult<>();
final GeckoResult<WebAuthnUtils.GetAssertionResponse> result = new GeckoResult<>();
intentTask.addOnSuccessListener(
pendingIntent -> {
GeckoRuntime.getInstance()
@ -539,46 +411,19 @@ import org.mozilla.gecko.util.GeckoBundle;
}
final AuthenticatorAssertionResponse responseData =
(AuthenticatorAssertionResponse) publicKeyCredentialData.getResponse();
Log.d(
LOGTAG,
"key handle: "
+ Base64.encodeToString(
publicKeyCredentialData.getRawId(), Base64.DEFAULT));
Log.d(
LOGTAG,
"clientDataJSON: "
+ Base64.encodeToString(
responseData.getClientDataJSON(), Base64.DEFAULT));
Log.d(
LOGTAG,
"auth data: "
+ Base64.encodeToString(
responseData.getAuthenticatorData(), Base64.DEFAULT));
Log.d(
LOGTAG,
"signature: "
+ Base64.encodeToString(responseData.getSignature(), Base64.DEFAULT));
Log.d(
LOGTAG,
"authenticatorAttachment :"
+ publicKeyCredentialData.getAuthenticatorAttachment());
// Nullable field
byte[] userHandle = responseData.getUserHandle();
if (userHandle == null) {
userHandle = new byte[0];
}
result.complete(
new WebAuthnTokenManager.GetAssertionResponse(
responseData.getClientDataJSON(),
publicKeyCredentialData.getRawId(),
responseData.getAuthenticatorData(),
responseData.getSignature(),
userHandle,
publicKeyCredentialData.getAuthenticatorAttachment()));
(AuthenticatorAssertionResponse) response;
final WebAuthnUtils.GetAssertionResponse assertionResponse =
new WebAuthnUtils.GetAssertionResponse.Builder()
.setClientDataJson(responseData.getClientDataJSON())
.setKeyHandle(publicKeyCredentialData.getRawId())
.setAuthData(responseData.getAuthenticatorData())
.setSignature(responseData.getSignature())
.setUserHandle(responseData.getUserHandle())
.setAuthenticatorAttachment(
publicKeyCredentialData.getAuthenticatorAttachment())
.build();
Log.d(LOGTAG, "GetAssertionResponse: " + assertionResponse.toString());
result.complete(assertionResponse);
},
e -> {
Log.w(LOGTAG, "Failed to get FIDO intent", e);
@ -590,18 +435,18 @@ import org.mozilla.gecko.util.GeckoBundle;
}
@WrapForJNI(calledFrom = "gecko")
private static GeckoResult<GetAssertionResponse> webAuthnGetAssertion(
private static GeckoResult<WebAuthnUtils.GetAssertionResponse> webAuthnGetAssertion(
final ByteBuffer challenge,
final Object[] idList,
final ByteBuffer transportList,
final GeckoBundle assertionBundle,
final GeckoBundle extensions) {
final ArrayList<WebAuthnPublicCredential> allowList;
final ArrayList<WebAuthnUtils.WebAuthnPublicCredential> allowList;
final byte[] challBytes = new byte[challenge.remaining()];
try {
challenge.get(challBytes);
allowList = WebAuthnPublicCredential.CombineBuffers(idList, transportList);
allowList = WebAuthnUtils.WebAuthnPublicCredential.CombineBuffers(idList, transportList);
} catch (final RuntimeException e) {
Log.w(LOGTAG, "Couldn't extract nio byte arrays!", e);
return GeckoResult.fromException(new WebAuthnTokenManager.Exception("UNKNOWN_ERR"));
@ -610,7 +455,7 @@ import org.mozilla.gecko.util.GeckoBundle;
try {
return getAssertion(
challBytes,
allowList.toArray(new WebAuthnPublicCredential[0]),
allowList.toArray(new WebAuthnUtils.WebAuthnPublicCredential[0]),
assertionBundle,
extensions);
} catch (final java.lang.Exception e) {

View File

@ -82,6 +82,7 @@ classes_with_WrapForJNI = [
"SurfaceTextureListener",
"TelemetryUtils",
"WebAuthnTokenManager",
"WebAuthnUtils",
"WebMessage",
"WebNotification",
"WebNotificationDelegate",