summaryrefslogtreecommitdiff
path: root/ts43authentication
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2024-06-13 10:50:14 -0700
committerXin Li <delphij@google.com>2024-06-13 10:50:14 -0700
commit4ee1c609cc1c294a9e194885a79b88e5625bd31f (patch)
tree84393f6c1324e85d1c206824eec1c4d597d23bda /ts43authentication
parent18112deb7946fcec48466815c486d584f688a95b (diff)
parentf1961e4a8a19e8c8eb0de3fceee0bf1b4d8e9871 (diff)
downloadgsma_services-master.tar.gz
Merge Android 14 QPR3 to AOSP mainHEADmastermain
Bug: 346855327 Merged-In: Iba24ee2291cc4f6c6796e86383235e6ed45bb6c2 Change-Id: I2c67a052d0f36d69b98cbaa84a18e7c86a25a5f3
Diffstat (limited to 'ts43authentication')
-rw-r--r--ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java44
-rw-r--r--ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java87
2 files changed, 102 insertions, 29 deletions
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java
new file mode 100644
index 0000000..37ad354
--- /dev/null
+++ b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.libraries.ts43authentication;
+
+/**
+ * Callback interface intended for use when an TS.43 authentication request may result in a failure.
+ * This interface may be used in cases where an asynchronous API may complete either with a value
+ * or with a {@link Throwable} that indicates an error.
+ * Functionally the same as an OutcomeReceiver, but creating a new class for backwards compatibility
+ * on devices with SDK < 31.
+ *
+ * @param <R> The type of the result that's being sent.
+ * @param <E> The type of the {@link Throwable} that contains more information about the error.
+ */
+public interface AuthenticationOutcomeReceiver <R, E extends Throwable> {
+ /**
+ * Called when the asynchronous operation succeeds and delivers a result value.
+ *
+ * @param result The value delivered by the asynchronous operation.
+ */
+ void onResult(R result);
+
+ /**
+ * Called when the asynchronous operation fails. The mode of failure is indicated by the
+ * {@link Throwable} passed as an argument to this method.
+ *
+ * @param error A subclass of {@link Throwable} with more details about the error that occurred.
+ */
+ default void onError(E error) {}
+}
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
index be3931d..da45671 100644
--- a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
+++ b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
@@ -22,10 +22,10 @@ import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.content.pm.SigningInfo;
import android.os.Binder;
+import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.OutcomeReceiver;
import android.os.PersistableBundle;
import android.telephony.SubscriptionInfo;
import android.util.Log;
@@ -43,7 +43,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.ArrayList;
-import java.util.HexFormat;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.ReentrantLock;
@@ -131,12 +130,12 @@ public class Ts43AuthenticationLibrary extends Handler {
@Nullable private final String mEntitlementVersion;
private final String mAppId;
private final Executor mExecutor;
- private final OutcomeReceiver<
+ private final AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback;
private EapAkaAuthenticationRequest(String appName, @Nullable String appVersion,
int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion,
- String appId, Executor executor, OutcomeReceiver<
+ String appId, Executor executor, AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
mAppName = appName;
mAppVersion = appVersion;
@@ -157,12 +156,12 @@ public class Ts43AuthenticationLibrary extends Handler {
@Nullable private final String mEntitlementVersion;
private final String mAppId;
private final Executor mExecutor;
- private final OutcomeReceiver<URL, AuthenticationException> mCallback;
+ private final AuthenticationOutcomeReceiver<URL, AuthenticationException> mCallback;
private OidcAuthenticationServerRequest(String appName, @Nullable String appVersion,
int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion,
String appId, Executor executor,
- OutcomeReceiver<URL, AuthenticationException> callback) {
+ AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) {
mAppName = appName;
mAppVersion = appVersion;
mSlotIndex = slotIndex;
@@ -179,11 +178,12 @@ public class Ts43AuthenticationLibrary extends Handler {
@Nullable private final String mEntitlementVersion;
private final URL mAesUrl;
private final Executor mExecutor;
- private final OutcomeReceiver<
+ private final AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback;
private OidcAuthenticationRequest(URL entitlementServerAddress,
- @Nullable String entitlementVersion, URL aesUrl, Executor executor, OutcomeReceiver<
+ @Nullable String entitlementVersion, URL aesUrl, Executor executor,
+ AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
mEntitlementServerAddress = entitlementServerAddress;
mEntitlementVersion = entitlementVersion;
@@ -216,14 +216,17 @@ public class Ts43AuthenticationLibrary extends Handler {
* Refer to GSMA Service Entitlement Configuration section 2.3.
* @param executor The executor on which the callback will be called.
* @param callback The callback to receive the results of the authentication request.
- * If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return
- * a {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
- * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
+ * If authentication is successful,
+ * {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a
+ * {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
+ * If the authentication fails,
+ * {@link AuthenticationOutcomeReceiver#onError(Throwable)} will return an
* {@link AuthenticationException} with the failure details.
*/
public void requestEapAkaAuthentication(PersistableBundle configs, String packageName,
@Nullable String appVersion, int slotIndex, URL entitlementServerAddress,
- @Nullable String entitlementVersion, String appId, Executor executor, OutcomeReceiver<
+ @Nullable String entitlementVersion, String appId, Executor executor,
+ AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
@@ -245,8 +248,8 @@ public class Ts43AuthenticationLibrary extends Handler {
* The client should present the content of the URL to the user to continue the authentication
* process. After receiving a response from the authentication server, the client can call
* {@link #requestOidcAuthentication(
- * PersistableBundle, String, URL, String, URL, Executor, OutcomeReceiver)} to get the
- * authentication token.
+ * PersistableBundle, String, URL, String, URL, Executor, AuthenticationOutcomeReceiver)} to get
+ * the authentication token.
*
* @param configs The configurations that should be applied to this authentication request.
* The keys of the bundle must be in {@link ConfigurationKey}.
@@ -267,18 +270,18 @@ public class Ts43AuthenticationLibrary extends Handler {
* Refer to GSMA Service Entitlement Configuration section 2.3.
* @param executor The executor on which the callback will be called.
* @param callback The callback to receive the results of the authentication server request.
- * If the request is successful, {@link OutcomeReceiver#onResult(Object)} will return a
- * {@link URL} with all the required parameters for the client to launch a user interface
- * for users to complete the authentication process. The parameters in URL include
- * {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}.
- * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
- * {@link AuthenticationException} with the failure details.
+ * If the request is successful, {@link AuthenticationOutcomeReceiver#onResult(Object)}
+ * will return a {@link URL} with all the required parameters for the client to launch a
+ * user interface for users to complete the authentication process. The parameters in URL
+ * include {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}.
+ * If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)}
+ * will return an {@link AuthenticationException} with the failure details.
*/
public void requestOidcAuthenticationServer(PersistableBundle configs,
String packageName, @Nullable String appVersion, int slotIndex,
URL entitlementServerAddress, @Nullable String entitlementVersion,
String appId, Executor executor,
- OutcomeReceiver<URL, AuthenticationException> callback) {
+ AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) {
String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
if (isCallingPackageAllowed(allowedPackageInfo, packageName, certificate)) {
@@ -309,15 +312,16 @@ public class Ts43AuthenticationLibrary extends Handler {
* URL include the OIDC authentication code {@code code} and {@code state}.
* @param executor The executor on which the callback will be called.
* @param callback The callback to receive the results of the authentication request.
- * If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return
- * a {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
- * If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
- * {@link AuthenticationException} with the failure details.
+ * If authentication is successful,
+ * {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a
+ * {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
+ * If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)}
+ * will return an {@link AuthenticationException} with the failure details.
*/
public void requestOidcAuthentication(PersistableBundle configs,
String packageName, URL entitlementServerAddress,
@Nullable String entitlementVersion, URL aesUrl, Executor executor,
- OutcomeReceiver<
+ AuthenticationOutcomeReceiver<
Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
@@ -372,7 +376,7 @@ public class Ts43AuthenticationLibrary extends Handler {
for (Signature signature : signatures) {
byte[] signatureHash = md.digest(signature.toByteArray());
for (String certificate : allowedCertificates) {
- byte[] certificateHash = HexFormat.of().parseHex(certificate);
+ byte[] certificateHash = hexStringToBytes(certificate);
if (Arrays.equals(signatureHash, certificateHash)) {
Log.d(TAG, "Found matching certificate for package " + packageName + ": "
+ certificate);
@@ -412,8 +416,14 @@ public class Ts43AuthenticationLibrary extends Handler {
@Nullable private Signature[] getMainPackageSignatures(String packageName) {
PackageInfo packageInfo;
try {
- packageInfo = mPackageManager.getPackageInfo(packageName,
- PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES));
+ if (Build.VERSION.SDK_INT < 33) {
+ packageInfo = mPackageManager.getPackageInfo(packageName,
+ PackageManager.GET_SIGNING_CERTIFICATES);
+ } else {
+ packageInfo = mPackageManager.getPackageInfo(packageName,
+ PackageManager.PackageInfoFlags.of(
+ PackageManager.GET_SIGNING_CERTIFICATES));
+ }
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Unable to find package name: " + packageName);
return null;
@@ -439,6 +449,25 @@ public class Ts43AuthenticationLibrary extends Handler {
return signatures;
}
+ @Nullable private byte[] hexStringToBytes(@Nullable String hex) {
+ if (hex == null) {
+ return null;
+ }
+
+ int length = hex.length();
+ byte[] ret = new byte[length / 2];
+
+ for (int i = 0; i < length; i += 2) {
+ ret[i / 2] =
+ (byte) ((hexCharToInt(hex.charAt(i)) << 4) | hexCharToInt(hex.charAt(i + 1)));
+ }
+ return ret;
+ }
+
+ private int hexCharToInt(char hex) {
+ return Integer.parseInt(String.valueOf(hex), 16);
+ }
+
private boolean isCallingPackageAllowed(@Nullable String[] allowedPackageInfo,
String packageName, @Nullable String certificate) {
// Check that the package name matches that of the calling package.