Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9502700d authored by David Zeuthen's avatar David Zeuthen Committed by Automerger Merge Worker
Browse files

Merge "Identity Credential: API changes for Android 12" am: 40d66357 am:...

Merge "Identity Credential: API changes for Android 12" am: 40d66357 am: 6252f82f am: 581bf34d am: 5147877a

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1464362

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ib7d7b137a0f396c6d2f332873f865c94923f5367
parents 32a4d8e2 5147877a
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -12344,6 +12344,8 @@ package android.content.pm {
    field public static final String FEATURE_GAMEPAD = "android.hardware.gamepad";
    field public static final String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors";
    field public static final String FEATURE_HOME_SCREEN = "android.software.home_screen";
    field public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE = "android.hardware.identity_credential";
    field public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS = "android.hardware.identity_credential_direct_access";
    field public static final String FEATURE_INPUT_METHODS = "android.software.input_methods";
    field public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels";
    field public static final String FEATURE_IRIS = "android.hardware.biometrics.iris";
@@ -36716,15 +36718,20 @@ package android.security.identity {
  public abstract class IdentityCredential {
    method @NonNull public abstract java.security.KeyPair createEphemeralKeyPair();
    method @NonNull public abstract byte[] decryptMessageFromReader(@NonNull byte[]) throws android.security.identity.MessageDecryptionException;
    method @NonNull public byte[] delete(@NonNull byte[]);
    method @NonNull public abstract byte[] encryptMessageToReader(@NonNull byte[]);
    method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getAuthKeysNeedingCertification();
    method @NonNull public abstract int[] getAuthenticationDataUsageCount();
    method @NonNull public abstract java.util.Collection<java.security.cert.X509Certificate> getCredentialKeyCertificateChain();
    method @NonNull public abstract android.security.identity.ResultData getEntries(@Nullable byte[], @NonNull java.util.Map<java.lang.String,java.util.Collection<java.lang.String>>, @Nullable byte[], @Nullable byte[]) throws android.security.identity.EphemeralPublicKeyNotFoundException, android.security.identity.InvalidReaderSignatureException, android.security.identity.InvalidRequestMessageException, android.security.identity.NoAuthenticationKeyAvailableException, android.security.identity.SessionTranscriptMismatchException;
    method @NonNull public byte[] proveOwnership(@NonNull byte[]);
    method public abstract void setAllowUsingExhaustedKeys(boolean);
    method public void setAllowUsingExpiredKeys(boolean);
    method public abstract void setAvailableAuthenticationKeys(int, int);
    method public abstract void setReaderEphemeralPublicKey(@NonNull java.security.PublicKey) throws java.security.InvalidKeyException;
    method public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
    method @Deprecated public abstract void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
    method public void storeStaticAuthenticationData(@NonNull java.security.cert.X509Certificate, @NonNull java.time.Instant, @NonNull byte[]) throws android.security.identity.UnknownAuthenticationKeyException;
    method @NonNull public byte[] update(@NonNull android.security.identity.PersonalizationData);
  }
  public class IdentityCredentialException extends java.lang.Exception {
@@ -36734,7 +36741,7 @@ package android.security.identity {
  public abstract class IdentityCredentialStore {
    method @NonNull public abstract android.security.identity.WritableIdentityCredential createCredential(@NonNull String, @NonNull String) throws android.security.identity.AlreadyPersonalizedException, android.security.identity.DocTypeNotSupportedException;
    method @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
    method @Deprecated @Nullable public abstract byte[] deleteCredentialByName(@NonNull String);
    method @Nullable public abstract android.security.identity.IdentityCredential getCredentialByName(@NonNull String, int) throws android.security.identity.CipherSuiteNotSupportedException;
    method @Nullable public static android.security.identity.IdentityCredentialStore getDirectAccessInstance(@NonNull android.content.Context);
    method @Nullable public static android.security.identity.IdentityCredentialStore getInstance(@NonNull android.content.Context);
+29 −0
Original line number Diff line number Diff line
@@ -2441,6 +2441,35 @@ public abstract class PackageManager {
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_CTS = "android.software.cts";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
     * {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
     * at the given feature version.
     *
     * <p>Known feature versions include:
     * <ul>
     * <li><code>202009</code>: corresponds to the features included in the Identity Credential
     * API shipped in Android 11.
     * <li><code>202101</code>: corresponds to the features included in the Identity Credential
     * API shipped in Android 12.
     * </ul>
     */
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE =
            "android.hardware.identity_credential";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature(String, int)}: If this feature is supported, the device supports
     * {@link android.security.identity.IdentityCredentialStore} implemented in secure hardware
     * with direct access at the given feature version.
     * See {@link #FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known feature versions.
     */
    @SdkConstant(SdkConstantType.FEATURE)
    public static final String FEATURE_IDENTITY_CREDENTIAL_HARDWARE_DIRECT_ACCESS =
            "android.hardware.identity_credential_direct_access";

    /**
     * Feature for {@link #getSystemAvailableFeatures} and
     * {@link #hasSystemFeature}: The device supports one or more methods of
+84 −2
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
@@ -237,12 +238,18 @@ class CredstoreIdentityCredential extends IdentityCredential {
    }

    private boolean mAllowUsingExhaustedKeys = true;
    private boolean mAllowUsingExpiredKeys = false;

    @Override
    public void setAllowUsingExhaustedKeys(boolean allowUsingExhaustedKeys) {
        mAllowUsingExhaustedKeys = allowUsingExhaustedKeys;
    }

    @Override
    public void setAllowUsingExpiredKeys(boolean allowUsingExpiredKeys) {
        mAllowUsingExpiredKeys = allowUsingExpiredKeys;
    }

    private boolean mOperationHandleSet = false;
    private long mOperationHandle = 0;

@@ -256,7 +263,8 @@ class CredstoreIdentityCredential extends IdentityCredential {
    public long getCredstoreOperationHandle() {
        if (!mOperationHandleSet) {
            try {
                mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys);
                mOperationHandle = mBinder.selectAuthKey(mAllowUsingExhaustedKeys,
                        mAllowUsingExpiredKeys);
                mOperationHandleSet = true;
            } catch (android.os.RemoteException e) {
                throw new RuntimeException("Unexpected RemoteException ", e);
@@ -306,7 +314,8 @@ class CredstoreIdentityCredential extends IdentityCredential {
                rnsParcels,
                sessionTranscript != null ? sessionTranscript : new byte[0],
                readerSignature != null ? readerSignature : new byte[0],
                mAllowUsingExhaustedKeys);
                mAllowUsingExhaustedKeys,
                mAllowUsingExpiredKeys);
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
@@ -409,6 +418,34 @@ class CredstoreIdentityCredential extends IdentityCredential {
        }
    }

    @Override
    public void storeStaticAuthenticationData(X509Certificate authenticationKey,
            Instant expirationDate,
            byte[] staticAuthData)
            throws UnknownAuthenticationKeyException {
        try {
            AuthKeyParcel authKeyParcel = new AuthKeyParcel();
            authKeyParcel.x509cert = authenticationKey.getEncoded();
            long millisSinceEpoch = (expirationDate.getEpochSecond() * 1000)
                                    + (expirationDate.getNano() / 1000000);
            mBinder.storeStaticAuthenticationDataWithExpiration(authKeyParcel,
                    millisSinceEpoch, staticAuthData);
        } catch (CertificateEncodingException e) {
            throw new RuntimeException("Error encoding authenticationKey", e);
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            if (e.errorCode == ICredentialStore.ERROR_NOT_SUPPORTED) {
                throw new UnsupportedOperationException("Not supported", e);
            } else if (e.errorCode == ICredentialStore.ERROR_AUTHENTICATION_KEY_NOT_FOUND) {
                throw new UnknownAuthenticationKeyException(e.getMessage(), e);
            } else {
                throw new RuntimeException("Unexpected ServiceSpecificException with code "
                        + e.errorCode, e);
            }
        }
    }

    @Override
    public @NonNull int[] getAuthenticationDataUsageCount() {
        try {
@@ -421,4 +458,49 @@ class CredstoreIdentityCredential extends IdentityCredential {
                    + e.errorCode, e);
        }
    }

    @Override
    public @NonNull byte[] proveOwnership(@NonNull byte[] challenge) {
        try {
            byte[] proofOfOwnership = mBinder.proveOwnership(challenge);
            return proofOfOwnership;
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            if (e.errorCode == ICredentialStore.ERROR_NOT_SUPPORTED) {
                throw new UnsupportedOperationException("Not supported", e);
            } else {
                throw new RuntimeException("Unexpected ServiceSpecificException with code "
                        + e.errorCode, e);
            }
        }
    }

    @Override
    public @NonNull byte[] delete(@NonNull byte[] challenge) {
        try {
            byte[] proofOfDeletion = mBinder.deleteWithChallenge(challenge);
            return proofOfDeletion;
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            throw new RuntimeException("Unexpected ServiceSpecificException with code "
                    + e.errorCode, e);
        }
    }

    @Override
    public @NonNull byte[] update(@NonNull PersonalizationData personalizationData) {
        try {
            IWritableCredential binder = mBinder.update();
            byte[] proofOfProvision =
                    CredstoreWritableIdentityCredential.personalize(binder, personalizationData);
            return proofOfProvision;
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
            throw new RuntimeException("Unexpected ServiceSpecificException with code "
                    + e.errorCode, e);
        }
    }
}
+0 −1
Original line number Diff line number Diff line
@@ -162,5 +162,4 @@ class CredstoreIdentityCredentialStore extends IdentityCredentialStore {
                    + e.errorCode, e);
        }
    }

}
+8 −2
Original line number Diff line number Diff line
@@ -76,7 +76,14 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {

    @NonNull @Override
    public byte[] personalize(@NonNull PersonalizationData personalizationData) {
        return personalize(mBinder, personalizationData);
    }

    // Used by both personalize() and CredstoreIdentityCredential.update().
    //
    @NonNull
    static byte[] personalize(IWritableCredential binder,
            @NonNull PersonalizationData personalizationData) {
        Collection<AccessControlProfile> accessControlProfiles =
                personalizationData.getAccessControlProfiles();

@@ -144,7 +151,7 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
            secureUserId = getRootSid();
        }
        try {
            byte[] personalizationReceipt = mBinder.personalize(acpParcels, ensParcels,
            byte[] personalizationReceipt = binder.personalize(acpParcels, ensParcels,
                    secureUserId);
            return personalizationReceipt;
        } catch (android.os.RemoteException e) {
@@ -164,5 +171,4 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
        return rootSid;
    }


}
Loading