diff options
author | Xin Li <delphij@google.com> | 2024-06-13 10:50:14 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2024-06-13 10:50:14 -0700 |
commit | 4ee1c609cc1c294a9e194885a79b88e5625bd31f (patch) | |
tree | 84393f6c1324e85d1c206824eec1c4d597d23bda /ts43authentication | |
parent | 18112deb7946fcec48466815c486d584f688a95b (diff) | |
parent | f1961e4a8a19e8c8eb0de3fceee0bf1b4d8e9871 (diff) | |
download | gsma_services-master.tar.gz |
Bug: 346855327
Merged-In: Iba24ee2291cc4f6c6796e86383235e6ed45bb6c2
Change-Id: I2c67a052d0f36d69b98cbaa84a18e7c86a25a5f3
Diffstat (limited to 'ts43authentication')
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. |