Repo Created
This commit is contained in:
parent
eb305e2886
commit
a8c22c65db
4784 changed files with 329907 additions and 2 deletions
6
play-services-fido/src/main/AndroidManifest.xml
Normal file
6
play-services-fido/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
~ SPDX-License-Identifier: Apache-2.0
|
||||
-->
|
||||
<manifest />
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.google.android.gms.fido.fido2.api;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
interface IBooleanCallback {
|
||||
void onBoolean(boolean value) = 0;
|
||||
void onError(in Status status) = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.google.android.gms.fido.fido2.api;
|
||||
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.fido.fido2.api.common.FidoCredentialDetails;
|
||||
|
||||
interface ICredentialListCallback {
|
||||
void onCredentialList(in List<FidoCredentialDetails> value) = 0;
|
||||
void onError(in Status status) = 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
parcelable BrowserPublicKeyCredentialCreationOptions;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
parcelable BrowserPublicKeyCredentialRequestOptions;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
parcelable FidoCredentialDetails;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
parcelable PublicKeyCredentialCreationOptions;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
parcelable PublicKeyCredentialRequestOptions;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.google.android.gms.fido.fido2.internal.privileged;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
interface IFido2PrivilegedCallbacks {
|
||||
void onPendingIntent(in Status status, in PendingIntent pendingIntent);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.google.android.gms.fido.fido2.internal.privileged;
|
||||
|
||||
import com.google.android.gms.fido.fido2.internal.privileged.IFido2PrivilegedCallbacks;
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.ICredentialListCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialRequestOptions;
|
||||
|
||||
interface IFido2PrivilegedService {
|
||||
void getRegisterPendingIntent(IFido2PrivilegedCallbacks callbacks, in BrowserPublicKeyCredentialCreationOptions options) = 0;
|
||||
void getSignPendingIntent(IFido2PrivilegedCallbacks callbacks, in BrowserPublicKeyCredentialRequestOptions options) = 1;
|
||||
void isUserVerifyingPlatformAuthenticatorAvailable(IBooleanCallback callbacks) = 2;
|
||||
void getCredentialList(ICredentialListCallback callbacks, String rpId) = 3;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package com.google.android.gms.fido.fido2.internal.regular;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
|
||||
interface IFido2AppCallbacks {
|
||||
void onPendingIntent(in Status status, in PendingIntent pendingIntent);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.google.android.gms.fido.fido2.internal.regular;
|
||||
|
||||
import com.google.android.gms.fido.fido2.internal.regular.IFido2AppCallbacks;
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.ICredentialListCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions;
|
||||
|
||||
interface IFido2AppService {
|
||||
void getRegisterPendingIntent(IFido2AppCallbacks callbacks, in PublicKeyCredentialCreationOptions options) = 0;
|
||||
void getSignPendingIntent(IFido2AppCallbacks callbacks, in PublicKeyCredentialRequestOptions options) = 1;
|
||||
void isUserVerifyingPlatformAuthenticatorAvailable(IBooleanCallback callbacks) = 2;
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
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;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredential;
|
||||
import com.google.android.gms.fido.fido2.Fido2ApiClient;
|
||||
import com.google.android.gms.fido.fido2.Fido2PendingIntent;
|
||||
import com.google.android.gms.fido.fido2.Fido2PrivilegedApiClient;
|
||||
import com.google.android.gms.fido.sourcedevice.SourceDirectTransferClient;
|
||||
import com.google.android.gms.fido.u2f.U2fApiClient;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Entry point for Fido APIs.
|
||||
* <p>
|
||||
* FIDO (Fast IDentity Online), which is the industry alliance where Security Keys are being standardized.
|
||||
*/
|
||||
@PublicApi
|
||||
public class Fido {
|
||||
/**
|
||||
* The key used by the calling {@link Activity} to retrieve {@link PublicKeyCredential} from the Intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link Fido2PendingIntent}.
|
||||
*/
|
||||
public static final String FIDO2_KEY_CREDENTIAL_EXTRA = "FIDO2_CREDENTIAL_EXTRA";
|
||||
|
||||
/**
|
||||
* The key used by the calling {@link Activity} to retrieve {@link AuthenticatorErrorResponse} from the Intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link Fido2PendingIntent}.
|
||||
*
|
||||
* @deprecated use {@link #FIDO2_KEY_CREDENTIAL_EXTRA} to fetch {@link PublicKeyCredential} instead.
|
||||
* {@link PublicKeyCredential} contains an {@link AuthenticatorErrorResponse}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String FIDO2_KEY_ERROR_EXTRA = "FIDO2_ERROR_EXTRA";
|
||||
|
||||
/**
|
||||
* The key used by the calling {@link Activity} to retrieve {@link AuthenticatorAttestationResponse} or
|
||||
* {@link AuthenticatorAssertionResponse} from the Intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link Fido2PendingIntent}.
|
||||
*
|
||||
* @deprecated use {@link #FIDO2_KEY_CREDENTIAL_EXTRA} to fetch {@link PublicKeyCredential} instead.
|
||||
* {@link PublicKeyCredential} contains an {@link AuthenticatorAttestationResponse} or an {@link AuthenticatorAssertionResponse}.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final String FIDO2_KEY_RESPONSE_EXTRA = "FIDO2_RESPONSE_EXTRA";
|
||||
|
||||
/**
|
||||
* The key used by the calling {@link Activity} to retrieve {@link ResponseData} from the Intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link Fido2PendingIntent}.
|
||||
*/
|
||||
public static final String KEY_RESPONSE_EXTRA = "RESPONSE_EXTRA";
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Fido2ApiClient} for use in a non-activity {@link Context}.
|
||||
*/
|
||||
public static Fido2ApiClient getFido2ApiClient(Context context) {
|
||||
return new Fido2ApiClient(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Fido2ApiClient} for use in an {@link Activity}.
|
||||
*/
|
||||
public static Fido2ApiClient getFido2ApiClient(Activity activity) {
|
||||
return new Fido2ApiClient(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Fido2PrivilegedApiClient} for use in a non-activity {@link Context}.
|
||||
*/
|
||||
public static Fido2PrivilegedApiClient getFido2PrivilegedApiClient(Context context) {
|
||||
return new Fido2PrivilegedApiClient(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Fido2PrivilegedApiClient} for use in an {@link Activity}.
|
||||
*/
|
||||
public static Fido2PrivilegedApiClient getFido2PrivilegedApiClient(Activity activity) {
|
||||
return new Fido2PrivilegedApiClient(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link SourceDirectTransferClient} for use in a non-activity {@link Context}.
|
||||
*/
|
||||
public static final SourceDirectTransferClient getSourceDirectTransferClient(Context context) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link SourceDirectTransferClient} for use in an {@link Activity}.
|
||||
*/
|
||||
public static final SourceDirectTransferClient getSourceDirectTransferClient(Activity activity) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link U2fApiClient} for use in a non-activity {@link Context}.
|
||||
*/
|
||||
public static U2fApiClient getU2fApiClient(Context context) {
|
||||
return new U2fApiClient(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link U2fApiClient} for use in an {@link Activity}.
|
||||
*/
|
||||
public static U2fApiClient getU2fApiClient(Activity activity) {
|
||||
return new U2fApiClient(activity);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* The transport between the authenticator and the client.
|
||||
*/
|
||||
@PublicApi
|
||||
public enum Transport implements Parcelable {
|
||||
BLUETOOTH_CLASSIC("bt"),
|
||||
BLUETOOTH_LOW_ENERGY("ble"),
|
||||
NFC("nfc"),
|
||||
USB("usb"),
|
||||
INTERNAL("internal"),
|
||||
HYBRID("cable");
|
||||
|
||||
private final String value;
|
||||
|
||||
Transport(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(toString());
|
||||
}
|
||||
|
||||
@PublicApi(exclude = true)
|
||||
public static Transport fromString(String transport) throws UnsupportedTransportException {
|
||||
for (Transport value : values()) {
|
||||
if (value.value.equals(transport)) return value;
|
||||
}
|
||||
if (transport.equals("hybrid")) {
|
||||
return HYBRID;
|
||||
}
|
||||
throw new UnsupportedTransportException("Transport " + transport + " not supported");
|
||||
}
|
||||
|
||||
@PublicApi(exclude = true)
|
||||
public static List<Transport> parseTransports(JSONArray jsonArray) throws JSONException {
|
||||
if (jsonArray == null) return null;
|
||||
Set<Transport> set = new HashSet<>();
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
String transport = jsonArray.getString(i);
|
||||
if (transport != null && !transport.isEmpty()) {
|
||||
try {
|
||||
set.add(fromString(transport));
|
||||
} catch (UnsupportedTransportException e) {
|
||||
Log.w("Transport", "Ignoring unrecognized transport " + transport);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(set);
|
||||
}
|
||||
|
||||
public static Creator<Transport> CREATOR = new Creator<Transport>() {
|
||||
@Override
|
||||
public Transport createFromParcel(Parcel source) {
|
||||
try {
|
||||
return Transport.fromString(source.readString());
|
||||
} catch (UnsupportedTransportException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Transport[] newArray(int size) {
|
||||
return new Transport[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized transport is encountered.
|
||||
*/
|
||||
public static class UnsupportedTransportException extends Exception {
|
||||
public UnsupportedTransportException(String errorMessage) {
|
||||
super(errorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.GoogleApi;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions;
|
||||
import com.google.android.gms.fido.fido2.internal.regular.IFido2AppCallbacks;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.Tasks;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.common.api.PendingGoogleApiCall;
|
||||
import org.microg.gms.fido.fido2.Fido2GmsClient;
|
||||
import org.microg.gms.fido.fido2.Fido2PendingIntentImpl;
|
||||
|
||||
/**
|
||||
* The entry point for interacting with FIDO2 APIs.
|
||||
*/
|
||||
@PublicApi
|
||||
public class Fido2ApiClient extends GoogleApi<Api.ApiOptions.NoOptions> {
|
||||
private static final Api<Api.ApiOptions.NoOptions> API = new Api<>((options, context, looper, clientSettings, callbacks, connectionFailedListener) -> new Fido2GmsClient(context, callbacks, connectionFailedListener));
|
||||
|
||||
@PublicApi(exclude = true)
|
||||
public Fido2ApiClient(Context context) {
|
||||
super(context, API, Api.ApiOptions.NO_OPTIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getRegisterPendingIntent(PublicKeyCredentialCreationOptions)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Task<Fido2PendingIntent> getRegisterIntent(PublicKeyCredentialCreationOptions requestOptions) {
|
||||
return getRegisterPendingIntent(requestOptions).onSuccessTask(pendingIntent -> Tasks.forResult(new Fido2PendingIntentImpl(pendingIntent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with {@link PendingIntent}, when started, will issue a FIDO2 registration request, which is done
|
||||
* once per FIDO2 device per account for associating the new FIDO2 device with that account.
|
||||
*
|
||||
* @param requestOptions for the registration request
|
||||
* @return Task with PendingIntent to launch FIDO2 registration request
|
||||
*/
|
||||
public Task<PendingIntent> getRegisterPendingIntent(PublicKeyCredentialCreationOptions requestOptions) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingIntent, Fido2GmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.getRegisterPendingIntent(new IFido2AppCallbacks.Stub() {
|
||||
@Override
|
||||
public void onPendingIntent(Status status, PendingIntent pendingIntent) throws RemoteException {
|
||||
if (status.isSuccess()) {
|
||||
completionSource.setResult(pendingIntent);
|
||||
} else {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
}
|
||||
}, requestOptions);
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #getSignPendingIntent(PublicKeyCredentialRequestOptions)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Task<Fido2PendingIntent> getSignIntent(PublicKeyCredentialRequestOptions requestOptions) {
|
||||
return getSignPendingIntent(requestOptions).onSuccessTask(pendingIntent -> Tasks.forResult(new Fido2PendingIntentImpl(pendingIntent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with {@link PendingIntent}, when started, will issue a FIDO2 signature request for a relying
|
||||
* party to authenticate a user.
|
||||
*
|
||||
* @param requestOptions for the sign request
|
||||
* @return Task with PendingIntent to launch FIDO2 signature request
|
||||
*/
|
||||
public Task<PendingIntent> getSignPendingIntent(PublicKeyCredentialRequestOptions requestOptions) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingIntent, Fido2GmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.getSignPendingIntent(new IFido2AppCallbacks.Stub() {
|
||||
@Override
|
||||
public void onPendingIntent(Status status, PendingIntent pendingIntent) throws RemoteException {
|
||||
if (status.isSuccess()) {
|
||||
completionSource.setResult(pendingIntent);
|
||||
} else {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
}
|
||||
}, requestOptions);
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with {@link Boolean}, which check if a user verifying platform authenticator is available on the
|
||||
* device.
|
||||
*/
|
||||
public Task<Boolean> isUserVerifyingPlatformAuthenticatorAvailable() {
|
||||
return scheduleTask((PendingGoogleApiCall<Boolean, Fido2GmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.isUserVerifyingPlatformAuthenticatorAvailable(new IBooleanCallback.Stub() {
|
||||
@Override
|
||||
public void onBoolean(boolean value) throws RemoteException {
|
||||
completionSource.setResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Status status) throws RemoteException {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentSender;
|
||||
|
||||
/**
|
||||
* Use {@link Fido2ApiClient#getRegisterPendingIntent(PublicKeyCredentialCreationOptions)} or
|
||||
* {@link Fido2ApiClient#getSignPendingIntent(PublicKeyCredentialRequestOptions)} to avoid a dependence on this.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface Fido2PendingIntent {
|
||||
/**
|
||||
* Returns true if an {@link Activity} has a {@link PendingIntent}.
|
||||
*/
|
||||
boolean hasPendingIntent();
|
||||
|
||||
/**
|
||||
* Launches the PendingIntent.
|
||||
*
|
||||
* @param activity An Activity context to use to launch the intent. The activity's onActivityResult method will
|
||||
* be invoked after the user is done.
|
||||
* @param requestCode The request code to pass to onActivityResult.
|
||||
* @throws IllegalStateException if hasPendingIntent is false
|
||||
* @throws IntentSender.SendIntentException If the resolution intent has been canceled or is no longer able to
|
||||
* execute the request.
|
||||
*/
|
||||
void launchPendingIntent(Activity activity, int requestCode) throws IntentSender.SendIntentException;
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.GoogleApi;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.ICredentialListCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialRequestOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.FidoCredentialDetails;
|
||||
import com.google.android.gms.fido.fido2.internal.privileged.IFido2PrivilegedCallbacks;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
import com.google.android.gms.tasks.Tasks;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.common.api.PendingGoogleApiCall;
|
||||
import org.microg.gms.fido.fido2.Fido2PendingIntentImpl;
|
||||
import org.microg.gms.fido.fido2.Fido2PrivilegedGmsClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The entry point for interacting with the privileged FIDO2 APIs.
|
||||
*/
|
||||
@PublicApi
|
||||
public class Fido2PrivilegedApiClient extends GoogleApi<Api.ApiOptions.NoOptions> {
|
||||
private static final Api<Api.ApiOptions.NoOptions> API = new Api<>((options, context, looper, clientSettings, callbacks, connectionFailedListener) -> new Fido2PrivilegedGmsClient(context, callbacks, connectionFailedListener));
|
||||
|
||||
@PublicApi(exclude = true)
|
||||
public Fido2PrivilegedApiClient(Context context) {
|
||||
super(context, API, Api.ApiOptions.NO_OPTIONS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with a list of {@link FidoCredentialDetails} which, when started, will retrieve a list of credentials associated
|
||||
* with the given relying party ID.
|
||||
*
|
||||
* @param rpId indicating the relying party for which we want to list credentials
|
||||
* @return PendingResult with PendingIntent to retrieve the credential list
|
||||
*/
|
||||
public Task<List<FidoCredentialDetails>> getCredentialList(String rpId) {
|
||||
return scheduleTask((PendingGoogleApiCall<List<FidoCredentialDetails>, Fido2PrivilegedGmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.getCredentialList(new ICredentialListCallback.Stub() {
|
||||
@Override
|
||||
public void onCredentialList(List<FidoCredentialDetails> value) throws RemoteException {
|
||||
completionSource.setResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Status status) throws RemoteException {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
}, rpId);
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with PendingIntent, when started, will issue a FIDO2 registration request for privileged apps.
|
||||
*
|
||||
* @param requestOptions for the registration request from a Web browser
|
||||
* @return PendingResult with PendingIntent to launch FIDO2 registration request
|
||||
* @deprecated use {@link #getRegisterPendingIntent(BrowserPublicKeyCredentialCreationOptions)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Task<Fido2PendingIntent> getRegisterIntent(BrowserPublicKeyCredentialCreationOptions requestOptions) {
|
||||
return getRegisterPendingIntent(requestOptions).onSuccessTask(pendingIntent -> Tasks.forResult(new Fido2PendingIntentImpl(pendingIntent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with PendingIntent, when started, will issue a FIDO2 registration request for privileged apps.
|
||||
*
|
||||
* @param requestOptions for the registration request from a Web browser
|
||||
* @return PendingResult with PendingIntent to launch FIDO2 registration request
|
||||
*/
|
||||
public Task<PendingIntent> getRegisterPendingIntent(BrowserPublicKeyCredentialCreationOptions requestOptions) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingIntent, Fido2PrivilegedGmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.getRegisterPendingIntent(new IFido2PrivilegedCallbacks.Stub() {
|
||||
@Override
|
||||
public void onPendingIntent(Status status, PendingIntent pendingIntent) throws RemoteException {
|
||||
if (status.isSuccess()) {
|
||||
completionSource.setResult(pendingIntent);
|
||||
} else {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
}
|
||||
}, requestOptions);
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with PendingIntent, when started, will issue a FIDO2 signature request for privileged apps.
|
||||
*
|
||||
* @param requestOptions for the sign request from a Web browser
|
||||
* @return PendingResult with PendingIntent to launch FIDO2 signature request
|
||||
* @deprecated use {@link #getSignPendingIntent(BrowserPublicKeyCredentialRequestOptions)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public Task<Fido2PendingIntent> getSignIntent(BrowserPublicKeyCredentialRequestOptions requestOptions) {
|
||||
return getSignPendingIntent(requestOptions).onSuccessTask(pendingIntent -> Tasks.forResult(new Fido2PendingIntentImpl(pendingIntent)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with PendingIntent, when started, will issue a FIDO2 signature request for privileged apps.
|
||||
*
|
||||
* @param requestOptions for the sign request from a Web browser
|
||||
* @return PendingResult with PendingIntent to launch FIDO2 signature request
|
||||
*/
|
||||
public Task<PendingIntent> getSignPendingIntent(BrowserPublicKeyCredentialRequestOptions requestOptions) {
|
||||
return scheduleTask((PendingGoogleApiCall<PendingIntent, Fido2PrivilegedGmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.getSignPendingIntent(new IFido2PrivilegedCallbacks.Stub() {
|
||||
@Override
|
||||
public void onPendingIntent(Status status, PendingIntent pendingIntent) throws RemoteException {
|
||||
if (status.isSuccess()) {
|
||||
completionSource.setResult(pendingIntent);
|
||||
} else {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
}
|
||||
}, requestOptions);
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Task with {@link Boolean}, which check if a user verifying platform authenticator is available on the
|
||||
* device.
|
||||
*/
|
||||
public Task<Boolean> isUserVerifyingPlatformAuthenticatorAvailable() {
|
||||
return scheduleTask((PendingGoogleApiCall<Boolean, Fido2PrivilegedGmsClient>) (client, completionSource) -> {
|
||||
try {
|
||||
client.isUserVerifyingPlatformAuthenticatorAvailable(new IBooleanCallback.Stub() {
|
||||
@Override
|
||||
public void onBoolean(boolean value) throws RemoteException {
|
||||
completionSource.setResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Status status) throws RemoteException {
|
||||
completionSource.setException(new ApiException(status));
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
completionSource.setException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
/**
|
||||
* An interface for an algorithm used in public key encryption. All implementations must conform to the guidelines
|
||||
* regarding algorithm registrations in RFC8152.
|
||||
*/
|
||||
public interface Algorithm {
|
||||
/**
|
||||
* Gets the COSE value for the algorithm used in the encryption of the credential.
|
||||
*/
|
||||
int getAlgoValue();
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
/**
|
||||
* Clients may communicate with authenticators using a variety of mechanisms. We define authenticators that are
|
||||
* part of the client's platform as having a platform attachment, and refer to them as platform authenticators.
|
||||
* While those that are reachable via cross-platform transport protocols are defined as having cross-platform
|
||||
* attachment, and refer to them as roaming authenticators.
|
||||
*/
|
||||
public enum Attachment implements Parcelable {
|
||||
PLATFORM("platform"),
|
||||
CROSS_PLATFORM("cross-platform");
|
||||
|
||||
private final String value;
|
||||
|
||||
Attachment(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(toString());
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static Attachment fromString(String attachment) throws UnsupportedAttachmentException {
|
||||
for (Attachment value : values()) {
|
||||
if (value.value.equals(attachment)) return value;
|
||||
}
|
||||
throw new UnsupportedAttachmentException("Attachment " + attachment + " not supported");
|
||||
}
|
||||
|
||||
public static Creator<Attachment> CREATOR = new Creator<Attachment>() {
|
||||
@Override
|
||||
public Attachment createFromParcel(Parcel source) {
|
||||
try {
|
||||
return Attachment.fromString(source.readString());
|
||||
} catch (Attachment.UnsupportedAttachmentException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attachment[] newArray(int size) {
|
||||
return new Attachment[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized attachment is encountered.
|
||||
*/
|
||||
public static class UnsupportedAttachmentException extends Exception {
|
||||
public UnsupportedAttachmentException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import org.microg.gms.common.Hide;
|
||||
|
||||
/**
|
||||
* An enum describing the relying party's preference for attestation conveyance.
|
||||
*/
|
||||
public enum AttestationConveyancePreference implements Parcelable {
|
||||
NONE("none"),
|
||||
INDIRECT("indirect"),
|
||||
DIRECT("direct");
|
||||
|
||||
private final String value;
|
||||
|
||||
AttestationConveyancePreference(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(toString());
|
||||
}
|
||||
|
||||
@Hide
|
||||
@NonNull
|
||||
public static AttestationConveyancePreference fromString(String attachment) throws UnsupportedAttestationConveyancePreferenceException {
|
||||
for (AttestationConveyancePreference value : values()) {
|
||||
if (value.value.equals(attachment)) return value;
|
||||
}
|
||||
throw new UnsupportedAttestationConveyancePreferenceException("Attestation conveyance preference " + attachment + " not supported");
|
||||
}
|
||||
|
||||
public static Creator<AttestationConveyancePreference> CREATOR = new Creator<AttestationConveyancePreference>() {
|
||||
@Override
|
||||
public AttestationConveyancePreference createFromParcel(Parcel source) {
|
||||
try {
|
||||
return AttestationConveyancePreference.fromString(source.readString());
|
||||
} catch (UnsupportedAttestationConveyancePreferenceException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttestationConveyancePreference[] newArray(int size) {
|
||||
return new AttestationConveyancePreference[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized attestation conveyance preference is encountered.
|
||||
*/
|
||||
public static class UnsupportedAttestationConveyancePreferenceException extends Exception {
|
||||
public UnsupportedAttestationConveyancePreferenceException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents extensions that can be passed into FIDO2 APIs. This container class corresponds to the additional
|
||||
* parameters requesting additional processing by authenticators.
|
||||
* <p>
|
||||
* Note that rather than accepting arbitrary objects as specified in WebAuthn, this class requires a structured entry
|
||||
* for each supported extension.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticationExtensions extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getFidoAppIdExtension")
|
||||
@Nullable
|
||||
private FidoAppIdExtension fidoAppIdExtension;
|
||||
@Field(value = 3, getterName = "getCableAuthenticationExtension")
|
||||
@Nullable
|
||||
private CableAuthenticationExtension cableAuthenticationExtension;
|
||||
@Field(value = 4, getterName = "getUserVerificationMethodExtension")
|
||||
@Nullable
|
||||
private UserVerificationMethodExtension userVerificationMethodExtension;
|
||||
@Field(value = 5, getterName = "getGoogleMultiAssertionExtension")
|
||||
@Nullable
|
||||
private GoogleMultiAssertionExtension googleMultiAssertionExtension;
|
||||
@Field(value = 6, getterName = "getGoogleSessionIdExtension")
|
||||
@Nullable
|
||||
private GoogleSessionIdExtension googleSessionIdExtension;
|
||||
@Field(value = 7, getterName = "getGoogleSilentVerificationExtension")
|
||||
@Nullable
|
||||
private GoogleSilentVerificationExtension googleSilentVerificationExtension;
|
||||
@Field(value = 8, getterName = "getDevicePublicKeyExtension")
|
||||
@Nullable
|
||||
private DevicePublicKeyExtension devicePublicKeyExtension;
|
||||
@Field(value = 9, getterName = "getGoogleTunnelServerIdExtension")
|
||||
@Nullable
|
||||
private GoogleTunnelServerIdExtension googleTunnelServerIdExtension;
|
||||
@Field(value = 10, getterName = "getGoogleThirdPartyPaymentExtension")
|
||||
@Nullable
|
||||
private GoogleThirdPartyPaymentExtension googleThirdPartyPaymentExtension;
|
||||
@Field(value = 11, getterName = "getPrfExtension")
|
||||
@Nullable
|
||||
private PrfExtension prfExtension;
|
||||
@Field(value = 12, getterName = "getSimpleTransactionAuthorizationExtension")
|
||||
@Nullable
|
||||
private SimpleTransactionAuthorizationExtension simpleTransactionAuthorizationExtension;
|
||||
@Field(value = 13, getterName = "getHmacSecretExtension")
|
||||
@Nullable
|
||||
private HmacSecretExtension hmacSecretExtension;
|
||||
@Field(value = 14, getterName = "getPaymentExtension")
|
||||
@Nullable
|
||||
private PaymentExtension paymentExtension;
|
||||
|
||||
@Constructor
|
||||
public AuthenticationExtensions(@Param(2) @Nullable FidoAppIdExtension fidoAppIdExtension, @Param(3) @Nullable CableAuthenticationExtension cableAuthenticationExtension, @Param(4) @Nullable UserVerificationMethodExtension userVerificationMethodExtension, @Param(5) @Nullable GoogleMultiAssertionExtension googleMultiAssertionExtension, @Param(6) @Nullable GoogleSessionIdExtension googleSessionIdExtension, @Param(7) @Nullable GoogleSilentVerificationExtension googleSilentVerificationExtension, @Param(8) @Nullable DevicePublicKeyExtension devicePublicKeyExtension, @Param(9) @Nullable GoogleTunnelServerIdExtension googleTunnelServerIdExtension, @Param(10) @Nullable GoogleThirdPartyPaymentExtension googleThirdPartyPaymentExtension, @Param(11) @Nullable PrfExtension prfExtension, @Param(12) @Nullable SimpleTransactionAuthorizationExtension simpleTransactionAuthorizationExtension, @Param(13) @Nullable HmacSecretExtension hmacSecretExtension, @Param(14) @Nullable PaymentExtension paymentExtension) {
|
||||
this.fidoAppIdExtension = fidoAppIdExtension;
|
||||
this.cableAuthenticationExtension = cableAuthenticationExtension;
|
||||
this.userVerificationMethodExtension = userVerificationMethodExtension;
|
||||
this.googleMultiAssertionExtension = googleMultiAssertionExtension;
|
||||
this.googleSessionIdExtension = googleSessionIdExtension;
|
||||
this.googleSilentVerificationExtension = googleSilentVerificationExtension;
|
||||
this.devicePublicKeyExtension = devicePublicKeyExtension;
|
||||
this.googleTunnelServerIdExtension = googleTunnelServerIdExtension;
|
||||
this.googleThirdPartyPaymentExtension = googleThirdPartyPaymentExtension;
|
||||
this.prfExtension = prfExtension;
|
||||
this.simpleTransactionAuthorizationExtension = simpleTransactionAuthorizationExtension;
|
||||
this.hmacSecretExtension = hmacSecretExtension;
|
||||
this.paymentExtension = paymentExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public FidoAppIdExtension getFidoAppIdExtension() {
|
||||
return fidoAppIdExtension;
|
||||
}
|
||||
|
||||
@Hide
|
||||
@Nullable
|
||||
public CableAuthenticationExtension getCableAuthenticationExtension() {
|
||||
return cableAuthenticationExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UserVerificationMethodExtension getUserVerificationMethodExtension() {
|
||||
return userVerificationMethodExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GoogleMultiAssertionExtension getGoogleMultiAssertionExtension() {
|
||||
return googleMultiAssertionExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GoogleSessionIdExtension getGoogleSessionIdExtension() {
|
||||
return googleSessionIdExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GoogleSilentVerificationExtension getGoogleSilentVerificationExtension() {
|
||||
return googleSilentVerificationExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DevicePublicKeyExtension getDevicePublicKeyExtension() {
|
||||
return devicePublicKeyExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GoogleTunnelServerIdExtension getGoogleTunnelServerIdExtension() {
|
||||
return googleTunnelServerIdExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GoogleThirdPartyPaymentExtension getGoogleThirdPartyPaymentExtension() {
|
||||
return googleThirdPartyPaymentExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PrfExtension getPrfExtension() {
|
||||
return prfExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public SimpleTransactionAuthorizationExtension getSimpleTransactionAuthorizationExtension() {
|
||||
return simpleTransactionAuthorizationExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public HmacSecretExtension getHmacSecretExtension() {
|
||||
return hmacSecretExtension;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PaymentExtension getPaymentExtension() {
|
||||
return paymentExtension;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticationExtensions)) return false;
|
||||
|
||||
AuthenticationExtensions that = (AuthenticationExtensions) o;
|
||||
|
||||
if (!Objects.equals(fidoAppIdExtension, that.fidoAppIdExtension)) return false;
|
||||
if (!Objects.equals(cableAuthenticationExtension, that.cableAuthenticationExtension)) return false;
|
||||
if (!Objects.equals(userVerificationMethodExtension, that.userVerificationMethodExtension)) return false;
|
||||
if (!Objects.equals(googleMultiAssertionExtension, that.googleMultiAssertionExtension)) return false;
|
||||
if (!Objects.equals(googleSessionIdExtension, that.googleSessionIdExtension)) return false;
|
||||
if (!Objects.equals(googleSilentVerificationExtension, that.googleSilentVerificationExtension)) return false;
|
||||
if (!Objects.equals(devicePublicKeyExtension, that.devicePublicKeyExtension)) return false;
|
||||
if (!Objects.equals(googleTunnelServerIdExtension, that.googleTunnelServerIdExtension)) return false;
|
||||
if (!Objects.equals(googleThirdPartyPaymentExtension, that.googleThirdPartyPaymentExtension)) return false;
|
||||
if (!Objects.equals(prfExtension, that.prfExtension)) return false;
|
||||
if (!Objects.equals(simpleTransactionAuthorizationExtension, that.simpleTransactionAuthorizationExtension)) return false;
|
||||
if (!Objects.equals(hmacSecretExtension, that.hmacSecretExtension)) return false;
|
||||
return Objects.equals(paymentExtension, that.paymentExtension);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{fidoAppIdExtension, cableAuthenticationExtension, userVerificationMethodExtension, googleMultiAssertionExtension, googleSessionIdExtension, googleSilentVerificationExtension, devicePublicKeyExtension, googleTunnelServerIdExtension, googleThirdPartyPaymentExtension, prfExtension, simpleTransactionAuthorizationExtension, hmacSecretExtension, paymentExtension});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticationExtensions").field("fidoAppIdExtension", fidoAppIdExtension != null ? fidoAppIdExtension.getAppId() : null).field("cableAuthenticationExtension", cableAuthenticationExtension).field("userVerificationMethodExtension", userVerificationMethodExtension != null ? userVerificationMethodExtension.getUvm() : null).field("googleMultiAssertionExtension", googleMultiAssertionExtension).field("googleSessionIdExtension", googleSessionIdExtension).field("googleSilentVerificationExtension", googleSilentVerificationExtension).field("devicePublicKeyExtension", devicePublicKeyExtension).field("googleTunnelServerIdExtension", googleTunnelServerIdExtension).field("googleThirdPartyPaymentExtension", googleThirdPartyPaymentExtension).field("prfExtension", prfExtension).field("simpleTransactionAuthorizationExtension", simpleTransactionAuthorizationExtension).field("hmacSecretExtension", hmacSecretExtension).field("paymentExtension", paymentExtension).end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link AuthenticationExtensions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private FidoAppIdExtension fidoAppIdExtension;
|
||||
@Nullable
|
||||
private UserVerificationMethodExtension userVerificationMethodExtension;
|
||||
|
||||
/**
|
||||
* The constructor of {@link AuthenticationExtensions.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the App ID extension, which allows for authentication of U2F authenticators previously registered
|
||||
* under the supplied App ID.
|
||||
*/
|
||||
public Builder setFido2Extension(@Nullable FidoAppIdExtension appIdExtension) {
|
||||
this.fidoAppIdExtension = appIdExtension;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the User Verification Method extension, which allows the relying party to ascertain up to three
|
||||
* authentication methods that were used.
|
||||
*/
|
||||
public Builder setUserVerificationMethodExtension(@Nullable UserVerificationMethodExtension userVerificationMethodExtension) {
|
||||
this.userVerificationMethodExtension = userVerificationMethodExtension;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link AuthenticationExtensions} object.
|
||||
*/
|
||||
@NonNull
|
||||
public AuthenticationExtensions build() {
|
||||
return new AuthenticationExtensions(fidoAppIdExtension, null, userVerificationMethodExtension, null, null, null, null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticationExtensions> CREATOR = findCreator(AuthenticationExtensions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This container class represents client output for extensions that can be passed into FIDO2 APIs.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticationExtensionsClientOutputs extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUvmEntries")
|
||||
@Nullable
|
||||
private UvmEntries uvmEntries;
|
||||
|
||||
@Field(value = 2, getterName = "getDevicePublicKeyOutputs")
|
||||
@Nullable
|
||||
private AuthenticationExtensionsDevicePublicKeyOutputs devicePublicKeyOutputs;
|
||||
|
||||
@Field(value = 3, getterName = "getCredProps")
|
||||
@Nullable
|
||||
private AuthenticationExtensionsCredPropsOutputs credProps;
|
||||
|
||||
@Field(value = 4, getterName = "getPrfOutputs")
|
||||
@Nullable
|
||||
private AuthenticationExtensionsPrfOutputs prfOutputs;
|
||||
|
||||
@Field(value = 5, getterName = "getTxAuthSimple")
|
||||
@Nullable
|
||||
private String txAuthSimple;
|
||||
|
||||
@Constructor
|
||||
public AuthenticationExtensionsClientOutputs(@Param(1) @Nullable UvmEntries uvmEntries, @Param(2) @Nullable AuthenticationExtensionsDevicePublicKeyOutputs devicePublicKeyOutputs, @Param(3) @Nullable AuthenticationExtensionsCredPropsOutputs credProps, @Param(4) @Nullable AuthenticationExtensionsPrfOutputs prfOutputs, @Param(5) @Nullable String txAuthSimple) {
|
||||
this.uvmEntries = uvmEntries;
|
||||
this.devicePublicKeyOutputs = devicePublicKeyOutputs;
|
||||
this.credProps = credProps;
|
||||
this.prfOutputs = prfOutputs;
|
||||
this.txAuthSimple = txAuthSimple;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public UvmEntries getUvmEntries() {
|
||||
return uvmEntries;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AuthenticationExtensionsDevicePublicKeyOutputs getDevicePublicKeyOutputs() {
|
||||
return devicePublicKeyOutputs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AuthenticationExtensionsCredPropsOutputs getCredProps() {
|
||||
return credProps;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AuthenticationExtensionsPrfOutputs getPrfOutputs() {
|
||||
return prfOutputs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getTxAuthSimple() {
|
||||
return txAuthSimple;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the {@link AuthenticationExtensionsClientOutputs} to bytes.
|
||||
* Use {@link #deserializeFromBytes(byte[])} to deserialize.
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* De-serializes the {@link AuthenticationExtensionsClientOutputs} from bytes, reversing {@link #serializeToBytes()}.
|
||||
*
|
||||
* @return The deserialized {@link AuthenticationExtensionsClientOutputs}
|
||||
*/
|
||||
@NonNull
|
||||
public static AuthenticationExtensionsClientOutputs deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticationExtensionsClientOutputs)) return false;
|
||||
|
||||
AuthenticationExtensionsClientOutputs that = (AuthenticationExtensionsClientOutputs) o;
|
||||
return (Objects.equals(uvmEntries, that.uvmEntries)) && (Objects.equals(devicePublicKeyOutputs, that.devicePublicKeyOutputs)) && (Objects.equals(credProps, that.credProps)) && (Objects.equals(prfOutputs, that.prfOutputs)) && (Objects.equals(txAuthSimple, that.txAuthSimple));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{uvmEntries, devicePublicKeyOutputs, credProps, prfOutputs, txAuthSimple});
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link AuthenticationExtensionsClientOutputs}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private UvmEntries uvmEntries;
|
||||
@Nullable
|
||||
private AuthenticationExtensionsDevicePublicKeyOutputs devicePublicKeyOutputs;
|
||||
@Nullable
|
||||
private AuthenticationExtensionsCredPropsOutputs credProps;
|
||||
@Nullable
|
||||
private AuthenticationExtensionsPrfOutputs prfOutputs;
|
||||
@Nullable
|
||||
private String txAuthSimple;
|
||||
|
||||
/**
|
||||
* The constructor of {@link AuthenticationExtensionsClientOutputs.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the User Verification Method extension, which allows the relying party to ascertain up to three
|
||||
* authentication methods that were used.
|
||||
*/
|
||||
public Builder setUserVerificationMethodEntries(@Nullable UvmEntries uvmEntries) {
|
||||
this.uvmEntries = uvmEntries;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Device Public Key client outputs
|
||||
*/
|
||||
public Builder setDevicePublicKeyOutputs(@Nullable AuthenticationExtensionsDevicePublicKeyOutputs dpkOutputs) {
|
||||
this.devicePublicKeyOutputs = dpkOutputs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Credential Properties client outputs (e.g., rk=true)
|
||||
*/
|
||||
public Builder setCredProps(@Nullable AuthenticationExtensionsCredPropsOutputs credProps) {
|
||||
this.credProps = credProps;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set PRF client outputs
|
||||
*/
|
||||
public Builder setPrfOutputs(@Nullable AuthenticationExtensionsPrfOutputs prfOutputs) {
|
||||
this.prfOutputs = prfOutputs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set txAuthSimple string
|
||||
*/
|
||||
public Builder setTxAuthSimple(@Nullable String txAuthSimple) {
|
||||
this.txAuthSimple = txAuthSimple;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link AuthenticationExtensionsClientOutputs} object.
|
||||
*/
|
||||
public AuthenticationExtensionsClientOutputs build() {
|
||||
return new AuthenticationExtensionsClientOutputs(uvmEntries, devicePublicKeyOutputs, credProps, prfOutputs, txAuthSimple);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticationExtensionsClientOutputs> CREATOR = findCreator(AuthenticationExtensionsClientOutputs.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Class that holds the result of the credProps extension.
|
||||
* <p>
|
||||
* Since this extension only reports information, it is always included in registration responses and does not need to be requested.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticationExtensionsCredPropsOutputs extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getIsDiscoverableCredential")
|
||||
private boolean rk;
|
||||
|
||||
@Constructor
|
||||
public AuthenticationExtensionsCredPropsOutputs(@Param(1) boolean rk) {
|
||||
this.rk = rk;
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
return (other instanceof AuthenticationExtensionsCredPropsOutputs) && this.rk == ((AuthenticationExtensionsCredPropsOutputs) other).rk;
|
||||
}
|
||||
|
||||
/**
|
||||
* This value reflects the "rk" flag of the WebAuthn extension.
|
||||
*/
|
||||
public boolean getIsDiscoverableCredential() {
|
||||
return rk;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(new Object[]{this.rk});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticationExtensionsCredPropsOutputs> CREATOR = findCreator(AuthenticationExtensionsCredPropsOutputs.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticationExtensionsDevicePublicKeyOutputs extends AbstractSafeParcelable {
|
||||
|
||||
@Field(value = 1, getterName = "getDevicePublicKey")
|
||||
@Nullable
|
||||
private final byte[] devicePublicKey;
|
||||
|
||||
@Field(value = 2, getterName = "getSignature")
|
||||
@Nullable
|
||||
private final byte[] signature;
|
||||
|
||||
@Constructor
|
||||
public AuthenticationExtensionsDevicePublicKeyOutputs(@Param(1) byte[] devicePublicKey, @Param(2) byte[] signature) {
|
||||
this.devicePublicKey = devicePublicKey;
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getDevicePublicKey() {
|
||||
return devicePublicKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@PublicApi
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private byte[] devicePublicKey;
|
||||
@Nullable
|
||||
private byte[] signature;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder setDevicePublicKey(@Nullable byte[] devicePublicKey) {
|
||||
this.devicePublicKey = devicePublicKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSignature(@Nullable byte[] signature) {
|
||||
this.signature = signature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AuthenticationExtensionsDevicePublicKeyOutputs build() {
|
||||
return new AuthenticationExtensionsDevicePublicKeyOutputs(devicePublicKey, signature);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@PublicApi
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
@PublicApi
|
||||
@NonNull
|
||||
public static AuthenticationExtensionsDevicePublicKeyOutputs deserializeFromBytes(@NonNull byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof AuthenticationExtensionsDevicePublicKeyOutputs)) return false;
|
||||
AuthenticationExtensionsDevicePublicKeyOutputs that = (AuthenticationExtensionsDevicePublicKeyOutputs) o;
|
||||
return Arrays.equals(devicePublicKey, that.devicePublicKey) && Arrays.equals(signature, that.signature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{Arrays.hashCode(devicePublicKey), Arrays.hashCode(signature)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticationExtensionsDevicePublicKeyOutputs").field("devicePublicKey", devicePublicKey != null ? devicePublicKey.length : null).field("signature", signature != null ? signature.length : null).end();
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticationExtensionsDevicePublicKeyOutputs> CREATOR = findCreator(AuthenticationExtensionsDevicePublicKeyOutputs.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticationExtensionsPrfOutputs extends AbstractSafeParcelable {
|
||||
|
||||
@Field(value = 1, getterName = "isEnabled")
|
||||
private final boolean enabled;
|
||||
|
||||
@Field(value = 2, getterName = "getFirst")
|
||||
@Nullable
|
||||
private final byte[] first;
|
||||
|
||||
@Field(value = 3, getterName = "getSecond")
|
||||
@Nullable
|
||||
private final byte[] second;
|
||||
|
||||
@Constructor
|
||||
public AuthenticationExtensionsPrfOutputs(@Param(1) boolean enabled, @Param(2) @Nullable byte[] first, @Param(3) @Nullable byte[] second) {
|
||||
this.enabled = enabled;
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getSecond() {
|
||||
return second;
|
||||
}
|
||||
|
||||
private String b64url(byte[] v) {
|
||||
return Base64.encodeToString(v, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticationExtensionsPrfOutputs> CREATOR = findCreator(AuthenticationExtensionsPrfOutputs.class);
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticationExtensionsPrfOutputs").field("enabled", enabled).field("first", first).field("second", second).end();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This structure contains cryptographic signatures produced by scoped credentials that provides proof of possession
|
||||
* of a private key as well as evidence of user consent to a specific transaction.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticatorAssertionResponse extends AuthenticatorResponse {
|
||||
@Field(value = 2, getterName = "getKeyHandle")
|
||||
@NonNull
|
||||
private byte[] keyHandle;
|
||||
@Field(value = 3, getterName = "getClientDataJSON")
|
||||
@NonNull
|
||||
private byte[] clientDataJSON;
|
||||
@Field(value = 4, getterName = "getAuthenticatorData")
|
||||
@NonNull
|
||||
private byte[] authenticatorData;
|
||||
@Field(value = 5, getterName = "getSignature")
|
||||
@NonNull
|
||||
private byte[] signature;
|
||||
@Field(value = 6, getterName = "getUserHandle")
|
||||
@Nullable
|
||||
private byte[] userHandle;
|
||||
|
||||
private AuthenticatorAssertionResponse() {
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public AuthenticatorAssertionResponse(@Param(2) @NonNull byte[] keyHandle, @Param(3) @NonNull byte[] clientDataJSON, @Param(4) @NonNull byte[] authenticatorData, @Param(5) @NonNull byte[] signature, @Param(6) @Nullable byte[] userHandle) {
|
||||
this.keyHandle = keyHandle;
|
||||
this.clientDataJSON = clientDataJSON;
|
||||
this.authenticatorData = authenticatorData;
|
||||
this.signature = signature;
|
||||
this.userHandle = userHandle;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getAuthenticatorData() {
|
||||
return authenticatorData;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getClientDataJSON() {
|
||||
return clientDataJSON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link PublicKeyCredential#getRawId()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public byte[] getKeyHandle() {
|
||||
return keyHandle;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public byte[] getUserHandle() {
|
||||
return userHandle;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticatorAssertionResponse)) return false;
|
||||
|
||||
AuthenticatorAssertionResponse that = (AuthenticatorAssertionResponse) o;
|
||||
|
||||
if (!Arrays.equals(keyHandle, that.keyHandle)) return false;
|
||||
if (!Arrays.equals(clientDataJSON, that.clientDataJSON)) return false;
|
||||
if (!Arrays.equals(authenticatorData, that.authenticatorData)) return false;
|
||||
if (!Arrays.equals(signature, that.signature)) return false;
|
||||
return Arrays.equals(userHandle, that.userHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{Arrays.hashCode(keyHandle), Arrays.hashCode(clientDataJSON), Arrays.hashCode(authenticatorData), Arrays.hashCode(signature), Arrays.hashCode(userHandle)});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticatorAssertionResponse")
|
||||
.field("keyHandle", keyHandle)
|
||||
.field("clientDataJSON", clientDataJSON)
|
||||
.field("authenticatorData", authenticatorData)
|
||||
.field("signature", signature)
|
||||
.field("userHandle", userHandle)
|
||||
.end();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static AuthenticatorAssertionResponse deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticatorAssertionResponse> CREATOR = findCreator(AuthenticatorAssertionResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a newly-created scoped credential, aka the response from a registration request.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticatorAttestationResponse extends AuthenticatorResponse {
|
||||
@Field(value = 2, getterName = "getKeyHandle")
|
||||
@NonNull
|
||||
private byte[] keyHandle;
|
||||
@Field(value = 3, getterName = "getClientDataJSON")
|
||||
@NonNull
|
||||
private byte[] clientDataJSON;
|
||||
@Field(value = 4, getterName = "getAttestationObject")
|
||||
@NonNull
|
||||
private byte[] attestationObject;
|
||||
@Field(value = 5, getterName = "getTransports")
|
||||
@NonNull
|
||||
private String[] transports;
|
||||
|
||||
private AuthenticatorAttestationResponse() {
|
||||
}
|
||||
|
||||
@Hide
|
||||
@Constructor
|
||||
public AuthenticatorAttestationResponse(@Param(2) @NonNull byte[] keyHandle, @Param(3) @NonNull byte[] clientDataJSON, @Param(4) @NonNull byte[] attestationObject, @Param(5) @NonNull String[] transports) {
|
||||
this.keyHandle = keyHandle;
|
||||
this.clientDataJSON = clientDataJSON;
|
||||
this.attestationObject = attestationObject;
|
||||
this.transports = transports;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getAttestationObject() {
|
||||
return attestationObject;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getClientDataJSON() {
|
||||
return clientDataJSON;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link PublicKeyCredential#getRawId()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
@NonNull
|
||||
public byte[] getKeyHandle() {
|
||||
return keyHandle;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String[] getTransports() {
|
||||
return transports;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticatorAttestationResponse)) return false;
|
||||
|
||||
AuthenticatorAttestationResponse that = (AuthenticatorAttestationResponse) o;
|
||||
|
||||
if (!Arrays.equals(keyHandle, that.keyHandle)) return false;
|
||||
if (!Arrays.equals(clientDataJSON, that.clientDataJSON)) return false;
|
||||
if (!Arrays.equals(attestationObject, that.attestationObject)) return false;
|
||||
if (!Arrays.equals(transports, that.transports)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{Arrays.hashCode(keyHandle), Arrays.hashCode(clientDataJSON), Arrays.hashCode(attestationObject), Arrays.hashCode(transports)});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticatorAttestationResponse")
|
||||
.field("keyHandle", keyHandle)
|
||||
.field("clientDataJSON", clientDataJSON)
|
||||
.field("attestationObject", attestationObject)
|
||||
.field("transports", transports)
|
||||
.end();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static AuthenticatorAttestationResponse deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticatorAttestationResponse> CREATOR = findCreator(AuthenticatorAttestationResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The response after an error occurred.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticatorErrorResponse extends AuthenticatorResponse {
|
||||
@Field(value = 2, getterName = "getErrorCode")
|
||||
@NonNull
|
||||
private ErrorCode errorCode;
|
||||
@Field(value = 3, getterName = "getErrorMessage")
|
||||
@Nullable
|
||||
private String errorMessage;
|
||||
@Field(value = 4, getterName = "getInternalErrorCode")
|
||||
private int internalErrorCode;
|
||||
|
||||
private AuthenticatorErrorResponse() {
|
||||
}
|
||||
|
||||
@Hide
|
||||
public AuthenticatorErrorResponse(@NonNull ErrorCode errorCode, @Nullable String errorMessage) {
|
||||
this.errorCode = errorCode;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@Constructor
|
||||
AuthenticatorErrorResponse(@Param(2) @NonNull ErrorCode errorCode, @Param(3) @Nullable String errorMessage, @Param(4) int internalErrorCode) {
|
||||
this.errorCode = errorCode;
|
||||
this.errorMessage = errorMessage;
|
||||
this.internalErrorCode = internalErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getClientDataJSON() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public ErrorCode getErrorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
public int getErrorCodeAsInt() {
|
||||
return errorCode.getCode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getErrorMessage() {
|
||||
return errorMessage;
|
||||
}
|
||||
|
||||
@Hide
|
||||
public int getInternalErrorCode() {
|
||||
return internalErrorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticatorErrorResponse)) return false;
|
||||
|
||||
AuthenticatorErrorResponse that = (AuthenticatorErrorResponse) o;
|
||||
|
||||
if (errorCode != null ? !errorCode.equals(that.errorCode) : that.errorCode != null) return false;
|
||||
if (errorMessage != null ? !errorMessage.equals(that.errorMessage) : that.errorMessage != null) return false;
|
||||
if (internalErrorCode != that.internalErrorCode) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{errorCode, errorMessage, internalErrorCode});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticatorErrorResponse")
|
||||
.value(errorCode.name())
|
||||
.value(errorMessage)
|
||||
.end();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static AuthenticatorErrorResponse deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticatorErrorResponse> CREATOR = findCreator(AuthenticatorErrorResponse.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
|
||||
/**
|
||||
* Authenticators respond to relying party requests by returning an object derived from this interface.
|
||||
*/
|
||||
public abstract class AuthenticatorResponse extends AbstractSafeParcelable {
|
||||
@NonNull
|
||||
public abstract byte[] getClientDataJSON();
|
||||
|
||||
@NonNull
|
||||
public abstract byte[] serializeToBytes();
|
||||
}
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Relying Parties may use {@link AuthenticatorSelectionCriteria} to specify their requirements regarding authenticator
|
||||
* attributes.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class AuthenticatorSelectionCriteria extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getAttachment")
|
||||
@Nullable
|
||||
private Attachment attachment;
|
||||
@Field(value = 3, getterName = "getRequireResidentKey")
|
||||
@Nullable
|
||||
private Boolean requireResidentKey;
|
||||
@Field(value = 4, getterName = "getRequireUserVerification")
|
||||
@Nullable
|
||||
private UserVerificationRequirement requireUserVerification;
|
||||
@Field(value = 5, getterName = "getResidentKeyRequirement")
|
||||
@Nullable
|
||||
private ResidentKeyRequirement residentKeyRequirement;
|
||||
|
||||
@Constructor
|
||||
AuthenticatorSelectionCriteria(@Param(2) @Nullable Attachment attachment, @Param(3) @Nullable Boolean requireResidentKey, @Param(4) @Nullable UserVerificationRequirement requireUserVerification, @Param(5) @Nullable ResidentKeyRequirement residentKeyRequirement) {
|
||||
this.attachment = attachment;
|
||||
this.requireResidentKey = requireResidentKey;
|
||||
this.requireUserVerification = requireUserVerification;
|
||||
this.residentKeyRequirement = residentKeyRequirement;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Attachment getAttachment() {
|
||||
return attachment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAttachmentAsString() {
|
||||
if (attachment == null) return null;
|
||||
return attachment.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Boolean getRequireResidentKey() {
|
||||
return requireResidentKey;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ResidentKeyRequirement getResidentKeyRequirement() {
|
||||
return residentKeyRequirement;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getResidentKeyRequirementAsString() {
|
||||
if (residentKeyRequirement == null) return null;
|
||||
return residentKeyRequirement.toString();
|
||||
}
|
||||
|
||||
@Hide
|
||||
@Nullable
|
||||
public UserVerificationRequirement getRequireUserVerification() {
|
||||
return requireUserVerification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof AuthenticatorSelectionCriteria)) return false;
|
||||
|
||||
AuthenticatorSelectionCriteria that = (AuthenticatorSelectionCriteria) o;
|
||||
|
||||
if (attachment != that.attachment) return false;
|
||||
if (requireResidentKey != null ? !requireResidentKey.equals(that.requireResidentKey) : that.requireResidentKey != null) return false;
|
||||
if (requireUserVerification != that.requireUserVerification) return false;
|
||||
if (residentKeyRequirement != that.residentKeyRequirement) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{attachment, requireResidentKey, requireUserVerification});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("AuthenticatorSelectionCriteria")
|
||||
.field("attachment", attachment)
|
||||
.field("requireResidentKey", requireResidentKey)
|
||||
.field("requireUserVerification", requireUserVerification)
|
||||
.field("residentKeyRequirement", residentKeyRequirement)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link AuthenticatorSelectionCriteria}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@Nullable
|
||||
private Attachment attachment;
|
||||
@Nullable
|
||||
private Boolean requireResidentKey;
|
||||
@Nullable
|
||||
private ResidentKeyRequirement residentKeyRequirement;
|
||||
|
||||
/**
|
||||
* Sets the attachment to use for this session.
|
||||
*/
|
||||
public Builder setAttachment(@Nullable Attachment attachment) {
|
||||
this.attachment = attachment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the key created will be a resident key.
|
||||
*/
|
||||
public Builder setRequireResidentKey(@Nullable Boolean requireResidentKey) {
|
||||
this.requireResidentKey = requireResidentKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets residentKeyRequirement
|
||||
*/
|
||||
public Builder setResidentKeyRequirement(@Nullable ResidentKeyRequirement residentKeyRequirement) {
|
||||
this.residentKeyRequirement = residentKeyRequirement;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public AuthenticatorSelectionCriteria build() {
|
||||
return new AuthenticatorSelectionCriteria(attachment, requireResidentKey, null, residentKeyRequirement);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<AuthenticatorSelectionCriteria> CREATOR = findCreator(AuthenticatorSelectionCriteria.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Parameters to a make credential request from a Web browser.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class BrowserPublicKeyCredentialCreationOptions extends BrowserRequestOptions {
|
||||
@Field(value = 2, getterName = "getPublicKeyCredentialCreationOptions")
|
||||
@NonNull
|
||||
private PublicKeyCredentialCreationOptions delegate;
|
||||
@Field(value = 3, getterName = "getOrigin")
|
||||
@NonNull
|
||||
private Uri origin;
|
||||
@Field(value = 4, getterName = "getClientDataHash")
|
||||
@Nullable
|
||||
private byte[] clientDataHash;
|
||||
|
||||
@Constructor
|
||||
BrowserPublicKeyCredentialCreationOptions(@Param(2) @NonNull PublicKeyCredentialCreationOptions delegate, @Param(3) @NonNull Uri origin, @Param(4) @Nullable byte[] clientDataHash) {
|
||||
this.delegate = delegate;
|
||||
this.origin = origin;
|
||||
this.clientDataHash = clientDataHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AuthenticationExtensions getAuthenticationExtensions() {
|
||||
return delegate.getAuthenticationExtensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getChallenge() {
|
||||
return delegate.getChallenge();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public byte[] getClientDataHash() {
|
||||
return clientDataHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Uri getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialCreationOptions getPublicKeyCredentialCreationOptions() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Integer getRequestId() {
|
||||
return delegate.getRequestId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Double getTimeoutSeconds() {
|
||||
return delegate.getTimeoutSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TokenBinding getTokenBinding() {
|
||||
return delegate.getTokenBinding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof BrowserPublicKeyCredentialCreationOptions)) return false;
|
||||
|
||||
BrowserPublicKeyCredentialCreationOptions that = (BrowserPublicKeyCredentialCreationOptions) o;
|
||||
|
||||
if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
|
||||
if (origin != null ? !origin.equals(that.origin) : that.origin != null) return false;
|
||||
return Arrays.equals(clientDataHash, that.clientDataHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{delegate, origin, Arrays.hashCode(clientDataHash)});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("BrowserPublicKeyCredentialCreationOptions")
|
||||
.value(delegate)
|
||||
.field("origin", origin)
|
||||
.field("clientDataHash", clientDataHash)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link BrowserPublicKeyCredentialCreationOptions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@NonNull
|
||||
private PublicKeyCredentialCreationOptions delegate;
|
||||
@NonNull
|
||||
private Uri origin;
|
||||
@Nullable
|
||||
private byte[] clientDataHash;
|
||||
|
||||
/**
|
||||
* The constructor of {@link BrowserPublicKeyCredentialCreationOptions.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a clientDataHash value to sign over in place of assembling and hashing clientDataJSON during the
|
||||
* signature request.
|
||||
* <p>
|
||||
* Note: This is optional and only provided for contexts where the unhashed information necessary to assemble
|
||||
* WebAuthn clientDataJSON is not available. If set, the resulting {@link AuthenticatorAssertionResponse} will
|
||||
* return an invalid value for {@code getClientDataJSON()}. Generally, browser clients should use
|
||||
* {@link PublicKeyCredentialCreationOptions.Builder#setChallenge(byte[])} instead.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public BrowserPublicKeyCredentialCreationOptions.Builder setClientDataHash(@NonNull byte[] clientDataHash) {
|
||||
this.clientDataHash = clientDataHash;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the origin on whose behalf the calling browser is requesting a registration operation.
|
||||
*/
|
||||
public BrowserPublicKeyCredentialCreationOptions.Builder setOrigin(@NonNull Uri origin) {
|
||||
this.origin = origin;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameters to dictate the client behavior during this registration session.
|
||||
*/
|
||||
public BrowserPublicKeyCredentialCreationOptions.Builder setPublicKeyCredentialCreationOptions(@NonNull PublicKeyCredentialCreationOptions publicKeyCredentialCreationOptions) {
|
||||
this.delegate = publicKeyCredentialCreationOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link BrowserPublicKeyCredentialCreationOptions} object.
|
||||
*/
|
||||
@NonNull
|
||||
public BrowserPublicKeyCredentialCreationOptions build() {
|
||||
return new BrowserPublicKeyCredentialCreationOptions(delegate, origin, clientDataHash);
|
||||
}
|
||||
}
|
||||
|
||||
public static BrowserPublicKeyCredentialCreationOptions deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<BrowserPublicKeyCredentialCreationOptions> CREATOR = findCreator(BrowserPublicKeyCredentialCreationOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Parameters for a signature request from a Web Browser.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class BrowserPublicKeyCredentialRequestOptions extends BrowserRequestOptions {
|
||||
@Field(value = 2, getterName = "getPublicKeyCredentialRequestOptions")
|
||||
@NonNull
|
||||
private PublicKeyCredentialRequestOptions delegate;
|
||||
@Field(value = 3, getterName = "getOrigin")
|
||||
@NonNull
|
||||
private Uri origin;
|
||||
@Field(value = 4, getterName = "getClientDataHash")
|
||||
@Nullable
|
||||
private byte[] clientDataHash;
|
||||
|
||||
@Constructor
|
||||
BrowserPublicKeyCredentialRequestOptions(@Param(2) @NonNull PublicKeyCredentialRequestOptions delegate, @Param(3) @NonNull Uri origin, @Param(4) @Nullable byte[] clientDataHash) {
|
||||
this.delegate = delegate;
|
||||
this.origin = origin;
|
||||
this.clientDataHash = clientDataHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AuthenticationExtensions getAuthenticationExtensions() {
|
||||
return delegate.getAuthenticationExtensions();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getChallenge() {
|
||||
return delegate.getChallenge();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public byte[] getClientDataHash() {
|
||||
return clientDataHash;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Uri getOrigin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialRequestOptions getPublicKeyCredentialRequestOptions() {
|
||||
return delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Integer getRequestId() {
|
||||
return delegate.getRequestId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Double getTimeoutSeconds() {
|
||||
return delegate.getTimeoutSeconds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TokenBinding getTokenBinding() {
|
||||
return delegate.getTokenBinding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof BrowserPublicKeyCredentialRequestOptions)) return false;
|
||||
|
||||
BrowserPublicKeyCredentialRequestOptions that = (BrowserPublicKeyCredentialRequestOptions) o;
|
||||
|
||||
if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false;
|
||||
if (origin != null ? !origin.equals(that.origin) : that.origin != null) return false;
|
||||
return Arrays.equals(clientDataHash, that.clientDataHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{delegate, origin, Arrays.hashCode(clientDataHash)});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("BrowserPublicKeyCredentialRequestOptions")
|
||||
.value(delegate)
|
||||
.field("origin", origin)
|
||||
.field("clientDataHash", clientDataHash)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link BrowserPublicKeyCredentialRequestOptions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@NonNull
|
||||
private PublicKeyCredentialRequestOptions delegate;
|
||||
@NonNull
|
||||
private Uri origin;
|
||||
@Nullable
|
||||
private byte[] clientDataHash;
|
||||
|
||||
/**
|
||||
* The constructor of {@link BrowserPublicKeyCredentialRequestOptions.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a clientDataHash value to sign over in place of assembling and hashing clientDataJSON during the
|
||||
* signature request.
|
||||
* <p>
|
||||
* Note: This is optional and only provided for contexts where the unhashed information necessary to assemble
|
||||
* WebAuthn clientDataJSON is not available. If set, the resulting {@link AuthenticatorAssertionResponse} will
|
||||
* return an invalid value for {@code getClientDataJSON()}. Generally, browser clients should use
|
||||
* {@link PublicKeyCredentialRequestOptions.Builder#setChallenge(byte[])} instead.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Builder setClientDataHash(@NonNull byte[] clientDataHash) {
|
||||
this.clientDataHash = clientDataHash;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the origin on whose behalf the calling browser is requesting an authentication operation.
|
||||
*/
|
||||
public Builder setOrigin(@NonNull Uri origin) {
|
||||
this.origin = origin;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the parameters to dictate client behavior during this authentication session.
|
||||
*/
|
||||
public Builder setPublicKeyCredentialRequestOptions(@NonNull PublicKeyCredentialRequestOptions publicKeyCredentialRequestOptions) {
|
||||
this.delegate = publicKeyCredentialRequestOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link BrowserPublicKeyCredentialRequestOptions} object.
|
||||
*/
|
||||
@NonNull
|
||||
public BrowserPublicKeyCredentialRequestOptions build() {
|
||||
return new BrowserPublicKeyCredentialRequestOptions(delegate, origin, clientDataHash);
|
||||
}
|
||||
}
|
||||
|
||||
public static BrowserPublicKeyCredentialRequestOptions deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<BrowserPublicKeyCredentialRequestOptions> CREATOR = findCreator(BrowserPublicKeyCredentialRequestOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An abstract class representing browser-based request parameters.
|
||||
*/
|
||||
public abstract class BrowserRequestOptions extends RequestOptions {
|
||||
/**
|
||||
* Gets value of the client data hash.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract byte[] getClientDataHash();
|
||||
|
||||
@NonNull
|
||||
public abstract Uri getOrigin();
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
public class COSEAlgorithmIdentifier implements Parcelable {
|
||||
private Algorithm algorithm;
|
||||
|
||||
private COSEAlgorithmIdentifier() {
|
||||
}
|
||||
|
||||
private COSEAlgorithmIdentifier(Algorithm algorithm) {
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static COSEAlgorithmIdentifier fromCoseValue(int value) throws UnsupportedAlgorithmIdentifierException {
|
||||
if (value == RSAAlgorithm.LEGACY_RS1.getAlgoValue()) return new COSEAlgorithmIdentifier(RSAAlgorithm.RS1);
|
||||
for (RSAAlgorithm algorithm : RSAAlgorithm.values()) {
|
||||
if (algorithm.getAlgoValue() == value) return new COSEAlgorithmIdentifier(algorithm);
|
||||
}
|
||||
for (EC2Algorithm algorithm : EC2Algorithm.values()) {
|
||||
if (algorithm.getAlgoValue() == value) return new COSEAlgorithmIdentifier(algorithm);
|
||||
}
|
||||
throw new UnsupportedAlgorithmIdentifierException(value);
|
||||
}
|
||||
|
||||
public int toCoseValue() {
|
||||
return algorithm.getAlgoValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("COSEAlgorithmIdentifier")
|
||||
.value(algorithm)
|
||||
.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(algorithm.getAlgoValue());
|
||||
}
|
||||
|
||||
public static final Creator<COSEAlgorithmIdentifier> CREATOR = new Creator<COSEAlgorithmIdentifier>() {
|
||||
@Override
|
||||
public COSEAlgorithmIdentifier createFromParcel(Parcel in) {
|
||||
try {
|
||||
return fromCoseValue(in.readInt());
|
||||
} catch (UnsupportedAlgorithmIdentifierException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public COSEAlgorithmIdentifier[] newArray(int size) {
|
||||
return new COSEAlgorithmIdentifier[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static class UnsupportedAlgorithmIdentifierException extends Exception {
|
||||
public UnsupportedAlgorithmIdentifierException(int algId) {
|
||||
super("Algorithm with COSE value " + algId + " not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
@SafeParcelable.Class
|
||||
public class CableAuthenticationData extends AbstractSafeParcelable {
|
||||
@Field(1)
|
||||
long version;
|
||||
@Field(2)
|
||||
@NonNull
|
||||
byte[] clientEid;
|
||||
@Field(3)
|
||||
@NonNull
|
||||
byte[] authenticatorEid;
|
||||
@Field(4)
|
||||
@NonNull
|
||||
byte[] sessionPreKey;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CableAuthenticationData> CREATOR = findCreator(CableAuthenticationData.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@SafeParcelable.Class
|
||||
public class CableAuthenticationExtension extends AbstractSafeParcelable {
|
||||
@Field(1)
|
||||
@NonNull
|
||||
List<CableAuthenticationData> cableAuthentication;
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CableAuthenticationExtension> CREATOR = findCreator(CableAuthenticationExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class CredentialPropertiesOutput extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isResidentKey")
|
||||
private final boolean residentKey;
|
||||
|
||||
@Constructor
|
||||
public CredentialPropertiesOutput(@Param(1) boolean residentKey) {
|
||||
this.residentKey = residentKey;
|
||||
}
|
||||
|
||||
public boolean isResidentKey() {
|
||||
return residentKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof CredentialPropertiesOutput)) return false;
|
||||
CredentialPropertiesOutput that = (CredentialPropertiesOutput) o;
|
||||
return residentKey == that.residentKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{residentKey});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<CredentialPropertiesOutput> CREATOR = findCreator(CredentialPropertiesOutput.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class DevicePublicKeyExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isDevicePublicKey")
|
||||
private final boolean devicePublicKey;
|
||||
|
||||
@Constructor
|
||||
public DevicePublicKeyExtension(@Param(1) boolean devicePublicKey) {
|
||||
this.devicePublicKey = devicePublicKey;
|
||||
}
|
||||
|
||||
public boolean isDevicePublicKey() {
|
||||
return devicePublicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("DevicePublicKeyExtension").field("isDevicePublicKey", devicePublicKey).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<DevicePublicKeyExtension> CREATOR = AbstractSafeParcelable.findCreator(DevicePublicKeyExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Enum values to be passed into DevicePublicKeyExtension. This tells the authenticator what to return for the DPK extension object.
|
||||
* <p>
|
||||
* These values are placeholders until the final spec is determined. For now,
|
||||
* <ul>
|
||||
* <li>NONE is to not request a DPK.</li>
|
||||
* <li>DIRECT is to request a DPK.</li>
|
||||
* <li>INDIRECT has no function at this time.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public @interface DevicePublicKeyStringDef {
|
||||
@NonNull
|
||||
String NONE = "none";
|
||||
@NonNull
|
||||
String INDIRECT = "indirect";
|
||||
@NonNull
|
||||
String DIRECT = "direct";
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Algorithm names and COSE identifiers for EC2 (public) keys.
|
||||
*/
|
||||
@PublicApi
|
||||
public enum EC2Algorithm implements Algorithm {
|
||||
/**
|
||||
* ECDH-ES with HKDF-SHA-256
|
||||
*/
|
||||
ECDH_HKDF_256(-25),
|
||||
/**
|
||||
* EdDSA with Ed25519
|
||||
*/
|
||||
ED25519(-8),
|
||||
/**
|
||||
* TPM_ECC_BN_P256 curve w/ SHA-256
|
||||
*/
|
||||
ED256(-260),
|
||||
/**
|
||||
* ECC_BN_ISOP512 curve w/ SHA-512
|
||||
*/
|
||||
ED512(-261),
|
||||
/**
|
||||
* ECDSA w/ SHA-256
|
||||
*/
|
||||
ES256(-7),
|
||||
/**
|
||||
* ECDSA w/ SHA-384
|
||||
*/
|
||||
ES384(-35),
|
||||
/**
|
||||
* ECDSA w/ SHA-512
|
||||
*/
|
||||
ES512(-36);
|
||||
|
||||
private final int algoValue;
|
||||
|
||||
EC2Algorithm(int algoValue) {
|
||||
this.algoValue = algoValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlgoValue() {
|
||||
return algoValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Error codes that are referenced by WebAuthn spec.
|
||||
*/
|
||||
@PublicApi
|
||||
public enum ErrorCode implements Parcelable {
|
||||
/**
|
||||
* The operation is not supported.
|
||||
*/
|
||||
NOT_SUPPORTED_ERR(9),
|
||||
/**
|
||||
* The object is in an invalid state.
|
||||
*/
|
||||
INVALID_STATE_ERR(11),
|
||||
/**
|
||||
* The operation is insecure.
|
||||
*/
|
||||
SECURITY_ERR(18),
|
||||
/**
|
||||
* A network error occurred.
|
||||
*/
|
||||
NETWORK_ERR(19),
|
||||
/**
|
||||
* The operation was aborted.
|
||||
*/
|
||||
ABORT_ERR(20),
|
||||
/**
|
||||
* The operation timed out.
|
||||
*/
|
||||
TIMEOUT_ERR(23),
|
||||
/**
|
||||
* The encoding operation (either encoded or decoding) failed.
|
||||
*/
|
||||
ENCODING_ERR(27),
|
||||
/**
|
||||
* The operation failed for an unknown transient reason.
|
||||
*/
|
||||
UNKNOWN_ERR(28),
|
||||
/**
|
||||
* A mutation operation in a transaction failed because a constraint was not satisfied.
|
||||
*/
|
||||
CONSTRAINT_ERR(29),
|
||||
/**
|
||||
* Provided data is inadequate.
|
||||
*/
|
||||
DATA_ERR(30),
|
||||
/**
|
||||
* The request is not allowed by the user agent or the platform in the current context, possibly because the user
|
||||
* denied permission.
|
||||
*/
|
||||
NOT_ALLOWED_ERR(35),
|
||||
/**
|
||||
* The authenticator violates the privacy requirements of the {@code AttestationStatementType} it is using.
|
||||
*/
|
||||
ATTESTATION_NOT_PRIVATE_ERR(36);
|
||||
|
||||
private int code;
|
||||
|
||||
ErrorCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
@Hide
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(code);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static ErrorCode toErrorCode(int errorCode) throws UnsupportedErrorCodeException {
|
||||
for (ErrorCode value : values()) {
|
||||
if (value.code == errorCode) return value;
|
||||
}
|
||||
throw new UnsupportedErrorCodeException(errorCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized error code is encountered.
|
||||
*/
|
||||
public static class UnsupportedErrorCodeException extends Exception {
|
||||
/**
|
||||
* Constructor for the {@link ErrorCode.UnsupportedErrorCodeException}.
|
||||
*/
|
||||
public UnsupportedErrorCodeException(int errorCode) {
|
||||
super("Error code " + errorCode + " is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final Creator<ErrorCode> CREATOR = new Creator<ErrorCode>() {
|
||||
@Override
|
||||
public ErrorCode createFromParcel(Parcel source) {
|
||||
try {
|
||||
return ErrorCode.toErrorCode(source.readInt());
|
||||
} catch (UnsupportedErrorCodeException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ErrorCode[] newArray(int size) {
|
||||
return new ErrorCode[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Extension for FIDO appId, to support U2F backward compatibility in FIDO2 assertion requests.
|
||||
* <p>
|
||||
* This authentication extension allows Relying Parties that have previously registered a credential using the legacy
|
||||
* FIDO U2F APIs to request an assertion. Specifically, this extension allows Relying Parties to specify an appId to
|
||||
* overwrite the computed rpId for U2F authenticators.
|
||||
* <p>
|
||||
* Note that this extension is only valid if used during the get() call; other usage should result in client error.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class FidoAppIdExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getAppId")
|
||||
@NonNull
|
||||
private String appId;
|
||||
|
||||
private FidoAppIdExtension() {
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public FidoAppIdExtension(@Param(2) @NonNull String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof FidoAppIdExtension)) return false;
|
||||
|
||||
FidoAppIdExtension that = (FidoAppIdExtension) o;
|
||||
|
||||
return appId.equals(that.appId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{appId});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<FidoAppIdExtension> CREATOR = findCreator(FidoAppIdExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Contains the attributes of a single FIDO credential that are returned to the caller in response to a
|
||||
* {@link Fido2PrivilegedApiClient#getCredentialList(String)} call.
|
||||
*/
|
||||
@SafeParcelable.Class
|
||||
public class FidoCredentialDetails extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUserName")
|
||||
@Nullable
|
||||
private String userName;
|
||||
@Field(value = 2, getterName = "getUserDisplayName")
|
||||
@Nullable
|
||||
private String userDisplayName;
|
||||
@Field(value = 3, getterName = "getUserId")
|
||||
@Nullable
|
||||
private byte[] userId;
|
||||
@Field(value = 4, getterName = "getCredentialId")
|
||||
@NonNull
|
||||
private byte[] credentialId;
|
||||
@Field(value = 5, getterName = "getIsDiscoverable")
|
||||
private boolean discoverable;
|
||||
@Field(value = 6, getterName = "getIsPaymentCredential")
|
||||
private boolean paymentCredential;
|
||||
|
||||
private FidoCredentialDetails() {
|
||||
}
|
||||
|
||||
@Constructor
|
||||
FidoCredentialDetails(@Nullable @Param(1) String userName, @Nullable @Param(2) String userDisplayName, @Nullable @Param(3) byte[] userId, @NonNull @Param(4) byte[] credentialId, @Param(5) boolean discoverable, @Param(6) boolean paymentCredential) {
|
||||
this.userName = userName;
|
||||
this.userDisplayName = userDisplayName;
|
||||
this.userId = userId;
|
||||
this.credentialId = credentialId;
|
||||
this.discoverable = discoverable;
|
||||
this.paymentCredential = paymentCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* De-serializes the {@link FidoCredentialDetails} from bytes, reversing {@link #serializeToBytes()}.
|
||||
*
|
||||
* @return The deserialized {@link FidoCredentialDetails}.
|
||||
*/
|
||||
@NonNull
|
||||
public static FidoCredentialDetails deserializeFromBytes(@NonNull byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credential's credential ID.
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] getCredentialId() {
|
||||
return credentialId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the credential is discoverable.
|
||||
*/
|
||||
public boolean getIsDiscoverable() {
|
||||
return discoverable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the credential is for payments.
|
||||
*/
|
||||
public boolean getIsPaymentCredential() {
|
||||
return paymentCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last used time in Unix Epoch Millis.
|
||||
*/
|
||||
public long getLastUsedTime() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credential's user display name.
|
||||
*/
|
||||
@Nullable
|
||||
public String getUserDisplayName() {
|
||||
return userDisplayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credential's user ID.
|
||||
*/
|
||||
@Nullable
|
||||
public byte[] getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the credential's user name.
|
||||
*/
|
||||
@Nullable
|
||||
public String getUserName() {
|
||||
return this.userName;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(new Object[]{this.userName, this.userDisplayName, this.userId, this.credentialId, this.discoverable, this.paymentCredential});
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the {@link FidoCredentialDetails} to bytes. Use {@link #deserializeFromBytes(byte[])} to deserialize.
|
||||
*
|
||||
* @return the serialized byte array.
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
CREATOR.writeToParcel(this, out, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<FidoCredentialDetails> CREATOR = findCreator(FidoCredentialDetails.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class GoogleMultiAssertionExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isRequestForMultiAssertion")
|
||||
private final boolean requestForMultiAssertion;
|
||||
|
||||
@Constructor
|
||||
public GoogleMultiAssertionExtension(@Param(1) boolean requestForMultiAssertion) {
|
||||
this.requestForMultiAssertion = requestForMultiAssertion;
|
||||
}
|
||||
|
||||
public boolean isRequestForMultiAssertion() {
|
||||
return requestForMultiAssertion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GoogleMultiAssertionExtension> CREATOR = AbstractSafeParcelable.findCreator(GoogleMultiAssertionExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class GoogleSessionIdExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getSessionId")
|
||||
private final long sessionId;
|
||||
|
||||
@Constructor
|
||||
public GoogleSessionIdExtension(@Param(1) long sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
public long getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("GoogleSessionIdExtension").field("sessionId", sessionId).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GoogleSessionIdExtension> CREATOR = AbstractSafeParcelable.findCreator(GoogleSessionIdExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class GoogleSilentVerificationExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isSilentVerification")
|
||||
private final boolean silentVerification;
|
||||
|
||||
@Constructor
|
||||
public GoogleSilentVerificationExtension(@Param(1) boolean silentVerification) {
|
||||
this.silentVerification = silentVerification;
|
||||
}
|
||||
|
||||
public boolean isSilentVerification() {
|
||||
return silentVerification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("GoogleSilentVerificationExtension").field("silentVerification", silentVerification).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GoogleSilentVerificationExtension> CREATOR = AbstractSafeParcelable.findCreator(GoogleSilentVerificationExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class GoogleThirdPartyPaymentExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isThirdPartyPayment")
|
||||
private final boolean thirdPartyPayment;
|
||||
|
||||
@Constructor
|
||||
public GoogleThirdPartyPaymentExtension(@Param(1) boolean thirdPartyPayment) {
|
||||
this.thirdPartyPayment = thirdPartyPayment;
|
||||
}
|
||||
|
||||
public boolean isThirdPartyPayment() {
|
||||
return thirdPartyPayment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("GoogleThirdPartyPaymentExtension").field("thirdPartyPayment", thirdPartyPayment).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GoogleThirdPartyPaymentExtension> CREATOR = AbstractSafeParcelable.findCreator(GoogleThirdPartyPaymentExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class GoogleTunnelServerIdExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getTunnelServerId")
|
||||
@NonNull
|
||||
private final String tunnelServerId;
|
||||
|
||||
@Constructor
|
||||
public GoogleTunnelServerIdExtension(@Param(1) @NonNull String tunnelServerId) {
|
||||
this.tunnelServerId = tunnelServerId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getTunnelServerId() {
|
||||
return tunnelServerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("GoogleTunnelServerIdExtension").field("tunnelServerId", tunnelServerId).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<GoogleTunnelServerIdExtension> CREATOR = AbstractSafeParcelable.findCreator(GoogleTunnelServerIdExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class HmacSecretExtension extends AbstractSafeParcelable {
|
||||
|
||||
@Field(value = 1, getterName = "getCoseKeyAgreement")
|
||||
private final byte[] coseKeyAgreement;
|
||||
|
||||
@Field(value = 2, getterName = "getSaltEnc")
|
||||
private final byte[] saltEnc;
|
||||
|
||||
@Field(value = 3, getterName = "getSaltAuth")
|
||||
private final byte[] saltAuth;
|
||||
|
||||
@Field(value = 4, getterName = "getPinUvAuthProtocol")
|
||||
private final int pinUvAuthProtocol;
|
||||
|
||||
@Constructor
|
||||
public HmacSecretExtension(@Param(1) byte[] coseKeyAgreement, @Param(2) byte[] saltEnc, @Param(3) byte[] saltAuth, @Param(4) int pinUvAuthProtocol) {
|
||||
this.coseKeyAgreement = coseKeyAgreement;
|
||||
this.saltEnc = saltEnc;
|
||||
this.saltAuth = saltAuth;
|
||||
this.pinUvAuthProtocol = pinUvAuthProtocol;
|
||||
}
|
||||
|
||||
public byte[] getCoseKeyAgreement() {
|
||||
return coseKeyAgreement;
|
||||
}
|
||||
|
||||
public byte[] getSaltEnc() {
|
||||
return saltEnc;
|
||||
}
|
||||
|
||||
public byte[] getSaltAuth() {
|
||||
return saltAuth;
|
||||
}
|
||||
|
||||
public int getPinUvAuthProtocol() {
|
||||
return pinUvAuthProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("HmacSecretExtension").field("coseKeyAgreement", coseKeyAgreement == null ? "" : coseKeyAgreement.length).field("saltEnc", saltEnc == null ? "" : saltEnc.length).field("saltAuth", saltAuth == null ? "" : saltAuth.length).field("pinUvAuthProtocol", pinUvAuthProtocol).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<HmacSecretExtension> CREATOR = AbstractSafeParcelable.findCreator(HmacSecretExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
/**
|
||||
* The method used by the authenticator to protect the FIDO registration private key material. Available values are
|
||||
* defined in Section 3.2 Key Protection Types.
|
||||
*/
|
||||
public final class KeyProtectionTypes {
|
||||
/**
|
||||
* This flag must be set if the authenticator uses software-based key management. Exclusive in authenticator
|
||||
* metadata with KEY_PROTECTION_HARDWARE, KEY_PROTECTION_TEE, KEY_PROTECTION_SECURE_ELEMENT.
|
||||
*/
|
||||
public static final short KEY_PROTECTION_SOFTWARE = 1;
|
||||
/**
|
||||
* This flag should be set if the authenticator uses hardware-based key management. Exclusive in authenticator
|
||||
* metadata with KEY_PROTECTION_SOFTWARE.
|
||||
*/
|
||||
public static final short KEY_PROTECTION_HARDWARE = 2;
|
||||
/**
|
||||
* This flag should be set if the authenticator uses the Trusted Execution Environment for key management. In
|
||||
* authenticator metadata, this flag should be set in conjunction with KEY_PROTECTION_HARDWARE. Mutually exclusive
|
||||
* in authenticator metadata with KEY_PROTECTION_SOFTWARE, KEY_PROTECTION_SECURE_ELEMENT.
|
||||
*/
|
||||
public static final short KEY_PROTECTION_TEE = 4;
|
||||
/**
|
||||
* This flag should be set if the authenticator uses a Secure Element for key management. In authenticator metadata,
|
||||
* this flag should be set in conjunction with KEY_PROTECTION_HARDWARE. Mutually exclusive in authenticator metadata
|
||||
* with KEY_PROTECTION_TEE, KEY_PROTECTION_SOFTWARE.
|
||||
*/
|
||||
public static final short KEY_PROTECTION_SECURE_ELEMENT = 8;
|
||||
/**
|
||||
* This flag must be set if the authenticator does not store (wrapped) UAuth keys at the client, but relies on a
|
||||
* server-provided key handle. This flag must be set in conjunction with one of the other KEY_PROTECTION flags to
|
||||
* indicate how the local key handle wrapping key and operations are protected. Servers may unset this flag in
|
||||
* authenticator policy if they are not prepared to store and return key handles, for example, if they have a
|
||||
* requirement to respond indistinguishably to authentication attempts against userIDs that do and do not exist.
|
||||
* Refer to for more details.
|
||||
*/
|
||||
public static final short KEY_PROTECTION_REMOTE_HANDLE = 16;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
/**
|
||||
* The method used by the authenticator to protect the matcher that performs user verification. Available values are
|
||||
* defined in Section 3.3 Matcher Protection Types.
|
||||
*/
|
||||
public final class MatcherProtectionTypes {
|
||||
/**
|
||||
* This flag must be set if the authenticator's matcher is running in software. Exclusive in authenticator metadata
|
||||
* with MATCHER_PROTECTION_TEE, MATCHER_PROTECTION_ON_CHIP.
|
||||
*/
|
||||
public static final short MATCHER_PROTECTION_SOFTWARE = 1;
|
||||
/**
|
||||
* This flag should be set if the authenticator's matcher is running inside the Trusted Execution Environment.
|
||||
* Mutually exclusive in authenticator metadata with MATCHER_PROTECTION_SOFTWARE, MATCHER_PROTECTION_ON_CHIP.
|
||||
*/
|
||||
public static final short MATCHER_PROTECTION_TEE = 2;
|
||||
/**
|
||||
* This flag should be set if the authenticator's matcher is running on the chip. Mutually exclusive in
|
||||
* authenticator metadata with MATCHER_PROTECTION_TEE, MATCHER_PROTECTION_SOFTWARE.
|
||||
*/
|
||||
public static final short MATCHER_PROTECTION_ON_CHIP = 4;
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PaymentExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "isPayment")
|
||||
private final boolean payment;
|
||||
|
||||
@Constructor
|
||||
public PaymentExtension(@Param(1) boolean payment) {
|
||||
this.payment = payment;
|
||||
}
|
||||
|
||||
public boolean isPayment() {
|
||||
return payment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PaymentExtension").field("payment", payment).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<PaymentExtension> CREATOR = AbstractSafeParcelable.findCreator(PaymentExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PrfExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getEntries")
|
||||
private final byte[][] entries;
|
||||
|
||||
@Constructor
|
||||
public PrfExtension(@Param(1) byte[][] entries) {
|
||||
this.entries = entries;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[][] getEntries() {
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<PrfExtension> CREATOR =
|
||||
AbstractSafeParcelable.findCreator(PrfExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This class is contains the attributes that are returned to the caller when a new credential is created, or a new
|
||||
* assertion is requested.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredential extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getId")
|
||||
@NonNull
|
||||
private String id;
|
||||
@Field(value = 2, getterName = "getType")
|
||||
@NonNull
|
||||
private String type;
|
||||
@Field(value = 3, getterName = "getRawId")
|
||||
@NonNull
|
||||
private byte[] rawId;
|
||||
@Field(value = 4, getter = "$object.getResponse() instanceof $type ? ($type) $object.getResponse() : null")
|
||||
@Nullable
|
||||
private AuthenticatorAttestationResponse registerResponse;
|
||||
@Field(value = 5, getter = "$object.getResponse() instanceof $type ? ($type) $object.getResponse() : null")
|
||||
@Nullable
|
||||
private AuthenticatorAssertionResponse signResponse;
|
||||
@Field(value = 6, getter = "$object.getResponse() instanceof $type ? ($type) $object.getResponse() : null")
|
||||
@Nullable
|
||||
private AuthenticatorErrorResponse errorResponse;
|
||||
@Field(value = 7, getterName = "getClientExtensionResults")
|
||||
@Nullable
|
||||
private AuthenticationExtensionsClientOutputs clientExtensionResults;
|
||||
@Field(value = 8, getterName = "getAuthenticatorAttachment")
|
||||
@Nullable
|
||||
private String authenticatorAttachment;
|
||||
|
||||
PublicKeyCredential(@NonNull String id, @NonNull String type, @NonNull byte[] rawId, @NonNull AuthenticatorResponse response, @Nullable AuthenticationExtensionsClientOutputs clientExtensionResults, @Nullable String authenticatorAttachment) {
|
||||
this(id, type, rawId, response instanceof AuthenticatorAttestationResponse ? (AuthenticatorAttestationResponse) response : null, response instanceof AuthenticatorAssertionResponse ? (AuthenticatorAssertionResponse) response : null, response instanceof AuthenticatorErrorResponse ? (AuthenticatorErrorResponse) response : null, clientExtensionResults, authenticatorAttachment);
|
||||
}
|
||||
|
||||
@Constructor
|
||||
PublicKeyCredential(@Param(1) @NonNull String id, @Param(2) @NonNull String type, @Param(3) @NonNull byte[] rawId, @Param(4) @Nullable AuthenticatorAttestationResponse registerResponse, @Param(5) @Nullable AuthenticatorAssertionResponse signResponse, @Param(6) @Nullable AuthenticatorErrorResponse errorResponse, @Param(7) @Nullable AuthenticationExtensionsClientOutputs clientExtensionResults, @Param(8) @Nullable String authenticatorAttachment) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.rawId = rawId;
|
||||
this.registerResponse = registerResponse;
|
||||
this.signResponse = signResponse;
|
||||
this.errorResponse = errorResponse;
|
||||
this.clientExtensionResults = clientExtensionResults;
|
||||
this.authenticatorAttachment = authenticatorAttachment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authenticator attachment of this credential.
|
||||
*/
|
||||
@Nullable
|
||||
public String getAuthenticatorAttachment() {
|
||||
return authenticatorAttachment;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AuthenticationExtensionsClientOutputs getClientExtensionResults() {
|
||||
return clientExtensionResults;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getRawId() {
|
||||
return rawId;
|
||||
}
|
||||
|
||||
public AuthenticatorResponse getResponse() {
|
||||
if (registerResponse != null) return registerResponse;
|
||||
if (signResponse != null) return signResponse;
|
||||
if (errorResponse != null) return errorResponse;
|
||||
throw new IllegalStateException("No response set.");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link PublicKeyCredential}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@NonNull
|
||||
private String id;
|
||||
@NonNull
|
||||
private byte[] rawId;
|
||||
private AuthenticatorResponse response;
|
||||
@Nullable
|
||||
private AuthenticationExtensionsClientOutputs extensionsClientOutputs;
|
||||
@Nullable
|
||||
private String authenticatorAttachment;
|
||||
|
||||
/**
|
||||
* The constructor of {@link PublicKeyCredential.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the output produced by the client's processing of the extensions requested by the relying party.
|
||||
*/
|
||||
public Builder setAuthenticationExtensionsClientOutputs(@Nullable AuthenticationExtensionsClientOutputs extensionsClientOutputs) {
|
||||
this.extensionsClientOutputs = extensionsClientOutputs;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authenticator attachment of the credential.
|
||||
*/
|
||||
public Builder setAuthenticatorAttachment(@NonNull String authenticatorAttachment) {
|
||||
this.authenticatorAttachment = authenticatorAttachment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the base64url encoding of the credential identifier.
|
||||
*/
|
||||
public Builder setId(@NonNull String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the raw value of the credential identifier.
|
||||
*/
|
||||
public Builder setRawId(@NonNull byte[] rawId) {
|
||||
this.rawId = rawId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the authenticator's response to the clients register or sign request.
|
||||
* <p>
|
||||
* This attribute contains the authenticator's response to the client’s request to either create a public key
|
||||
* credential, or generate an authentication assertion. If the {@link PublicKeyCredential} is created in
|
||||
* response a register request, this attribute’s value will be an {@link AuthenticatorAttestationResponse},
|
||||
* otherwise, the {@link PublicKeyCredential} was created in response to a sign request, and this attribute’s
|
||||
* value will be an {@link AuthenticatorAssertionResponse}.
|
||||
*/
|
||||
public Builder setResponse(@NonNull AuthenticatorResponse response) {
|
||||
this.response = response;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link PublicKeyCredential} object.
|
||||
*/
|
||||
public PublicKeyCredential build() {
|
||||
return new PublicKeyCredential(id, PublicKeyCredentialType.PUBLIC_KEY.toString(), rawId, response, extensionsClientOutputs, authenticatorAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
String rawIdB64 = Base64.encodeToString(rawId, Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
|
||||
return ToStringHelper.name("PublicKeyCredential")
|
||||
.field("id", id)
|
||||
.field("type", type)
|
||||
.field("rawId", rawIdB64)
|
||||
.field("registerResponse", registerResponse)
|
||||
.field("signResponse", signResponse)
|
||||
.field("errorResponse", errorResponse)
|
||||
.field("clientExtensionResults", clientExtensionResults)
|
||||
.field("authenticatorAttachment", authenticatorAttachment)
|
||||
.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredential)) return false;
|
||||
|
||||
PublicKeyCredential that = (PublicKeyCredential) o;
|
||||
|
||||
if (!Objects.equals(id, that.id)) return false;
|
||||
if (!Objects.equals(type, that.type)) return false;
|
||||
if (!Arrays.equals(rawId, that.rawId)) return false;
|
||||
if (!Objects.equals(registerResponse, that.registerResponse)) return false;
|
||||
if (!Objects.equals(signResponse, that.signResponse)) return false;
|
||||
if (!Objects.equals(errorResponse, that.errorResponse)) return false;
|
||||
if (!Objects.equals(clientExtensionResults, that.clientExtensionResults)) return false;
|
||||
return Objects.equals(authenticatorAttachment, that.authenticatorAttachment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{id, type, rawId, signResponse, registerResponse, errorResponse, clientExtensionResults, authenticatorAttachment});
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes the {@link PublicKeyCredential} to bytes. Use {@link #deserializeFromBytes(byte[])} to deserialize.
|
||||
*
|
||||
* @return the serialized byte array.
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the {@link PublicKeyCredential} from bytes, reversing {@link #serializeToBytes()}.
|
||||
*
|
||||
* @param serializedBytes The serialized bytes.
|
||||
* @return The deserialized {@link PublicKeyCredential}.
|
||||
*/
|
||||
@NonNull
|
||||
public static PublicKeyCredential deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredential> CREATOR = findCreator(PublicKeyCredential.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is used to supply options when creating a new credential.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialCreationOptions extends RequestOptions {
|
||||
@Field(value = 2, getterName = "getRp")
|
||||
@NonNull
|
||||
private PublicKeyCredentialRpEntity rp;
|
||||
@Field(value = 3, getterName = "getUser")
|
||||
@NonNull
|
||||
private PublicKeyCredentialUserEntity user;
|
||||
@Field(value = 4, getterName = "getChallenge")
|
||||
@NonNull
|
||||
private byte[] challenge;
|
||||
@Field(value = 5, getterName = "getParameters")
|
||||
@NonNull
|
||||
private List<PublicKeyCredentialParameters> parameters;
|
||||
@Field(value = 6, getterName = "getTimeoutSeconds")
|
||||
@Nullable
|
||||
private Double timeoutSeconds;
|
||||
@Field(value = 7, getterName = "getExcludeList")
|
||||
@Nullable
|
||||
private List<PublicKeyCredentialDescriptor> excludeList;
|
||||
@Field(value = 8, getterName = "getAuthenticatorSelection")
|
||||
@Nullable
|
||||
private AuthenticatorSelectionCriteria authenticatorSelection;
|
||||
@Field(value = 9, getterName = "getRequestId")
|
||||
@Nullable
|
||||
private Integer requestId;
|
||||
@Field(value = 10, getterName = "getTokenBinding")
|
||||
@Nullable
|
||||
private TokenBinding tokenBinding;
|
||||
@Field(value = 11, getterName = "getAttestationConveyancePreference")
|
||||
@Nullable
|
||||
private AttestationConveyancePreference attestationConveyancePreference;
|
||||
@Field(value = 12, getterName = "getAuthenticationExtensions")
|
||||
@Nullable
|
||||
private AuthenticationExtensions authenticationExtensions;
|
||||
|
||||
@Constructor
|
||||
PublicKeyCredentialCreationOptions(@Param(2) @NonNull PublicKeyCredentialRpEntity rp, @Param(3) @NonNull PublicKeyCredentialUserEntity user, @Param(4) @NonNull byte[] challenge, @Param(5) @NonNull List<PublicKeyCredentialParameters> parameters, @Param(6) @Nullable Double timeoutSeconds, @Param(7) @Nullable List<PublicKeyCredentialDescriptor> excludeList, @Param(8) @Nullable AuthenticatorSelectionCriteria authenticatorSelection, @Param(9) @Nullable Integer requestId, @Param(10) @Nullable TokenBinding tokenBinding, @Param(11) @Nullable AttestationConveyancePreference attestationConveyancePreference, @Param(12) @Nullable AuthenticationExtensions authenticationExtensions) {
|
||||
this.rp = rp;
|
||||
this.user = user;
|
||||
this.challenge = challenge;
|
||||
this.parameters = parameters;
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
this.excludeList = excludeList;
|
||||
this.authenticatorSelection = authenticatorSelection;
|
||||
this.requestId = requestId;
|
||||
this.tokenBinding = tokenBinding;
|
||||
this.attestationConveyancePreference = attestationConveyancePreference;
|
||||
this.authenticationExtensions = authenticationExtensions;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AttestationConveyancePreference getAttestationConveyancePreference() {
|
||||
return attestationConveyancePreference;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getAttestationConveyancePreferenceAsString() {
|
||||
if (attestationConveyancePreference == null) return null;
|
||||
return attestationConveyancePreference.toString();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AuthenticationExtensions getAuthenticationExtensions() {
|
||||
return authenticationExtensions;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AuthenticatorSelectionCriteria getAuthenticatorSelection() {
|
||||
return authenticatorSelection;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public byte[] getChallenge() {
|
||||
return challenge;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<PublicKeyCredentialDescriptor> getExcludeList() {
|
||||
return excludeList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public List<PublicKeyCredentialParameters> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Integer getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialRpEntity getRp() {
|
||||
return rp;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Double getTimeoutSeconds() {
|
||||
return timeoutSeconds;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TokenBinding getTokenBinding() {
|
||||
return tokenBinding;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialUserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialCreationOptions)) return false;
|
||||
|
||||
PublicKeyCredentialCreationOptions that = (PublicKeyCredentialCreationOptions) o;
|
||||
|
||||
if (rp != null ? !rp.equals(that.rp) : that.rp != null) return false;
|
||||
if (user != null ? !user.equals(that.user) : that.user != null) return false;
|
||||
if (!Arrays.equals(challenge, that.challenge)) return false;
|
||||
if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) return false;
|
||||
if (timeoutSeconds != null ? !timeoutSeconds.equals(that.timeoutSeconds) : that.timeoutSeconds != null)
|
||||
return false;
|
||||
if (excludeList != null ? !excludeList.equals(that.excludeList) : that.excludeList != null) return false;
|
||||
if (authenticatorSelection != null ? !authenticatorSelection.equals(that.authenticatorSelection) : that.authenticatorSelection != null)
|
||||
return false;
|
||||
if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) return false;
|
||||
if (tokenBinding != null ? !tokenBinding.equals(that.tokenBinding) : that.tokenBinding != null) return false;
|
||||
if (attestationConveyancePreference != that.attestationConveyancePreference) return false;
|
||||
return authenticationExtensions != null ? authenticationExtensions.equals(that.authenticationExtensions) : that.authenticationExtensions == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{rp, user, Arrays.hashCode(challenge), parameters, timeoutSeconds, excludeList, authenticatorSelection, requestId, tokenBinding, attestationConveyancePreference, authenticationExtensions});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialCreationOptions")
|
||||
.field("rp", rp)
|
||||
.field("user", user)
|
||||
.field("challenge", challenge)
|
||||
.field("parameters", parameters)
|
||||
.field("timeoutSeconds", timeoutSeconds)
|
||||
.field("excludeList", excludeList)
|
||||
.field("authenticatorSelection", authenticatorSelection)
|
||||
.field("requestId", requestId)
|
||||
.field("tokenBinding", tokenBinding)
|
||||
.field("attestationConveyancePreference", attestationConveyancePreference)
|
||||
.field("authenticationExtensions", authenticationExtensions)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link PublicKeyCredentialCreationOptions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@NonNull
|
||||
private PublicKeyCredentialRpEntity rp;
|
||||
@NonNull
|
||||
private PublicKeyCredentialUserEntity user;
|
||||
@NonNull
|
||||
private byte[] challenge;
|
||||
@NonNull
|
||||
private List<PublicKeyCredentialParameters> parameters;
|
||||
@Nullable
|
||||
private Double timeoutSeconds;
|
||||
@Nullable
|
||||
private List<PublicKeyCredentialDescriptor> excludeList;
|
||||
@Nullable
|
||||
private AuthenticatorSelectionCriteria authenticatorSelection;
|
||||
@Nullable
|
||||
private Integer requestId;
|
||||
@Nullable
|
||||
private TokenBinding tokenBinding;
|
||||
@Nullable
|
||||
private AttestationConveyancePreference attestationConveyancePreference;
|
||||
@Nullable
|
||||
private AuthenticationExtensions authenticationExtensions;
|
||||
|
||||
/**
|
||||
* The constructor of {@link PublicKeyCredentialCreationOptions.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the preference for obfuscation level of the returned attestation data.
|
||||
*/
|
||||
public Builder setAttestationConveyancePreference(@Nullable AttestationConveyancePreference attestationConveyancePreference) {
|
||||
this.attestationConveyancePreference = attestationConveyancePreference;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets additional extensions that may dictate some client behavior during an exchange with a connected
|
||||
* authenticator.
|
||||
*/
|
||||
public Builder setAuthenticationExtensions(@Nullable AuthenticationExtensions authenticationExtensions) {
|
||||
this.authenticationExtensions = authenticationExtensions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets constraints on the type of authenticator that is acceptable for this session.
|
||||
*/
|
||||
public Builder setAuthenticatorSelection(@Nullable AuthenticatorSelectionCriteria authenticatorSelection) {
|
||||
this.authenticatorSelection = authenticatorSelection;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the challenge to sign when generating the attestation for this request.
|
||||
*/
|
||||
public Builder setChallenge(@NonNull byte[] challenge) {
|
||||
this.challenge = challenge;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of credentials that, if found on a connected authenticator, will preclude registration of that
|
||||
* authenticator with the relying party. This is often set to prevent re-registration of authenticators that
|
||||
* the relying party has already registered on behalf of the user.
|
||||
*/
|
||||
public Builder setExcludeList(@Nullable List<PublicKeyCredentialDescriptor> excludeList) {
|
||||
this.excludeList = excludeList;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link PublicKeyCredentialParameters} that constrain the type of credential to generate.
|
||||
*/
|
||||
public Builder setParameters(@NonNull List<PublicKeyCredentialParameters> parameters) {
|
||||
this.parameters = parameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request id in order to link together events into a single session (the span of events between the
|
||||
* time that the server initiates a single FIDO2 request to the client and receives reply) on a single device.
|
||||
*/
|
||||
public Builder setRequestId(@Nullable Integer requestId) {
|
||||
this.requestId = requestId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets information for a relying party, on whose behalf a given registration operation is being performed.
|
||||
* <p>
|
||||
* Note: the RpId should be an effective domain (aka, without scheme or port); and it should also be in secure
|
||||
* context (aka https connection). Apps-facing API needs to check the package signature against Digital Asset
|
||||
* Links, whose resource is the RP ID with prepended "//". Privileged (browser) API doesn't need the check.
|
||||
*/
|
||||
public Builder setRp(@NonNull PublicKeyCredentialRpEntity rp) {
|
||||
this.rp = rp;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a timeout that limits the duration of the registration session provided to the user.
|
||||
*/
|
||||
public Builder setTimeoutSeconds(@Nullable Double timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TokenBinding} associated with the calling origin.
|
||||
*/
|
||||
public Builder setTokenBinding(@Nullable TokenBinding tokenBinding) {
|
||||
this.tokenBinding = tokenBinding;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets information about the user on whose behalf the relying party is registering a credential.
|
||||
*/
|
||||
public Builder setUser(@NonNull PublicKeyCredentialUserEntity user) {
|
||||
this.user = user;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link PublicKeyCredentialCreationOptions} object.
|
||||
*/
|
||||
public PublicKeyCredentialCreationOptions build() {
|
||||
return new PublicKeyCredentialCreationOptions(rp, user, challenge, parameters, timeoutSeconds, excludeList, authenticatorSelection, requestId, tokenBinding, attestationConveyancePreference, authenticationExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the {@link PublicKeyCredentialCreationOptions} from bytes, reversing {@link #serializeToBytes()}.
|
||||
*
|
||||
* @param serializedBytes The serialized bytes.
|
||||
* @return The deserialized {@link PublicKeyCredentialCreationOptions}.
|
||||
*/
|
||||
@NonNull
|
||||
public static PublicKeyCredentialCreationOptions deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialCreationOptions> CREATOR = findCreator(PublicKeyCredentialCreationOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.fido.common.Transport;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class contains the attributes that are specified by a caller when referring to a credential as an input
|
||||
* parameter to the registration or authentication method.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialDescriptor extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getType")
|
||||
@NonNull
|
||||
private PublicKeyCredentialType type;
|
||||
@Field(value = 3, getterName = "getId")
|
||||
@NonNull
|
||||
private byte[] id;
|
||||
@Field(value = 4, getterName = "getTransports")
|
||||
@Nullable
|
||||
private List<Transport> transports;
|
||||
|
||||
private PublicKeyCredentialDescriptor() {
|
||||
}
|
||||
|
||||
public PublicKeyCredentialDescriptor(@NonNull String type, @NonNull byte[] id, @Nullable List<Transport> transports) {
|
||||
try {
|
||||
this.type = PublicKeyCredentialType.fromString(type);
|
||||
} catch (PublicKeyCredentialType.UnsupportedPublicKeyCredTypeException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
this.id = id;
|
||||
this.transports = transports;
|
||||
}
|
||||
|
||||
@Constructor
|
||||
PublicKeyCredentialDescriptor(@Param(2) @NonNull PublicKeyCredentialType type, @Param(3) @NonNull byte[] id, @Param(4) @Nullable List<Transport> transports) {
|
||||
this.type = type;
|
||||
this.id = id;
|
||||
this.transports = transports;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<Transport> getTransports() {
|
||||
return transports;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getTypeAsString() {
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialDescriptor)) return false;
|
||||
|
||||
PublicKeyCredentialDescriptor that = (PublicKeyCredentialDescriptor) o;
|
||||
|
||||
if (type != that.type) return false;
|
||||
if (!Arrays.equals(id, that.id)) return false;
|
||||
return transports != null ? transports.equals(that.transports) : that.transports == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{type, Arrays.hashCode(id), transports});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialDescriptor")
|
||||
.value(id)
|
||||
.field("type", type)
|
||||
.field("transports", transports)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized public key credential descriptor is encountered.
|
||||
*/
|
||||
public static class UnsupportedPubKeyCredDescriptorException extends Exception {
|
||||
public UnsupportedPubKeyCredDescriptorException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public UnsupportedPubKeyCredDescriptorException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialDescriptor> CREATOR = findCreator(PublicKeyCredentialDescriptor.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class supplies additional parameters when creating a new credential.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialParameters extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getType")
|
||||
@NonNull
|
||||
private PublicKeyCredentialType type;
|
||||
@Field(value = 3, getterName = "getAlgorithm")
|
||||
@NonNull
|
||||
private COSEAlgorithmIdentifier algorithm;
|
||||
|
||||
private PublicKeyCredentialParameters() {
|
||||
}
|
||||
|
||||
public PublicKeyCredentialParameters(@NonNull String type, int algorithm) {
|
||||
try {
|
||||
this.type = PublicKeyCredentialType.fromString(type);
|
||||
} catch (PublicKeyCredentialType.UnsupportedPublicKeyCredTypeException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
try {
|
||||
this.algorithm = COSEAlgorithmIdentifier.fromCoseValue(algorithm);
|
||||
} catch (COSEAlgorithmIdentifier.UnsupportedAlgorithmIdentifierException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Constructor
|
||||
PublicKeyCredentialParameters(@Param(2) @NonNull PublicKeyCredentialType type, @Param(3) @NonNull COSEAlgorithmIdentifier algorithm) {
|
||||
this.type = type;
|
||||
this.algorithm = algorithm;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public COSEAlgorithmIdentifier getAlgorithm() {
|
||||
return algorithm;
|
||||
}
|
||||
|
||||
public int getAlgorithmIdAsInteger() {
|
||||
return algorithm.toCoseValue();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public PublicKeyCredentialType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getTypeAsString() {
|
||||
return type.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialParameters)) return false;
|
||||
|
||||
PublicKeyCredentialParameters that = (PublicKeyCredentialParameters) o;
|
||||
|
||||
if (type != that.type) return false;
|
||||
return algorithm != null ? algorithm.equals(that.algorithm) : that.algorithm == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{type, algorithm});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialParameters")
|
||||
.field("type", type)
|
||||
.field("algorithm", algorithm)
|
||||
.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialParameters> CREATOR = findCreator(PublicKeyCredentialParameters.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class is used to supply an authentication request with the data it needs to generate an assertion.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialRequestOptions extends RequestOptions {
|
||||
@Field(value = 2, getterName = "getChallenge")
|
||||
@NonNull
|
||||
private byte[] challenge;
|
||||
@Field(value = 3, getterName = "getTimeoutSeconds")
|
||||
@Nullable
|
||||
private Double timeoutSeconds;
|
||||
@Field(value = 4, getterName = "getRpId")
|
||||
@NonNull
|
||||
private String rpId;
|
||||
@Field(value = 5, getterName = "getAllowList")
|
||||
@Nullable
|
||||
private List<PublicKeyCredentialDescriptor> allowList;
|
||||
@Field(value = 6, getterName = "getRequestId")
|
||||
@Nullable
|
||||
private Integer requestId;
|
||||
@Field(value = 7, getterName = "getTokenBinding")
|
||||
@Nullable
|
||||
private TokenBinding tokenBinding;
|
||||
@Field(value = 8, getterName = "getRequireUserVerification")
|
||||
@Nullable
|
||||
private UserVerificationRequirement requireUserVerification;
|
||||
@Field(value = 9, getterName = "getAuthenticationExtensions")
|
||||
@Nullable
|
||||
private AuthenticationExtensions authenticationExtensions;
|
||||
@Field(10)
|
||||
@Nullable
|
||||
Long longRequestId;
|
||||
|
||||
@Constructor
|
||||
public PublicKeyCredentialRequestOptions(@Param(2)@NonNull byte[] challenge,@Param(3) @Nullable Double timeoutSeconds, @Param(4)@NonNull String rpId, @Param(5)@Nullable List<PublicKeyCredentialDescriptor> allowList,@Param(6) @Nullable Integer requestId,@Param(7) @Nullable TokenBinding tokenBinding,@Param(8) @Nullable UserVerificationRequirement requireUserVerification, @Param(9)@Nullable AuthenticationExtensions authenticationExtensions) {
|
||||
this.challenge = challenge;
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
this.rpId = rpId;
|
||||
this.allowList = allowList;
|
||||
this.requestId = requestId;
|
||||
this.tokenBinding = tokenBinding;
|
||||
this.requireUserVerification = requireUserVerification;
|
||||
this.authenticationExtensions = authenticationExtensions;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public List<PublicKeyCredentialDescriptor> getAllowList() {
|
||||
return allowList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public AuthenticationExtensions getAuthenticationExtensions() {
|
||||
return authenticationExtensions;
|
||||
}
|
||||
|
||||
@Hide
|
||||
@Nullable
|
||||
public UserVerificationRequirement getRequireUserVerification() {
|
||||
return requireUserVerification;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public byte[] getChallenge() {
|
||||
return challenge;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Integer getRequestId() {
|
||||
return requestId;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getRpId() {
|
||||
return rpId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Double getTimeoutSeconds() {
|
||||
return timeoutSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TokenBinding getTokenBinding() {
|
||||
return tokenBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialRequestOptions)) return false;
|
||||
|
||||
PublicKeyCredentialRequestOptions that = (PublicKeyCredentialRequestOptions) o;
|
||||
|
||||
if (!Arrays.equals(challenge, that.challenge)) return false;
|
||||
if (timeoutSeconds != null ? !timeoutSeconds.equals(that.timeoutSeconds) : that.timeoutSeconds != null)
|
||||
return false;
|
||||
if (rpId != null ? !rpId.equals(that.rpId) : that.rpId != null) return false;
|
||||
if (allowList != null ? !allowList.equals(that.allowList) : that.allowList != null) return false;
|
||||
if (requestId != null ? !requestId.equals(that.requestId) : that.requestId != null) return false;
|
||||
if (tokenBinding != null ? !tokenBinding.equals(that.tokenBinding) : that.tokenBinding != null) return false;
|
||||
if (requireUserVerification != that.requireUserVerification) return false;
|
||||
return authenticationExtensions != null ? authenticationExtensions.equals(that.authenticationExtensions) : that.authenticationExtensions == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{Arrays.hashCode(challenge), timeoutSeconds, rpId, allowList, requestId, tokenBinding, requireUserVerification, authenticationExtensions});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialRequestOptions")
|
||||
.field("challenge", challenge)
|
||||
.field("timeoutSeconds", timeoutSeconds)
|
||||
.field("rpId", rpId)
|
||||
.field("allowList", allowList)
|
||||
.field("requestId", requestId)
|
||||
.field("tokenBinding", tokenBinding)
|
||||
.field("userVerificationRequirement", requireUserVerification)
|
||||
.field("authenticationExtensions", authenticationExtensions)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link PublicKeyCredentialRequestOptions}.
|
||||
*/
|
||||
public static class Builder {
|
||||
@NonNull
|
||||
private byte[] challenge;
|
||||
@Nullable
|
||||
private Double timeoutSeconds;
|
||||
@NonNull
|
||||
private String rpId;
|
||||
@Nullable
|
||||
private List<PublicKeyCredentialDescriptor> allowList;
|
||||
@Nullable
|
||||
private Integer requestId;
|
||||
@Nullable
|
||||
private TokenBinding tokenBinding;
|
||||
@Nullable
|
||||
private AuthenticationExtensions authenticationExtensions;
|
||||
@Nullable
|
||||
private UserVerificationRequirement requireUserVerification;
|
||||
|
||||
/**
|
||||
* The constructor of {@link PublicKeyCredentialRequestOptions.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of public key credentials which constrain authentication to authenticators that contain a
|
||||
* private key for at least one of the supplied public keys.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAllowList(@Nullable List<PublicKeyCredentialDescriptor> allowList) {
|
||||
this.allowList = allowList;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets additional extensions that may dictate some client behavior during an exchange with a connected
|
||||
* authenticator.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setAuthenticationExtensions(@Nullable AuthenticationExtensions authenticationExtensions) {
|
||||
this.authenticationExtensions = authenticationExtensions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nonce value that the authenticator should sign using a private key corresponding to a public key
|
||||
* credential that is acceptable for this authentication session.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setChallenge(@NonNull byte[] challenge) {
|
||||
this.challenge = challenge;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the request id in order to link together events into a single session (the span of events between the
|
||||
* time that the server initiates a single FIDO2 request to the client and receives reply) on a single device.
|
||||
* This field is optional.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setRequestId(@Nullable Integer requestId) {
|
||||
this.requestId = requestId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Hide
|
||||
@NonNull
|
||||
public Builder setRequireUserVerification(@Nullable UserVerificationRequirement requireUserVerification) {
|
||||
this.requireUserVerification = requireUserVerification;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets identifier for a relying party, on whose behalf a given authentication operation is being performed.
|
||||
* A public key credential can only be used for authentication with the same replying party it was registered
|
||||
* with.
|
||||
* <p>
|
||||
* Note: the RpId should be an effective domain (aka, without scheme or port); and it should also be in secure
|
||||
* context (aka https connection). Apps-facing API needs to check the package signature against Digital Asset
|
||||
* Links, whose resource is the RP ID with prepended "//". Privileged (browser) API doesn't need the check.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setRpId(@NonNull String rpId) {
|
||||
this.rpId = rpId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public Builder setTimeoutSeconds(@Nullable Double timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link TokenBinding} associated with the calling origin.
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setTokenBinding(@Nullable TokenBinding tokenBinding) {
|
||||
this.tokenBinding = tokenBinding;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the {@link PublicKeyCredentialRequestOptions} object.
|
||||
*/
|
||||
@NonNull
|
||||
public PublicKeyCredentialRequestOptions build() {
|
||||
return new PublicKeyCredentialRequestOptions(challenge, timeoutSeconds, rpId, allowList, requestId, tokenBinding, requireUserVerification, authenticationExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the {@link PublicKeyCredentialRequestOptions} from bytes, reversing {@link #serializeToBytes()}.
|
||||
*
|
||||
* @param serializedBytes The serialized bytes.
|
||||
* @return The deserialized {@link PublicKeyCredentialRequestOptions}.
|
||||
*/
|
||||
@NonNull
|
||||
public static PublicKeyCredentialRequestOptions deserializeFromBytes(byte[] serializedBytes) {
|
||||
return SafeParcelableSerializer.deserializeFromBytes(serializedBytes, CREATOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialRequestOptions> CREATOR = findCreator(PublicKeyCredentialRequestOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents the information about a relying party with which a credential is associated.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialRpEntity extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getId")
|
||||
@NonNull
|
||||
private String id;
|
||||
@Field(value = 3, getterName = "getName")
|
||||
@NonNull
|
||||
private String name;
|
||||
@Field(value = 4, getterName = "getIcon")
|
||||
@Nullable
|
||||
private String icon;
|
||||
|
||||
private PublicKeyCredentialRpEntity() {
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public PublicKeyCredentialRpEntity(@Param(2)@NonNull String id, @Param(3)@NonNull String name, @Param(4)@Nullable String icon) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialRpEntity)) return false;
|
||||
|
||||
PublicKeyCredentialRpEntity that = (PublicKeyCredentialRpEntity) o;
|
||||
|
||||
if (id != null ? !id.equals(that.id) : that.id != null) return false;
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
||||
return icon != null ? icon.equals(that.icon) : that.icon == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{id, name, icon});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialRpEntity")
|
||||
.value(id)
|
||||
.field("name", name)
|
||||
.field("icon", icon)
|
||||
.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialRpEntity> CREATOR = findCreator(PublicKeyCredentialRpEntity.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* This enumeration defines the valid credential types.
|
||||
*/
|
||||
public enum PublicKeyCredentialType implements Parcelable {
|
||||
PUBLIC_KEY("public-key");
|
||||
|
||||
private final String value;
|
||||
|
||||
PublicKeyCredentialType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(toString());
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static PublicKeyCredentialType fromString(String type) throws UnsupportedPublicKeyCredTypeException {
|
||||
for (PublicKeyCredentialType value : values()) {
|
||||
if (value.value.equals(type)) return value;
|
||||
}
|
||||
throw new UnsupportedPublicKeyCredTypeException("PublicKeyCredentialType " + type + " not supported");
|
||||
}
|
||||
|
||||
public static Creator<PublicKeyCredentialType> CREATOR = new Creator<PublicKeyCredentialType>() {
|
||||
@Override
|
||||
public PublicKeyCredentialType createFromParcel(Parcel source) {
|
||||
try {
|
||||
return PublicKeyCredentialType.fromString(source.readString());
|
||||
} catch (UnsupportedPublicKeyCredTypeException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicKeyCredentialType[] newArray(int size) {
|
||||
return new PublicKeyCredentialType[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized transport is encountered.
|
||||
*/
|
||||
public static class UnsupportedPublicKeyCredTypeException extends Exception {
|
||||
public UnsupportedPublicKeyCredTypeException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.util.Base64;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class is used to supply additional parameters about the user account when creating a new Credential.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class PublicKeyCredentialUserEntity extends AbstractSafeParcelable {
|
||||
@Field(value = 2, getterName = "getId")
|
||||
@NonNull
|
||||
private byte[] id;
|
||||
@Field(value = 3, getterName = "getName")
|
||||
@NonNull
|
||||
private String name;
|
||||
@Field(value = 4, getterName = "getIcon")
|
||||
@Nullable
|
||||
private String icon;
|
||||
@Field(value = 5, getterName = "getDisplayName")
|
||||
@NonNull
|
||||
private String displayName;
|
||||
|
||||
private PublicKeyCredentialUserEntity() {
|
||||
}
|
||||
|
||||
public String toJson() throws JSONException {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", Base64.encodeToString(id, Base64.NO_WRAP | Base64.URL_SAFE | Base64.NO_PADDING));
|
||||
jsonObject.put("name", name);
|
||||
jsonObject.put("icon", icon);
|
||||
jsonObject.put("displayName", displayName);
|
||||
return jsonObject.toString();
|
||||
}
|
||||
|
||||
public static PublicKeyCredentialUserEntity parseJson(String json) throws JSONException {
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
byte[] id = Base64.decode(jsonObject.getString("id"), Base64.NO_WRAP | Base64.URL_SAFE | Base64.NO_PADDING);
|
||||
String name = jsonObject.optString("name");
|
||||
String icon = jsonObject.optString("icon");
|
||||
String displayName = jsonObject.optString("displayName");
|
||||
return new PublicKeyCredentialUserEntity(id, name, icon, displayName);
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public PublicKeyCredentialUserEntity(@Param(2) @NonNull byte[] id, @Param(3) @NonNull String name, @Param(4) @Nullable String icon, @Param(5) @NonNull String displayName) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public byte[] getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof PublicKeyCredentialUserEntity)) return false;
|
||||
|
||||
PublicKeyCredentialUserEntity that = (PublicKeyCredentialUserEntity) o;
|
||||
|
||||
if (!Arrays.equals(id, that.id)) return false;
|
||||
if (name != null ? !name.equals(that.name) : that.name != null) return false;
|
||||
if (icon != null ? !icon.equals(that.icon) : that.icon != null) return false;
|
||||
return displayName != null ? displayName.equals(that.displayName) : that.displayName == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{id, name, icon, displayName});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("PublicKeyCredentialUserEntity")
|
||||
.value(id)
|
||||
.field("name", name)
|
||||
.field("icon", icon)
|
||||
.field("displayName", displayName)
|
||||
.end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<PublicKeyCredentialUserEntity> CREATOR = findCreator(PublicKeyCredentialUserEntity.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Algorithm names and COSE identifiers for RSA (public) keys.
|
||||
*/
|
||||
@PublicApi
|
||||
public enum RSAAlgorithm implements Algorithm {
|
||||
/**
|
||||
* RSASSA-PKCS1-v1_5 w/ SHA-256
|
||||
*/
|
||||
RS256(-257),
|
||||
/**
|
||||
* RSASSA-PKCS1-v1_5 w/ SHA-384
|
||||
*/
|
||||
RS384(-258),
|
||||
/**
|
||||
* RSASSA-PKCS1-v1_5 w/ SHA-512
|
||||
*/
|
||||
RS512(-259),
|
||||
/**
|
||||
* The legacy value for "RSASSA-PKCS1-v1_5 w/ SHA-1"
|
||||
*
|
||||
* @deprecated please use {@link #RS1} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
LEGACY_RS1(-262),
|
||||
/**
|
||||
* RSASSA-PSS w/ SHA-256
|
||||
*/
|
||||
PS256(-37),
|
||||
/**
|
||||
* RSASSA-PSS w/ SHA-384
|
||||
*/
|
||||
PS384(-38),
|
||||
/**
|
||||
* RSASSA-PSS w/ SHA-512
|
||||
*/
|
||||
PS512(-39),
|
||||
/**
|
||||
* RSASSA-PKCS1-v1_5 w/ SHA-1
|
||||
*/
|
||||
RS1(-65535);
|
||||
|
||||
private final int algoValue;
|
||||
|
||||
RSAAlgorithm(int algoValue) {
|
||||
this.algoValue = algoValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAlgoValue() {
|
||||
return algoValue;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableSerializer;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* An abstract class representing FIDO2 request options.
|
||||
*/
|
||||
@PublicApi
|
||||
public abstract class RequestOptions extends AbstractSafeParcelable {
|
||||
@NonNull
|
||||
public abstract byte[] getChallenge();
|
||||
@Nullable
|
||||
public abstract Double getTimeoutSeconds();
|
||||
@Nullable
|
||||
public abstract Integer getRequestId();
|
||||
@Nullable
|
||||
public abstract TokenBinding getTokenBinding();
|
||||
@Nullable
|
||||
public abstract AuthenticationExtensions getAuthenticationExtensions();
|
||||
|
||||
/**
|
||||
* Serializes the {@link RequestOptions} to bytes. Use deserializeFromBytes(byte[]) to deserialize.
|
||||
*/
|
||||
@NonNull
|
||||
public byte[] serializeToBytes() {
|
||||
return SafeParcelableSerializer.serializeToBytes(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2023 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* An enum that describes the Resident Key (Discoverable Credential) requirements.
|
||||
* <p>
|
||||
* According to WebAuthn, this structure describes the Relying Party's requirements for client-side discoverable credentials
|
||||
* (formerly known as resident credentials or resident keys):
|
||||
* <p>
|
||||
* If the resident key requirement is set to "required", then the Relying Party requires a client-side discoverable credential
|
||||
* and is prepared to receive an error if it can't be created. If the resident key requirement is set to "preferred", the Relying
|
||||
* party strongly prefers a client-side discoverable credential but will accept a server-side credential. If the resident key
|
||||
* requirement is set to "discouraged" then a server-side credential is preferable, but will accept a client-side discoverable
|
||||
* credential.
|
||||
*/
|
||||
public enum ResidentKeyRequirement implements Parcelable {
|
||||
RESIDENT_KEY_DISCOURAGED("discouraged"),
|
||||
RESIDENT_KEY_PREFERRED("preferred"),
|
||||
RESIDENT_KEY_REQUIRED("required");
|
||||
|
||||
private final String requirement;
|
||||
|
||||
ResidentKeyRequirement(String requirement) {
|
||||
this.requirement = requirement;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static ResidentKeyRequirement fromString(@NonNull String requirement) throws UnsupportedResidentKeyRequirementException {
|
||||
for (ResidentKeyRequirement value : values()) {
|
||||
if (requirement.equals(value.requirement)) return value;
|
||||
}
|
||||
throw new UnsupportedResidentKeyRequirementException(requirement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return requirement;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
dest.writeString(requirement);
|
||||
}
|
||||
|
||||
public static Creator<ResidentKeyRequirement> CREATOR = new Creator<ResidentKeyRequirement>() {
|
||||
@Override
|
||||
public ResidentKeyRequirement createFromParcel(Parcel source) {
|
||||
try {
|
||||
return ResidentKeyRequirement.fromString(source.readString());
|
||||
} catch (UnsupportedResidentKeyRequirementException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResidentKeyRequirement[] newArray(int size) {
|
||||
return new ResidentKeyRequirement[size];
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized resident key requirement is encountered.
|
||||
*/
|
||||
public static class UnsupportedResidentKeyRequirementException extends Exception {
|
||||
public UnsupportedResidentKeyRequirementException(@NonNull String requirement) {
|
||||
super("Resident key requirement " + requirement + " not supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2025 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class SimpleTransactionAuthorizationExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getText")
|
||||
private final String text;
|
||||
|
||||
@Constructor
|
||||
public SimpleTransactionAuthorizationExtension(@Param(1) String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ToStringHelper.name("SimpleTransactionAuthorizationExtension").field("text", text).end();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<SimpleTransactionAuthorizationExtension> CREATOR = AbstractSafeParcelable.findCreator(SimpleTransactionAuthorizationExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
import org.microg.gms.utils.ToStringHelper;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents the Token binding information provided by the relying party.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class TokenBinding extends AbstractSafeParcelable {
|
||||
/**
|
||||
* A singleton instance representing that token binding is not supported by the client.
|
||||
*/
|
||||
@NonNull
|
||||
public static final TokenBinding NOT_SUPPORTED = new TokenBinding(TokenBindingStatus.NOT_SUPPORTED, null);
|
||||
/**
|
||||
* A singleton instance representing that token binding is supported by the client, but unused by the relying party.
|
||||
*/
|
||||
@NonNull
|
||||
public static final TokenBinding SUPPORTED = new TokenBinding(TokenBindingStatus.SUPPORTED, null);
|
||||
|
||||
@Field(value = 2, getterName = "getTokenBindingStatus")
|
||||
@NonNull
|
||||
private TokenBindingStatus status;
|
||||
@Field(value = 3, getterName = "getTokenBindingId")
|
||||
@Nullable
|
||||
private String tokenBindingId;
|
||||
|
||||
private TokenBinding() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an instance of a {@link TokenBinding} for a provided token binding id.
|
||||
*/
|
||||
public TokenBinding(@Nullable String tokenBindingId) {
|
||||
status = TokenBindingStatus.PRESENT;
|
||||
this.tokenBindingId = tokenBindingId;
|
||||
}
|
||||
|
||||
@Constructor
|
||||
TokenBinding(@Param(2) @NonNull TokenBindingStatus status, @Param(3) @Nullable String tokenBindingId) {
|
||||
this.status = status;
|
||||
this.tokenBindingId = tokenBindingId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the token binding ID if the token binding status is {@code PRESENT}, otherwise returns null.
|
||||
*/
|
||||
@Nullable
|
||||
public String getTokenBindingId() {
|
||||
return tokenBindingId;
|
||||
}
|
||||
|
||||
@Hide
|
||||
@NonNull
|
||||
public TokenBindingStatus getTokenBindingStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stringified {@link TokenBinding.TokenBindingStatus} associated with this instance.
|
||||
*/
|
||||
@NonNull
|
||||
public String getTokenBindingStatusAsString() {
|
||||
return status.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this {@link TokenBinding} object as a {@link JSONObject}.
|
||||
*/
|
||||
public JSONObject toJsonObject() {
|
||||
try {
|
||||
return new JSONObject().put("status", this.status).put("id", this.tokenBindingId);
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof TokenBinding)) return false;
|
||||
|
||||
TokenBinding that = (TokenBinding) o;
|
||||
|
||||
if (status != that.status) return false;
|
||||
return tokenBindingId != null ? tokenBindingId.equals(that.tokenBindingId) : that.tokenBindingId == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{status, tokenBindingId});
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return ToStringHelper.name("TokenBinding")
|
||||
.value(tokenBindingId)
|
||||
.field("status", status)
|
||||
.end();
|
||||
}
|
||||
|
||||
/**
|
||||
* The token binding status specified by the client.
|
||||
*/
|
||||
public enum TokenBindingStatus implements Parcelable {
|
||||
/**
|
||||
* The client supports token binding and the relying party is using it.
|
||||
*/
|
||||
PRESENT("present"),
|
||||
/**
|
||||
* The client supports token binding but the relying party is not using it.
|
||||
*/
|
||||
SUPPORTED("supported"),
|
||||
/**
|
||||
* The client does not support token binding.
|
||||
*/
|
||||
NOT_SUPPORTED("not-supported");
|
||||
|
||||
@NonNull
|
||||
private final String value;
|
||||
|
||||
TokenBindingStatus(@NonNull String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static TokenBindingStatus fromString(String str) throws UnsupportedTokenBindingStatusException {
|
||||
for (TokenBindingStatus value : values()) {
|
||||
if (value.value.equals(str)) return value;
|
||||
}
|
||||
throw new UnsupportedTokenBindingStatusException("TokenBindingStatus " + str + " not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Creator<TokenBindingStatus> CREATOR = new Creator<TokenBindingStatus>() {
|
||||
@Override
|
||||
public TokenBindingStatus createFromParcel(Parcel in) {
|
||||
try {
|
||||
return fromString(in.readString());
|
||||
} catch (UnsupportedTokenBindingStatusException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TokenBindingStatus[] newArray(int size) {
|
||||
return new TokenBindingStatus[size];
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception thrown when an unsupported or unrecognized {@link TokenBinding.TokenBindingStatus} is encountered.
|
||||
*/
|
||||
public static class UnsupportedTokenBindingStatusException extends Exception {
|
||||
public UnsupportedTokenBindingStatusException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<TokenBinding> CREATOR = findCreator(TokenBinding.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Extension for FIDO User Verification Method.
|
||||
* <p>
|
||||
* This authentication extension allows Relying Parties to ascertain the method(s) used by the user to authorize the
|
||||
* operation.
|
||||
* <p>
|
||||
* Note that this extension can be used in only sign calls.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class UserVerificationMethodExtension extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUvm")
|
||||
@NonNull
|
||||
private boolean uvm;
|
||||
|
||||
@Constructor
|
||||
UserVerificationMethodExtension(@Param(1) boolean uvm) {
|
||||
this.uvm = uvm;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public boolean getUvm() {
|
||||
return uvm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof UserVerificationMethodExtension)) return false;
|
||||
|
||||
UserVerificationMethodExtension that = (UserVerificationMethodExtension) o;
|
||||
|
||||
return uvm == that.uvm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{uvm});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<UserVerificationMethodExtension> CREATOR = findCreator(UserVerificationMethodExtension.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* The authentication method/factor used by the authenticator to verify the user.
|
||||
*/
|
||||
@PublicApi
|
||||
public final class UserVerificationMethods {
|
||||
/**
|
||||
* This flag must be set if the authenticator is able to confirm user presence in any fashion. If this flag and no
|
||||
* other is set for user verification, the guarantee is only that the authenticator cannot be operated without some
|
||||
* human intervention, not necessarily that the sensing of "presence" provides any level of user verification (e.g.
|
||||
* a device that requires a button press to activate).
|
||||
*/
|
||||
public static final int USER_VERIFY_PRESENCE = 1;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses any type of measurement of a fingerprint for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_FINGERPRINT = 2;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses a local-only passcode (i.e. a passcode not known by the server)
|
||||
* for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_PASSCODE = 4;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses a voiceprint (also known as speaker recognition) for user
|
||||
* verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_VOICEPRINT = 8;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses any manner of face recognition to verify the user.
|
||||
*/
|
||||
public static final int USER_VERIFY_FACEPRINT = 16;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses any form of location sensor or measurement for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_LOCATION = 32;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses any form of eye biometrics for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_EYEPRINT = 64;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses a drawn pattern for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_PATTERN = 128;
|
||||
/**
|
||||
* This flag must be set if the authenticator uses any measurement of a full hand (including palm-print, hand
|
||||
* geometry or vein geometry) for user verification.
|
||||
*/
|
||||
public static final int USER_VERIFY_HANDPRINT = 256;
|
||||
/**
|
||||
* This flag must be set if the authenticator will respond without any user interaction (e.g. Silent Authenticator).
|
||||
*/
|
||||
public static final int USER_VERIFY_NONE = 512;
|
||||
/**
|
||||
* If an authenticator sets multiple flags for user verification types, it may also set this flag to indicate that
|
||||
* all verification methods will be enforced (e.g. faceprint AND voiceprint). If flags for multiple user
|
||||
* verification methods are set and this flag is not set, verification with only one is necessary (e.g. fingerprint
|
||||
* OR passcode).
|
||||
*/
|
||||
public static final int USER_VERIFY_ALL = 1024;
|
||||
|
||||
private UserVerificationMethods() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
public enum UserVerificationRequirement implements Parcelable {
|
||||
REQUIRED("required"),
|
||||
PREFERRED("preferred"),
|
||||
DISCOURAGED("discouraged");
|
||||
|
||||
private final String value;
|
||||
|
||||
UserVerificationRequirement(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(toString());
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static UserVerificationRequirement fromString(String attachment) throws UnsupportedUserVerificationRequirementException {
|
||||
for (UserVerificationRequirement value : values()) {
|
||||
if (value.value.equals(attachment)) return value;
|
||||
}
|
||||
throw new UnsupportedUserVerificationRequirementException("User verification requirement " + attachment + " not supported");
|
||||
}
|
||||
|
||||
public static Creator<UserVerificationRequirement> CREATOR = new Creator<UserVerificationRequirement>() {
|
||||
@Override
|
||||
public UserVerificationRequirement createFromParcel(Parcel source) {
|
||||
try {
|
||||
return UserVerificationRequirement.fromString(source.readString());
|
||||
} catch (UnsupportedUserVerificationRequirementException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVerificationRequirement[] newArray(int size) {
|
||||
return new UserVerificationRequirement[size];
|
||||
}
|
||||
};
|
||||
|
||||
public static class UnsupportedUserVerificationRequirementException extends Exception {
|
||||
public UnsupportedUserVerificationRequirementException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents up to three user verification methods used by the authenticator.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class UvmEntries extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUvmEntryList")
|
||||
@Nullable
|
||||
private List<UvmEntry> uvmEntryList;
|
||||
|
||||
@Nullable
|
||||
public List<UvmEntry> getUvmEntryList() {
|
||||
return uvmEntryList;
|
||||
}
|
||||
|
||||
@Constructor
|
||||
UvmEntries(@Param(1) @Nullable List<UvmEntry> uvmEntryList) {
|
||||
this.uvmEntryList = uvmEntryList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof UvmEntries)) return false;
|
||||
|
||||
UvmEntries that = (UvmEntries) o;
|
||||
|
||||
if (uvmEntryList == null && that.uvmEntryList == null) return true;
|
||||
if (uvmEntryList == null || that.uvmEntryList == null) return false;
|
||||
return uvmEntryList.containsAll(that.uvmEntryList) && that.uvmEntryList.containsAll(uvmEntryList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{new HashSet<>(uvmEntryList)});
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link UvmEntries}
|
||||
*/
|
||||
public static class Builder {
|
||||
private List<UvmEntry> uvmEntryList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The constructor of {@link UvmEntries.Builder}.
|
||||
*/
|
||||
public Builder() {
|
||||
}
|
||||
|
||||
public Builder addAll(@NonNull List<UvmEntry> uvmEntryList) {
|
||||
if (this.uvmEntryList.size() + uvmEntryList.size() > 3) throw new IllegalStateException();
|
||||
this.uvmEntryList.addAll(uvmEntryList);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addUvmEntry(@Nullable UvmEntry uvmEntry) {
|
||||
if (uvmEntryList.size() >= 3) throw new IllegalStateException();
|
||||
uvmEntryList.add(uvmEntry);
|
||||
return this;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public UvmEntries build() {
|
||||
return new UvmEntries(new ArrayList<>(uvmEntryList));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static SafeParcelableCreatorAndWriter<UvmEntries> CREATOR = findCreator(UvmEntries.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.fido2.api.common;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.Hide;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a single User Verification Method Entry
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class UvmEntry extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getUserVerificationMethod")
|
||||
private int userVerificationMethod;
|
||||
@Field(value = 2, getterName = "getKeyProtectionType")
|
||||
private short keyProtectionType;
|
||||
@Field(value = 3, getterName = "getMatcherProtectionType")
|
||||
private short matcherProtectionType;
|
||||
|
||||
@Constructor
|
||||
UvmEntry(@Param(1) int userVerificationMethod, @Param(2) short keyProtectionType, @Param(3) short matcherProtectionType) {
|
||||
this.userVerificationMethod = userVerificationMethod;
|
||||
this.keyProtectionType = keyProtectionType;
|
||||
this.matcherProtectionType = matcherProtectionType;
|
||||
}
|
||||
|
||||
public int getUserVerificationMethod() {
|
||||
return userVerificationMethod;
|
||||
}
|
||||
|
||||
public short getKeyProtectionType() {
|
||||
return keyProtectionType;
|
||||
}
|
||||
|
||||
public short getMatcherProtectionType() {
|
||||
return matcherProtectionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof UvmEntry)) return false;
|
||||
|
||||
UvmEntry uvmEntry = (UvmEntry) o;
|
||||
|
||||
if (userVerificationMethod != uvmEntry.userVerificationMethod) return false;
|
||||
if (keyProtectionType != uvmEntry.keyProtectionType) return false;
|
||||
return matcherProtectionType == uvmEntry.matcherProtectionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new Object[]{userVerificationMethod, keyProtectionType, matcherProtectionType});
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link UvmEntry}.
|
||||
*/
|
||||
public static class Builder {
|
||||
private int userVerificationMethod;
|
||||
private short keyProtectionType;
|
||||
private short matcherProtectionType;
|
||||
|
||||
public Builder setUserVerificationMethod(int userVerificationMethod) {
|
||||
this.userVerificationMethod = userVerificationMethod;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setKeyProtectionType(short keyProtectionType) {
|
||||
this.keyProtectionType = keyProtectionType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMatcherProtectionType(short matcherProtectionType) {
|
||||
this.matcherProtectionType = matcherProtectionType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UvmEntry build() {
|
||||
return new UvmEntry(userVerificationMethod, keyProtectionType, matcherProtectionType);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
@Hide
|
||||
public static final SafeParcelableCreatorAndWriter<UvmEntry> CREATOR = findCreator(UvmEntry.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.sourcedevice;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.HasApiKey;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* The entry point for interacting with the FIDO SourceDirectTransfer APIs.
|
||||
*/
|
||||
@PublicApi
|
||||
public interface SourceDirectTransferClient extends HasApiKey<Api.ApiOptions.NoOptions> {
|
||||
/**
|
||||
* The key used to retrieve {@link SourceDirectTransferResult} from the intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link PendingIntent} returned by
|
||||
* {@link #startDirectTransfer(SourceStartDirectTransferOptions, ParcelFileDescriptor, ParcelFileDescriptor)}.
|
||||
*/
|
||||
String KEY_SOURCE_DIRECT_TRANSFER_RESULT = "source_direct_transfer_result";
|
||||
|
||||
/**
|
||||
* Retrieves {@link SourceDirectTransferResult} from the intent received by
|
||||
* {@link Activity#onActivityResult(int, int, Intent)} after launching {@link PendingIntent} returned by
|
||||
* {@link #startDirectTransfer(SourceStartDirectTransferOptions, ParcelFileDescriptor, ParcelFileDescriptor)}.
|
||||
*/
|
||||
SourceDirectTransferResult getSourceDirectTransferResultFromIntent(Intent intent) throws ApiException;
|
||||
|
||||
/**
|
||||
* Creates a Task with {@link PendingIntent}, which when started, will start direct transfer.
|
||||
*
|
||||
* @param input read side of pipe from the other device.
|
||||
* @param output write side of pipe to the other device.
|
||||
*/
|
||||
Task<PendingIntent> startDirectTransfer(SourceStartDirectTransferOptions options, ParcelFileDescriptor input, ParcelFileDescriptor output);
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.sourcedevice;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
import org.microg.gms.common.PublicApi;
|
||||
|
||||
/**
|
||||
* Result returned from the UI activity in {@link Activity#onActivityResult(int, int, Intent)} after the direct transfer finishes.
|
||||
*/
|
||||
@PublicApi
|
||||
@SafeParcelable.Class
|
||||
public class SourceDirectTransferResult extends AbstractSafeParcelable {
|
||||
@Field(value = 1, getterName = "getStatus")
|
||||
private Status status;
|
||||
|
||||
private SourceDirectTransferResult() {
|
||||
}
|
||||
|
||||
@Constructor
|
||||
public SourceDirectTransferResult(@Param(1) Status status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link Status} from the returned {@link SourceDirectTransferResult}.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<SourceDirectTransferResult> CREATOR = findCreator(SourceDirectTransferResult.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.sourcedevice;
|
||||
|
||||
import android.os.Parcel;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.google.android.gms.common.internal.safeparcel.AbstractSafeParcelable;
|
||||
import com.google.android.gms.common.internal.safeparcel.SafeParcelableCreatorAndWriter;
|
||||
|
||||
/**
|
||||
* Customized options to start direct transfer.
|
||||
*/
|
||||
public class SourceStartDirectTransferOptions extends AbstractSafeParcelable {
|
||||
/**
|
||||
* Value of the callerType if the caller is unknown.
|
||||
*/
|
||||
public static final int CALLER_TYPE_UNKNOWN = 0;
|
||||
/**
|
||||
* Value of the callerType if the caller is browser.
|
||||
*/
|
||||
public static final int CALLER_TYPE_BROWSER = 2;
|
||||
|
||||
@Field(value = 1, getterName = "getCallerType")
|
||||
private int callerType;
|
||||
|
||||
private SourceStartDirectTransferOptions() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for the {@link SourceStartDirectTransferOptions}.
|
||||
*/
|
||||
public SourceStartDirectTransferOptions(@Param(1) int callerType) {
|
||||
this.callerType = callerType;
|
||||
}
|
||||
|
||||
public int getCallerType() {
|
||||
return callerType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
CREATOR.writeToParcel(this, dest, flags);
|
||||
}
|
||||
|
||||
public static final SafeParcelableCreatorAndWriter<SourceStartDirectTransferOptions> CREATOR = findCreator(SourceStartDirectTransferOptions.class);
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.u2f;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
||||
import com.google.android.gms.common.api.Api;
|
||||
import com.google.android.gms.common.api.GoogleApi;
|
||||
import com.google.android.gms.fido.Fido;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
/**
|
||||
* The entry point for interacting with the regular app U2F APIs.
|
||||
* <p>
|
||||
* U2F (Universal Second Factor) is the name of the Security Key protocol in FIDO (Fast IDentity Online), which is the
|
||||
* industry alliance where Security Keys are being standardized.
|
||||
*
|
||||
* @deprecated Please use {@link Fido} APIs instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class U2fApiClient extends GoogleApi<Api.ApiOptions.NoOptions> {
|
||||
private static final Api<Api.ApiOptions.NoOptions> API = null;
|
||||
|
||||
/**
|
||||
* @param activity Calling {@link Activity}
|
||||
*/
|
||||
public U2fApiClient(Activity activity) {
|
||||
super(activity, API, Api.ApiOptions.NO_OPTIONS);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context The {@link Context} of the calling application
|
||||
*/
|
||||
public U2fApiClient(Context context) {
|
||||
super(context, API, Api.ApiOptions.NO_OPTIONS);
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Creates a Task with {@link U2fPendingIntent}. When this Task object starts, it issues a U2F registration request,
|
||||
// * which is done once per U2F device per account for associating the new U2F device with that account.
|
||||
// *
|
||||
// * @param requestParams for the registration request
|
||||
// * @return Task with PendingIntent to launch U2F registration request
|
||||
// */
|
||||
// public Task<U2fPendingIntent> getRegisterIntent(RegisterRequestParams requestParams) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Creates a Task with U2fPendingIntent. When this Task object starts, it issues a U2F signing request for a relying party to authenticate a user.
|
||||
// *
|
||||
// * @param requestParams for the sign request
|
||||
// * @return Task with PendingIntent to launch U2F signature request
|
||||
// */
|
||||
// public Task<U2fPendingIntent> getSignIntent(SignRequestParams requestParams) {
|
||||
// throw new UnsupportedOperationException();
|
||||
// }
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
* Notice: Portions of this file are reproduced from work created and shared by Google and used
|
||||
* according to terms described in the Creative Commons 4.0 Attribution License.
|
||||
* See https://developers.google.com/readme/policies for details.
|
||||
*/
|
||||
|
||||
package com.google.android.gms.fido.u2f;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentSender;
|
||||
|
||||
import com.google.android.gms.fido.Fido;
|
||||
|
||||
/**
|
||||
* Interface for apps to launch a {@link PendingIntent}.
|
||||
*
|
||||
* @deprecated Please use {@link Fido} APIs instead.
|
||||
*/
|
||||
public interface U2fPendingIntent {
|
||||
/**
|
||||
* Returns true if an {@link Activity} has a {@link PendingIntent}.
|
||||
*/
|
||||
boolean hasPendingIntent();
|
||||
|
||||
/**
|
||||
* Launches the PendingIntent.
|
||||
*
|
||||
* @param activity An Activity context to use to launch the intent. The activity's onActivityResult method will
|
||||
* be invoked after the user is done.
|
||||
* @param requestCode The request code to pass to onActivityResult.
|
||||
* @throws IllegalStateException if hasPendingIntent is false
|
||||
* @throws IntentSender.SendIntentException If the resolution intent has been canceled or is no longer able to
|
||||
* execute the request.
|
||||
*/
|
||||
void launchPendingIntent(Activity activity, int requestCode);
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.fido.fido2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.PublicKeyCredentialRequestOptions;
|
||||
import com.google.android.gms.fido.fido2.internal.regular.IFido2AppCallbacks;
|
||||
import com.google.android.gms.fido.fido2.internal.regular.IFido2AppService;
|
||||
|
||||
import org.microg.gms.common.GmsClient;
|
||||
import org.microg.gms.common.GmsService;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
|
||||
public class Fido2GmsClient extends GmsClient<IFido2AppService> {
|
||||
public Fido2GmsClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
super(context, callbacks, connectionFailedListener, GmsService.FIDO2_REGULAR.ACTION);
|
||||
serviceId = GmsService.FIDO2_REGULAR.SERVICE_ID;
|
||||
}
|
||||
|
||||
public void getRegisterPendingIntent(IFido2AppCallbacks callbacks, PublicKeyCredentialCreationOptions options) throws RemoteException {
|
||||
getServiceInterface().getRegisterPendingIntent(callbacks, options);
|
||||
}
|
||||
|
||||
public void getSignPendingIntent(IFido2AppCallbacks callbacks, PublicKeyCredentialRequestOptions options) throws RemoteException {
|
||||
getServiceInterface().getSignPendingIntent(callbacks, options);
|
||||
}
|
||||
|
||||
public void isUserVerifyingPlatformAuthenticatorAvailable(IBooleanCallback callback) throws RemoteException {
|
||||
getServiceInterface().isUserVerifyingPlatformAuthenticatorAvailable(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IFido2AppService interfaceFromBinder(IBinder binder) {
|
||||
return IFido2AppService.Stub.asInterface(binder);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.fido.fido2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.IntentSender;
|
||||
|
||||
import com.google.android.gms.fido.fido2.Fido2PendingIntent;
|
||||
|
||||
public class Fido2PendingIntentImpl implements Fido2PendingIntent {
|
||||
private PendingIntent pendingIntent;
|
||||
|
||||
public Fido2PendingIntentImpl(PendingIntent pendingIntent) {
|
||||
this.pendingIntent = pendingIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPendingIntent() {
|
||||
return pendingIntent != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchPendingIntent(Activity activity, int requestCode) throws IntentSender.SendIntentException {
|
||||
if (!hasPendingIntent()) throw new IllegalStateException("No PendingIntent available");
|
||||
activity.startIntentSenderForResult(pendingIntent.getIntentSender(), requestCode, null, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022 microG Project Team
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package org.microg.gms.fido.fido2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import com.google.android.gms.fido.fido2.api.IBooleanCallback;
|
||||
import com.google.android.gms.fido.fido2.api.ICredentialListCallback;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialCreationOptions;
|
||||
import com.google.android.gms.fido.fido2.api.common.BrowserPublicKeyCredentialRequestOptions;
|
||||
import com.google.android.gms.fido.fido2.internal.privileged.IFido2PrivilegedCallbacks;
|
||||
import com.google.android.gms.fido.fido2.internal.privileged.IFido2PrivilegedService;
|
||||
|
||||
import org.microg.gms.common.GmsClient;
|
||||
import org.microg.gms.common.GmsService;
|
||||
import com.google.android.gms.common.api.internal.ConnectionCallbacks;
|
||||
import com.google.android.gms.common.api.internal.OnConnectionFailedListener;
|
||||
|
||||
public class Fido2PrivilegedGmsClient extends GmsClient<IFido2PrivilegedService> {
|
||||
public Fido2PrivilegedGmsClient(Context context, ConnectionCallbacks callbacks, OnConnectionFailedListener connectionFailedListener) {
|
||||
super(context, callbacks, connectionFailedListener, GmsService.FIDO2_PRIVILEGED.ACTION);
|
||||
serviceId = GmsService.FIDO2_PRIVILEGED.SERVICE_ID;
|
||||
}
|
||||
|
||||
public void getRegisterPendingIntent(IFido2PrivilegedCallbacks callbacks, BrowserPublicKeyCredentialCreationOptions options) throws RemoteException {
|
||||
getServiceInterface().getRegisterPendingIntent(callbacks, options);
|
||||
}
|
||||
|
||||
public void getSignPendingIntent(IFido2PrivilegedCallbacks callbacks, BrowserPublicKeyCredentialRequestOptions options) throws RemoteException {
|
||||
getServiceInterface().getSignPendingIntent(callbacks, options);
|
||||
}
|
||||
|
||||
public void isUserVerifyingPlatformAuthenticatorAvailable(IBooleanCallback callback) throws RemoteException {
|
||||
getServiceInterface().isUserVerifyingPlatformAuthenticatorAvailable(callback);
|
||||
}
|
||||
|
||||
public void getCredentialList(ICredentialListCallback callbacks, String rpId) throws RemoteException {
|
||||
getServiceInterface().getCredentialList(callbacks, rpId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IFido2PrivilegedService interfaceFromBinder(IBinder binder) {
|
||||
return IFido2PrivilegedService.Stub.asInterface(binder);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue