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

Commit 6b8617ce authored by David Zeuthen's avatar David Zeuthen Committed by Automerger Merge Worker
Browse files

identity: Add support for ECDSA auth and don't require session encryption. am: 55f62fc1

parents ad76a152 55f62fc1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -37682,6 +37682,7 @@ package android.security.identity {
  public abstract class CredentialDataResult {
    method @Nullable public abstract byte[] getDeviceMac();
    method @NonNull public abstract byte[] getDeviceNameSpaces();
    method @Nullable public byte[] getDeviceSignature();
    method @NonNull public abstract android.security.identity.CredentialDataResult.Entries getDeviceSignedEntries();
    method @NonNull public abstract android.security.identity.CredentialDataResult.Entries getIssuerSignedEntries();
    method @NonNull public abstract byte[] getStaticAuthenticationData();
+24 −0
Original line number Diff line number Diff line
@@ -105,6 +105,30 @@ public abstract class CredentialDataResult {
     */
    public abstract @Nullable byte[] getDeviceMac();

    /**
     * Returns a signature over the {@code DeviceAuthenticationBytes} CBOR
     * specified in {@link #getDeviceNameSpaces()}, to prove to the reader that the data
     * is from a trusted credential.
     *
     * <p>The signature is made using the authentication private key. See section 9.1.3.4 of
     * ISO/IEC 18013-5:2021 for details of this operation.
     *
     * <p>If the session transcript or reader ephemeral key wasn't set on the {@link
     * PresentationSession} used to obtain this data no signature will be produced and this method
     * will return {@code null}.
     *
     * <p>This is only implemented in feature version 202301 or later. If not implemented, the call
     * fails with {@link UnsupportedOperationException}. See
     * {@link android.content.pm.PackageManager#FEATURE_IDENTITY_CREDENTIAL_HARDWARE} for known
     * feature versions.
     *
     * @return A COSE_Sign1 structure as described above or {@code null} if the conditions
     *     specified above are not met.
     */
    public @Nullable byte[] getDeviceSignature() {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns the static authentication data associated with the dynamic authentication
     * key used to MAC the data returned by {@link #getDeviceNameSpaces()}.
+5 −0
Original line number Diff line number Diff line
@@ -46,6 +46,11 @@ class CredstoreCredentialDataResult extends CredentialDataResult {
        return mDeviceSignedResult.getMessageAuthenticationCode();
    }

    @Override
    public @Nullable byte[] getDeviceSignature() {
        return mDeviceSignedResult.getSignature();
    }

    @Override
    public @NonNull byte[] getStaticAuthenticationData() {
        return mDeviceSignedResult.getStaticAuthenticationData();
+11 −2
Original line number Diff line number Diff line
@@ -60,16 +60,19 @@ class CredstoreIdentityCredential extends IdentityCredential {
    private Context mContext;
    private ICredential mBinder;
    private CredstorePresentationSession mSession;
    private int mFeatureVersion;

    CredstoreIdentityCredential(Context context, String credentialName,
            @IdentityCredentialStore.Ciphersuite int cipherSuite,
            ICredential binder,
            @Nullable CredstorePresentationSession session) {
            @Nullable CredstorePresentationSession session,
            int featureVersion) {
        mContext = context;
        mCredentialName = credentialName;
        mCipherSuite = cipherSuite;
        mBinder = binder;
        mSession = session;
        mFeatureVersion = featureVersion;
    }

    private KeyPair mEphemeralKeyPair = null;
@@ -347,12 +350,18 @@ class CredstoreIdentityCredential extends IdentityCredential {
            }
        }

        byte[] signature = resultParcel.signature;
        if (signature != null && signature.length == 0) {
            signature = null;
        }

        byte[] mac = resultParcel.mac;
        if (mac != null && mac.length == 0) {
            mac = null;
        }
        CredstoreResultData.Builder resultDataBuilder = new CredstoreResultData.Builder(
                resultParcel.staticAuthenticationData, resultParcel.deviceNameSpaces, mac);
                mFeatureVersion, resultParcel.staticAuthenticationData,
                resultParcel.deviceNameSpaces, mac, signature);

        for (ResultNamespaceParcel resultNamespaceParcel : resultParcel.resultNamespaces) {
            for (ResultEntryParcel resultEntryParcel : resultNamespaceParcel.entries) {
+23 −3
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package android.security.identity;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.security.GenerateRkpKey;
@@ -30,10 +32,28 @@ class CredstoreIdentityCredentialStore extends IdentityCredentialStore {

    private Context mContext = null;
    private ICredentialStore mStore = null;
    private int mFeatureVersion;

    static int getFeatureVersion(@NonNull Context context) {
        PackageManager pm = context.getPackageManager();
        if (pm.hasSystemFeature(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
            FeatureInfo[] infos = pm.getSystemAvailableFeatures();
            for (int n = 0; n < infos.length; n++) {
                FeatureInfo info = infos[n];
                if (info.name.equals(PackageManager.FEATURE_IDENTITY_CREDENTIAL_HARDWARE)) {
                    return info.version;
                }
            }
        }
        // Use of the system feature is not required since Android 12. So for Android 11
        // return 202009 which is the feature version shipped with Android 11.
        return 202009;
    }

    private CredstoreIdentityCredentialStore(@NonNull Context context, ICredentialStore store) {
        mContext = context;
        mStore = store;
        mFeatureVersion = getFeatureVersion(mContext);
    }

    static CredstoreIdentityCredentialStore getInstanceForType(@NonNull Context context,
@@ -139,8 +159,7 @@ class CredstoreIdentityCredentialStore extends IdentityCredentialStore {
            ICredential credstoreCredential;
            credstoreCredential = mStore.getCredentialByName(credentialName, cipherSuite);
            return new CredstoreIdentityCredential(mContext, credentialName, cipherSuite,
                    credstoreCredential,
                    null);
                    credstoreCredential, null, mFeatureVersion);
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
@@ -182,7 +201,8 @@ class CredstoreIdentityCredentialStore extends IdentityCredentialStore {
            throws CipherSuiteNotSupportedException {
        try {
            ISession credstoreSession = mStore.createPresentationSession(cipherSuite);
            return new CredstorePresentationSession(mContext, cipherSuite, this, credstoreSession);
            return new CredstorePresentationSession(mContext, cipherSuite, this, credstoreSession,
                                                    mFeatureVersion);
        } catch (android.os.RemoteException e) {
            throw new RuntimeException("Unexpected RemoteException ", e);
        } catch (android.os.ServiceSpecificException e) {
Loading