This commit introduces a complete, software-based simulation of the key generation and attestation flow for the legacy IKeystoreService API, as used on Android 11. It refactors the KeystoreInterceptor to handle the entire multi-step transaction sequence (`generateKey`, `getKeyCharacteristics`, `exportKey`, `attestKey`) in software. A new `LegacyKeygenParameters` data class is introduced to decouple the legacy interception logic from modern data structures. This class parses arguments from the old `KeymasterArguments`, stores the state across the multi-step generation process, and acts as an adapter to the generic `CertificateGenerator` by converting the parameters to the modern `KeyMintAttestation` format. The `CertificateGenerator` has been refactored to better model the behavior of the legacy Keystore API. Key pair generation (`generateSoftwareKeyPair`) and certificate chain creation (`generateCertificateChain`) are now separate functions. This allows the interceptor to correctly create a key pair during the `handleExportKey` step and then generate a certificate for that pre-existing key pair during the `handleAttestKey` step. Finally, the implementation correctly extracts and applies the `attestationChallenge` provided during the `attestKey` transaction, ensuring the generated certificate chain contains the appropriate attestation.
148 lines
4.2 KiB
Java
148 lines
4.2 KiB
Java
package android.security.keymaster;
|
|
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import java.math.BigInteger;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
|
|
public class KeymasterArguments implements Parcelable {
|
|
|
|
private static final long UINT32_RANGE = 1L << 32;
|
|
public static final long UINT32_MAX_VALUE = UINT32_RANGE - 1;
|
|
|
|
private static final BigInteger UINT64_RANGE = BigInteger.ONE.shiftLeft(64);
|
|
public static final BigInteger UINT64_MAX_VALUE = UINT64_RANGE.subtract(BigInteger.ONE);
|
|
|
|
private List<KeymasterArgument> mArguments;
|
|
|
|
public static final @NonNull Parcelable.Creator<KeymasterArguments> CREATOR = new Parcelable.Creator<KeymasterArguments>() {
|
|
@Override
|
|
public KeymasterArguments createFromParcel(Parcel in) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
@Override
|
|
public KeymasterArguments[] newArray(int size) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
};
|
|
|
|
public KeymasterArguments() {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private KeymasterArguments(Parcel in) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addEnum(int tag, int value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addEnums(int tag, int... values) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public int getEnum(int tag, int defaultValue) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public List<Integer> getEnums(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private void addEnumTag(int tag, int value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private int getEnumTagValue(KeymasterArgument arg) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addUnsignedInt(int tag, long value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public long getUnsignedInt(int tag, long defaultValue) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addUnsignedLong(int tag, BigInteger value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public List<BigInteger> getUnsignedLongs(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private void addLongTag(int tag, BigInteger value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private BigInteger getLongTagValue(KeymasterArgument arg) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addBoolean(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public boolean getBoolean(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addBytes(int tag, byte[] value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public byte[] getBytes(int tag, byte[] defaultValue) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addDate(int tag, Date value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void addDateIfNotNull(int tag, Date value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public Date getDate(int tag, Date defaultValue) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
private KeymasterArgument getArgumentByTag(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public boolean containsTag(int tag) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public int size() {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
@Override
|
|
public void writeToParcel(Parcel out, int flags) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public void readFromParcel(Parcel in) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
@Override
|
|
public int describeContents() {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
|
|
public static BigInteger toUint64(long value) {
|
|
throw new UnsupportedOperationException("STUB!");
|
|
}
|
|
}
|