Merge "Add hidden KeyProtection API to specify SID"
This commit is contained in:
committed by
Android (Google) Code Review
commit
c21f12d4eb
@@ -29,6 +29,8 @@ import android.service.gatekeeper.IGateKeeperService;
|
||||
*/
|
||||
public abstract class GateKeeper {
|
||||
|
||||
public static final long INVALID_SECURE_USER_ID = 0;
|
||||
|
||||
private GateKeeper() {}
|
||||
|
||||
public static IGateKeeperService getService() {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.security.keystore;
|
||||
|
||||
import android.security.Credentials;
|
||||
import android.security.GateKeeper;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keymaster.KeyCharacteristics;
|
||||
import android.security.keymaster.KeymasterArguments;
|
||||
@@ -235,7 +236,8 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
||||
spec.isUserAuthenticationRequired(),
|
||||
spec.getUserAuthenticationValidityDurationSeconds(),
|
||||
spec.isUserAuthenticationValidWhileOnBody(),
|
||||
spec.isInvalidatedByBiometricEnrollment());
|
||||
spec.isInvalidatedByBiometricEnrollment(),
|
||||
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
|
||||
} catch (IllegalStateException | IllegalArgumentException e) {
|
||||
throw new InvalidAlgorithmParameterException(e);
|
||||
}
|
||||
@@ -275,7 +277,8 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
|
||||
spec.isUserAuthenticationRequired(),
|
||||
spec.getUserAuthenticationValidityDurationSeconds(),
|
||||
spec.isUserAuthenticationValidWhileOnBody(),
|
||||
spec.isInvalidatedByBiometricEnrollment());
|
||||
spec.isInvalidatedByBiometricEnrollment(),
|
||||
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
|
||||
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
|
||||
args,
|
||||
mKeymasterAlgorithm,
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.security.keystore;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.security.Credentials;
|
||||
import android.security.GateKeeper;
|
||||
import android.security.KeyPairGeneratorSpec;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keymaster.KeyCharacteristics;
|
||||
@@ -346,7 +347,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
|
||||
mSpec.isUserAuthenticationRequired(),
|
||||
mSpec.getUserAuthenticationValidityDurationSeconds(),
|
||||
mSpec.isUserAuthenticationValidWhileOnBody(),
|
||||
mSpec.isInvalidatedByBiometricEnrollment());
|
||||
mSpec.isInvalidatedByBiometricEnrollment(),
|
||||
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
|
||||
} catch (IllegalArgumentException | IllegalStateException e) {
|
||||
throw new InvalidAlgorithmParameterException(e);
|
||||
}
|
||||
@@ -533,7 +535,8 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato
|
||||
mSpec.isUserAuthenticationRequired(),
|
||||
mSpec.getUserAuthenticationValidityDurationSeconds(),
|
||||
mSpec.isUserAuthenticationValidWhileOnBody(),
|
||||
mSpec.isInvalidatedByBiometricEnrollment());
|
||||
mSpec.isInvalidatedByBiometricEnrollment(),
|
||||
GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */);
|
||||
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
|
||||
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
|
||||
mSpec.getKeyValidityForOriginationEnd());
|
||||
|
||||
@@ -500,7 +500,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
spec.isUserAuthenticationRequired(),
|
||||
spec.getUserAuthenticationValidityDurationSeconds(),
|
||||
spec.isUserAuthenticationValidWhileOnBody(),
|
||||
spec.isInvalidatedByBiometricEnrollment());
|
||||
spec.isInvalidatedByBiometricEnrollment(),
|
||||
spec.getBoundToSpecificSecureUserId());
|
||||
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
|
||||
spec.getKeyValidityStart());
|
||||
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
|
||||
@@ -696,7 +697,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi {
|
||||
params.isUserAuthenticationRequired(),
|
||||
params.getUserAuthenticationValidityDurationSeconds(),
|
||||
params.isUserAuthenticationValidWhileOnBody(),
|
||||
params.isInvalidatedByBiometricEnrollment());
|
||||
params.isInvalidatedByBiometricEnrollment(),
|
||||
params.getBoundToSpecificSecureUserId());
|
||||
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
|
||||
args,
|
||||
keymasterAlgorithm,
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.KeyguardManager;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.security.GateKeeper;
|
||||
|
||||
import java.security.Key;
|
||||
import java.security.Signature;
|
||||
@@ -225,6 +226,7 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
private final int mUserAuthenticationValidityDurationSeconds;
|
||||
private final boolean mUserAuthenticationValidWhileOnBody;
|
||||
private final boolean mInvalidatedByBiometricEnrollment;
|
||||
private final long mBoundToSecureUserId;
|
||||
|
||||
private KeyProtection(
|
||||
Date keyValidityStart,
|
||||
@@ -239,7 +241,8 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
boolean userAuthenticationRequired,
|
||||
int userAuthenticationValidityDurationSeconds,
|
||||
boolean userAuthenticationValidWhileOnBody,
|
||||
boolean invalidatedByBiometricEnrollment) {
|
||||
boolean invalidatedByBiometricEnrollment,
|
||||
long boundToSecureUserId) {
|
||||
mKeyValidityStart = Utils.cloneIfNotNull(keyValidityStart);
|
||||
mKeyValidityForOriginationEnd = Utils.cloneIfNotNull(keyValidityForOriginationEnd);
|
||||
mKeyValidityForConsumptionEnd = Utils.cloneIfNotNull(keyValidityForConsumptionEnd);
|
||||
@@ -255,6 +258,7 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
|
||||
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
|
||||
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
|
||||
mBoundToSecureUserId = boundToSecureUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -435,6 +439,24 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
return mInvalidatedByBiometricEnrollment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the secure user id that this key should be bound to.
|
||||
*
|
||||
* Normally an authentication-bound key is tied to the secure user id of the current user
|
||||
* (either the root SID from GateKeeper for auth-bound keys with a timeout, or the authenticator
|
||||
* id of the current fingerprint set for keys requiring explicit fingerprint authorization).
|
||||
* If this parameter is set (this method returning non-zero value), the key should be tied to
|
||||
* the specified secure user id, overriding the logic above.
|
||||
*
|
||||
* This is only applicable when {@link #isUserAuthenticationRequired} is {@code true}
|
||||
*
|
||||
* @see KeymasterUtils#addUserAuthArgs
|
||||
* @hide
|
||||
*/
|
||||
public long getBoundToSpecificSecureUserId() {
|
||||
return mBoundToSecureUserId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder of {@link KeyProtection} instances.
|
||||
*/
|
||||
@@ -454,6 +476,7 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
private boolean mUserAuthenticationValidWhileOnBody;
|
||||
private boolean mInvalidatedByBiometricEnrollment = true;
|
||||
|
||||
private long mBoundToSecureUserId = GateKeeper.INVALID_SECURE_USER_ID;
|
||||
/**
|
||||
* Creates a new instance of the {@code Builder}.
|
||||
*
|
||||
@@ -773,6 +796,26 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the secure user id that this key should be bound to.
|
||||
*
|
||||
* Normally an authentication-bound key is tied to the secure user id of the current user
|
||||
* (either the root SID from GateKeeper for auth-bound keys with a timeout, or the
|
||||
* authenticator id of the current fingerprint set for keys requiring explicit fingerprint
|
||||
* authorization). If this parameter is set (this method returning non-zero value), the key
|
||||
* should be tied to the specified secure user id, overriding the logic above.
|
||||
*
|
||||
* This is only applicable when {@link #setUserAuthenticationRequired} is set to
|
||||
* {@code true}
|
||||
*
|
||||
* @see KeyProtection#getBoundToSpecificSecureUserId()
|
||||
* @hide
|
||||
*/
|
||||
public Builder setBoundToSpecificSecureUserId(long secureUserId) {
|
||||
mBoundToSecureUserId = secureUserId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an instance of {@link KeyProtection}.
|
||||
*
|
||||
@@ -793,7 +836,8 @@ public final class KeyProtection implements ProtectionParameter {
|
||||
mUserAuthenticationRequired,
|
||||
mUserAuthenticationValidityDurationSeconds,
|
||||
mUserAuthenticationValidWhileOnBody,
|
||||
mInvalidatedByBiometricEnrollment);
|
||||
mInvalidatedByBiometricEnrollment,
|
||||
mBoundToSecureUserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +89,10 @@ public abstract class KeymasterUtils {
|
||||
* @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user
|
||||
* authentication is valid as authorization for using the key or {@code -1} if every
|
||||
* use of the key needs authorization.
|
||||
*
|
||||
* @param boundToSpecificSecureUserId if non-zero, specify which SID the key will be bound to,
|
||||
* overriding the default logic in this method where the key is bound to either the root
|
||||
* SID of the current user, or the fingerprint SID if explicit fingerprint authorization
|
||||
* is requested.
|
||||
* @throws IllegalStateException if user authentication is required but the system is in a wrong
|
||||
* state (e.g., secure lock screen not set up) for generating or importing keys that
|
||||
* require user authentication.
|
||||
@@ -98,7 +101,8 @@ public abstract class KeymasterUtils {
|
||||
boolean userAuthenticationRequired,
|
||||
int userAuthenticationValidityDurationSeconds,
|
||||
boolean userAuthenticationValidWhileOnBody,
|
||||
boolean invalidatedByBiometricEnrollment) {
|
||||
boolean invalidatedByBiometricEnrollment,
|
||||
long boundToSpecificSecureUserId) {
|
||||
if (!userAuthenticationRequired) {
|
||||
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
|
||||
return;
|
||||
@@ -120,7 +124,9 @@ public abstract class KeymasterUtils {
|
||||
}
|
||||
|
||||
long sid;
|
||||
if (invalidatedByBiometricEnrollment) {
|
||||
if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
|
||||
sid = boundToSpecificSecureUserId;
|
||||
} else if (invalidatedByBiometricEnrollment) {
|
||||
// The fingerprint-only SID will change on fingerprint enrollment or removal of all,
|
||||
// enrolled fingerprints, invalidating the key.
|
||||
sid = fingerprintOnlySid;
|
||||
@@ -138,11 +144,16 @@ public abstract class KeymasterUtils {
|
||||
+ "supported for keys requiring fingerprint authentication");
|
||||
}
|
||||
} else {
|
||||
// The key is authorized for use for the specified amount of time after the user has
|
||||
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
|
||||
long rootSid = getRootSid();
|
||||
long sid;
|
||||
if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
|
||||
sid = boundToSpecificSecureUserId;
|
||||
} else {
|
||||
// The key is authorized for use for the specified amount of time after the user has
|
||||
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
|
||||
sid = getRootSid();
|
||||
}
|
||||
args.addUnsignedLong(KeymasterDefs.KM_TAG_USER_SECURE_ID,
|
||||
KeymasterArguments.toUint64(rootSid));
|
||||
KeymasterArguments.toUint64(sid));
|
||||
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
|
||||
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
|
||||
args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
|
||||
|
||||
Reference in New Issue
Block a user