diff options
Diffstat (limited to 'keystore/java/android')
-rw-r--r-- | keystore/java/android/security/keystore/AttestationUtils.java | 107 |
1 files changed, 14 insertions, 93 deletions
diff --git a/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java index 4da2a28fffc3..67484d4f2b2d 100644 --- a/keystore/java/android/security/keystore/AttestationUtils.java +++ b/keystore/java/android/security/keystore/AttestationUtils.java @@ -21,18 +21,13 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.content.Context; -import android.os.Build; -import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; -import android.security.keymaster.KeymasterDefs; -import android.telephony.TelephonyManager; -import android.util.ArraySet; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.nio.charset.StandardCharsets; import java.security.KeyPairGenerator; import java.security.KeyStore; +import java.security.ProviderException; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; @@ -41,7 +36,6 @@ import java.security.spec.ECGenParameterSpec; import java.util.Arrays; import java.util.Collection; import java.util.Random; -import java.util.Set; /** * Utilities for attesting the device's hardware identifiers. @@ -110,92 +104,6 @@ public abstract class AttestationUtils { } } - @NonNull private static KeymasterArguments prepareAttestationArgumentsForDeviceId( - Context context, @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws - DeviceIdAttestationException { - // Verify that device ID attestation types are provided. - if (idTypes == null) { - throw new NullPointerException("Missing id types"); - } - - return prepareAttestationArguments(context, idTypes, attestationChallenge); - } - - /** - * Prepares Keymaster Arguments with attestation data. - * @hide should only be used by KeyChain. - */ - @NonNull public static KeymasterArguments prepareAttestationArguments(Context context, - @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws - DeviceIdAttestationException { - // Check method arguments, retrieve requested device IDs and prepare attestation arguments. - if (attestationChallenge == null) { - throw new NullPointerException("Missing attestation challenge"); - } - final KeymasterArguments attestArgs = new KeymasterArguments(); - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_CHALLENGE, attestationChallenge); - // Return early if the caller did not request any device identifiers to be included in the - // attestation record. - if (idTypes == null) { - return attestArgs; - } - final Set<Integer> idTypesSet = new ArraySet<>(idTypes.length); - for (int idType : idTypes) { - idTypesSet.add(idType); - } - TelephonyManager telephonyService = null; - if (idTypesSet.contains(ID_TYPE_IMEI) || idTypesSet.contains(ID_TYPE_MEID)) { - telephonyService = (TelephonyManager) context.getSystemService( - Context.TELEPHONY_SERVICE); - if (telephonyService == null) { - throw new DeviceIdAttestationException("Unable to access telephony service"); - } - } - for (final Integer idType : idTypesSet) { - switch (idType) { - case ID_TYPE_SERIAL: - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_SERIAL, - Build.getSerial().getBytes(StandardCharsets.UTF_8)); - break; - case ID_TYPE_IMEI: { - final String imei = telephonyService.getImei(0); - if (imei == null) { - throw new DeviceIdAttestationException("Unable to retrieve IMEI"); - } - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_IMEI, - imei.getBytes(StandardCharsets.UTF_8)); - break; - } - case ID_TYPE_MEID: { - final String meid = telephonyService.getMeid(0); - if (meid == null) { - throw new DeviceIdAttestationException("Unable to retrieve MEID"); - } - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MEID, - meid.getBytes(StandardCharsets.UTF_8)); - break; - } - case USE_INDIVIDUAL_ATTESTATION: { - attestArgs.addBoolean(KeymasterDefs.KM_TAG_DEVICE_UNIQUE_ATTESTATION); - break; - } - default: - throw new IllegalArgumentException("Unknown device ID type " + idType); - } - } - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, - Build.BRAND.getBytes(StandardCharsets.UTF_8)); - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, - Build.DEVICE.getBytes(StandardCharsets.UTF_8)); - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, - Build.PRODUCT.getBytes(StandardCharsets.UTF_8)); - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MANUFACTURER, - Build.MANUFACTURER.getBytes(StandardCharsets.UTF_8)); - attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_MODEL, - Build.MODEL.getBytes(StandardCharsets.UTF_8)); - return attestArgs; - } - /** * Performs attestation of the device's identifiers. This method returns a certificate chain * whose first element contains the requested device identifiers in an extension. The device's @@ -229,6 +137,13 @@ public abstract class AttestationUtils { @NonNull public static X509Certificate[] attestDeviceIds(Context context, @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws DeviceIdAttestationException { + if (attestationChallenge == null) { + throw new NullPointerException("Missing attestation challenge"); + } + if (idTypes == null) { + throw new NullPointerException("Missing id types"); + } + String keystoreAlias = generateRandomAlias(); KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder(keystoreAlias, KeyProperties.PURPOSE_SIGN) @@ -265,6 +180,12 @@ public abstract class AttestationUtils { if (e.getCause() instanceof DeviceIdAttestationException) { throw (DeviceIdAttestationException) e.getCause(); } + // Illegal argument errors are wrapped up by a ProviderException. Catch those so that + // we can unwrap them into a more meaningful exception type for the caller. + if (e instanceof ProviderException + && e.getCause() instanceof IllegalArgumentException) { + throw (IllegalArgumentException) e.getCause(); + } throw new DeviceIdAttestationException("Unable to perform attestation", e); } } |