Merge "Keystore 2.0 SPI: Update KeyInfo and KeyGenParameterSpec"
This commit is contained in:
@@ -42821,10 +42821,11 @@ package android.security.keystore {
|
||||
method public String getKeystoreAlias();
|
||||
method public int getOrigin();
|
||||
method public int getPurposes();
|
||||
method public int getSecurityLevel();
|
||||
method @NonNull public String[] getSignaturePaddings();
|
||||
method public int getUserAuthenticationType();
|
||||
method public int getUserAuthenticationValidityDurationSeconds();
|
||||
method public boolean isInsideSecureHardware();
|
||||
method @Deprecated public boolean isInsideSecureHardware();
|
||||
method public boolean isInvalidatedByBiometricEnrollment();
|
||||
method public boolean isTrustedUserPresenceRequired();
|
||||
method public boolean isUserAuthenticationRequired();
|
||||
|
||||
@@ -9377,8 +9377,13 @@ package android.security.keystore {
|
||||
ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
|
||||
}
|
||||
|
||||
public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
|
||||
method public int getNamespace();
|
||||
}
|
||||
|
||||
public static final class KeyGenParameterSpec.Builder {
|
||||
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
|
||||
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
|
||||
method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40989,10 +40989,11 @@ package android.security.keystore {
|
||||
method public String getKeystoreAlias();
|
||||
method public int getOrigin();
|
||||
method public int getPurposes();
|
||||
method public int getSecurityLevel();
|
||||
method @NonNull public String[] getSignaturePaddings();
|
||||
method public int getUserAuthenticationType();
|
||||
method public int getUserAuthenticationValidityDurationSeconds();
|
||||
method public boolean isInsideSecureHardware();
|
||||
method @Deprecated public boolean isInsideSecureHardware();
|
||||
method public boolean isInvalidatedByBiometricEnrollment();
|
||||
method public boolean isTrustedUserPresenceRequired();
|
||||
method public boolean isUserAuthenticationRequired();
|
||||
|
||||
@@ -8259,8 +8259,13 @@ package android.security.keystore {
|
||||
ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
|
||||
}
|
||||
|
||||
public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
|
||||
method public int getNamespace();
|
||||
}
|
||||
|
||||
public static final class KeyGenParameterSpec.Builder {
|
||||
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
|
||||
method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setNamespace(int);
|
||||
method @Deprecated @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUid(int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.security.KeyStore;
|
||||
import android.security.keymaster.ExportResult;
|
||||
import android.security.keymaster.KeyCharacteristics;
|
||||
import android.security.keymaster.KeymasterDefs;
|
||||
import android.sysprop.Keystore2Properties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.KeyFactory;
|
||||
@@ -111,6 +112,26 @@ public class AndroidKeyStoreProvider extends Provider {
|
||||
putSecretKeyFactoryImpl("HmacSHA512");
|
||||
}
|
||||
|
||||
private static boolean sKeystore2Enabled;
|
||||
|
||||
/**
|
||||
* This function indicates whether or not Keystore 2.0 is enabled. Some parts of the
|
||||
* Keystore SPI must behave subtly differently when Keystore 2.0 is enabled. However,
|
||||
* the platform property that indicates that Keystore 2.0 is enabled is not readable
|
||||
* by applications. So we set this value when {@code install()} is called because it
|
||||
* is called by zygote, which can access Keystore2Properties.
|
||||
*
|
||||
* This function can be removed once the transition to Keystore 2.0 is complete.
|
||||
* b/171305684
|
||||
*
|
||||
* @return true if Keystore 2.0 is enabled.
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isKeystore2Enabled() {
|
||||
return sKeystore2Enabled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Installs a new instance of this provider (and the
|
||||
* {@link AndroidKeyStoreBCWorkaroundProvider}).
|
||||
@@ -138,6 +159,11 @@ public class AndroidKeyStoreProvider extends Provider {
|
||||
// priority.
|
||||
Security.addProvider(workaroundProvider);
|
||||
}
|
||||
|
||||
// {@code install()} is run by zygote when this property is still accessible. We store its
|
||||
// value so that the Keystore SPI can act accordingly without having to access an internal
|
||||
// property.
|
||||
sKeystore2Enabled = Keystore2Properties.keystore2_enabled().orElse(false);
|
||||
}
|
||||
|
||||
private void putSecretKeyFactoryImpl(String algorithm) {
|
||||
|
||||
@@ -211,7 +211,11 @@ public class AndroidKeyStoreSecretKeyFactorySpi extends SecretKeyFactorySpi {
|
||||
userAuthenticationValidWhileOnBody,
|
||||
trustedUserPresenceRequired,
|
||||
invalidatedByBiometricEnrollment,
|
||||
userConfirmationRequired);
|
||||
userConfirmationRequired,
|
||||
// Keystore 1.0 does not tell us the exact security level of the key
|
||||
// so we report an unknown but secure security level.
|
||||
insideSecureHardware ? KeyProperties.SECURITY_LEVEL_UNKNOWN_SECURE
|
||||
: KeyProperties.SECURITY_LEVEL_SOFTWARE);
|
||||
}
|
||||
|
||||
private static BigInteger getGateKeeperSecureUserId() throws ProviderException {
|
||||
|
||||
@@ -27,7 +27,6 @@ import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.BiometricPrompt;
|
||||
import android.os.Build;
|
||||
import android.security.GateKeeper;
|
||||
import android.security.KeyStore;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.math.BigInteger;
|
||||
@@ -246,7 +245,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
|
||||
|
||||
private final String mKeystoreAlias;
|
||||
private final int mUid;
|
||||
private final int mNamespace;
|
||||
private final int mKeySize;
|
||||
private final AlgorithmParameterSpec mSpec;
|
||||
private final X500Principal mCertificateSubject;
|
||||
@@ -286,7 +285,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
*/
|
||||
public KeyGenParameterSpec(
|
||||
String keyStoreAlias,
|
||||
int uid,
|
||||
int namespace,
|
||||
int keySize,
|
||||
AlgorithmParameterSpec spec,
|
||||
X500Principal certificateSubject,
|
||||
@@ -337,7 +336,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
}
|
||||
|
||||
mKeystoreAlias = keyStoreAlias;
|
||||
mUid = uid;
|
||||
mNamespace = namespace;
|
||||
mKeySize = keySize;
|
||||
mSpec = spec;
|
||||
mCertificateSubject = certificateSubject;
|
||||
@@ -382,11 +381,43 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
* Returns the UID which will own the key. {@code -1} is an alias for the UID of the current
|
||||
* process.
|
||||
*
|
||||
* @deprecated See deprecation message on {@link KeyGenParameterSpec.Builder#setUid(int)}.
|
||||
* Known namespaces will be translated to their legacy UIDs. Unknown
|
||||
* Namespaces will yield {@link IllegalStateException}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@UnsupportedAppUsage
|
||||
@Deprecated
|
||||
public int getUid() {
|
||||
return mUid;
|
||||
if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
|
||||
// If Keystore2 has not been enabled we have to behave as if mNamespace is actually
|
||||
// a UID, because we are still being used with the old Keystore SPI.
|
||||
// TODO This if statement and body can be removed when the Keystore 2 migration is
|
||||
// complete. b/171563717
|
||||
return mNamespace;
|
||||
}
|
||||
try {
|
||||
return KeyProperties.namespaceToLegacyUid(mNamespace);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IllegalStateException("getUid called on KeyGenParameterSpec with non legacy"
|
||||
+ " keystore namespace.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the target namespace for the key.
|
||||
* See {@link KeyGenParameterSpec.Builder#setNamespace(int)}.
|
||||
*
|
||||
* @return The numeric namespace as configured in the keystore2_key_contexts files of Android's
|
||||
* SEPolicy.
|
||||
* TODO b/171806779 link to public Keystore 2.0 documentation.
|
||||
* See bug for more details for now.
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
public int getNamespace() {
|
||||
return mNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -767,7 +798,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
private final String mKeystoreAlias;
|
||||
private @KeyProperties.PurposeEnum int mPurposes;
|
||||
|
||||
private int mUid = KeyStore.UID_SELF;
|
||||
private int mNamespace = KeyProperties.NAMESPACE_APPLICATION;
|
||||
private int mKeySize = -1;
|
||||
private AlgorithmParameterSpec mSpec;
|
||||
private X500Principal mCertificateSubject;
|
||||
@@ -830,7 +861,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
*/
|
||||
public Builder(@NonNull KeyGenParameterSpec sourceSpec) {
|
||||
this(sourceSpec.getKeystoreAlias(), sourceSpec.getPurposes());
|
||||
mUid = sourceSpec.getUid();
|
||||
mNamespace = sourceSpec.getNamespace();
|
||||
mKeySize = sourceSpec.getKeySize();
|
||||
mSpec = sourceSpec.getAlgorithmParameterSpec();
|
||||
mCertificateSubject = sourceSpec.getCertificateSubject();
|
||||
@@ -873,12 +904,51 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
*
|
||||
* @param uid UID or {@code -1} for the UID of the current process.
|
||||
*
|
||||
* @deprecated Setting the UID of the target namespace is based on a hardcoded
|
||||
* hack in the Keystore service. This is no longer supported with Keystore 2.0/Android S.
|
||||
* Instead, dedicated non UID based namespaces can be configured in SEPolicy using
|
||||
* the keystore2_key_contexts files. The functionality of this method will be supported
|
||||
* by mapping knows special UIDs, such as WIFI, to the newly configured SELinux based
|
||||
* namespaces. Unknown UIDs will yield {@link IllegalArgumentException}.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
@Deprecated
|
||||
public Builder setUid(int uid) {
|
||||
mUid = uid;
|
||||
if (!AndroidKeyStoreProvider.isKeystore2Enabled()) {
|
||||
// If Keystore2 has not been enabled we have to behave as if mNamespace is actually
|
||||
// a UID, because we are still being used with the old Keystore SPI.
|
||||
// TODO This if statement and body can be removed when the Keystore 2 migration is
|
||||
// complete. b/171563717
|
||||
mNamespace = uid;
|
||||
return this;
|
||||
}
|
||||
mNamespace = KeyProperties.legacyUidToNamespace(uid);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the designated SELinux namespace that the key shall live in. The caller must
|
||||
* have sufficient permissions to install a key in the given namespace. Namespaces
|
||||
* can be created using SEPolicy. The keystore2_key_contexts files map numeric
|
||||
* namespaces to SELinux labels, and SEPolicy can be used to grant access to these
|
||||
* namespaces to the desired target context. This is the preferred way to share
|
||||
* keys between system and vendor components, e.g., WIFI settings and WPA supplicant.
|
||||
*
|
||||
* @param namespace Numeric SELinux namespace as configured in keystore2_key_contexts
|
||||
* of Android's SEPolicy.
|
||||
* TODO b/171806779 link to public Keystore 2.0 documentation.
|
||||
* See bug for more details for now.
|
||||
* @return this Builder object.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
public Builder setNamespace(int namespace) {
|
||||
mNamespace = namespace;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1559,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu
|
||||
public KeyGenParameterSpec build() {
|
||||
return new KeyGenParameterSpec(
|
||||
mKeystoreAlias,
|
||||
mUid,
|
||||
mNamespace,
|
||||
mKeySize,
|
||||
mSpec,
|
||||
mCertificateSubject,
|
||||
|
||||
@@ -84,6 +84,7 @@ public class KeyInfo implements KeySpec {
|
||||
private final boolean mTrustedUserPresenceRequired;
|
||||
private final boolean mInvalidatedByBiometricEnrollment;
|
||||
private final boolean mUserConfirmationRequired;
|
||||
private final @KeyProperties.SecurityLevelEnum int mSecurityLevel;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -107,7 +108,8 @@ public class KeyInfo implements KeySpec {
|
||||
boolean userAuthenticationValidWhileOnBody,
|
||||
boolean trustedUserPresenceRequired,
|
||||
boolean invalidatedByBiometricEnrollment,
|
||||
boolean userConfirmationRequired) {
|
||||
boolean userConfirmationRequired,
|
||||
@KeyProperties.SecurityLevelEnum int securityLevel) {
|
||||
mKeystoreAlias = keystoreKeyAlias;
|
||||
mInsideSecureHardware = insideSecureHardware;
|
||||
mOrigin = origin;
|
||||
@@ -131,6 +133,7 @@ public class KeyInfo implements KeySpec {
|
||||
mTrustedUserPresenceRequired = trustedUserPresenceRequired;
|
||||
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
|
||||
mUserConfirmationRequired = userConfirmationRequired;
|
||||
mSecurityLevel = securityLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,7 +147,10 @@ public class KeyInfo implements KeySpec {
|
||||
* Returns {@code true} if the key resides inside secure hardware (e.g., Trusted Execution
|
||||
* Environment (TEE) or Secure Element (SE)). Key material of such keys is available in
|
||||
* plaintext only inside the secure hardware and is not exposed outside of it.
|
||||
*
|
||||
* @deprecated This method is superseded by @see getSecurityLevel.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isInsideSecureHardware() {
|
||||
return mInsideSecureHardware;
|
||||
}
|
||||
@@ -355,4 +361,17 @@ public class KeyInfo implements KeySpec {
|
||||
public boolean isTrustedUserPresenceRequired() {
|
||||
return mTrustedUserPresenceRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the security level that the key is protected by.
|
||||
* {@code KeyProperties.SecurityLevelEnum.TRUSTED_ENVIRONMENT} and
|
||||
* {@code KeyProperties.SecurityLevelEnum.STRONGBOX} indicate that the key material resides
|
||||
* in secure hardware. Key material of such keys is available in
|
||||
* plaintext only inside the secure hardware and is not exposed outside of it.
|
||||
*
|
||||
* <p>See {@link KeyProperties}.{@code SecurityLevelEnum} constants.
|
||||
*/
|
||||
public @KeyProperties.SecurityLevelEnum int getSecurityLevel() {
|
||||
return mSecurityLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringDef;
|
||||
import android.security.KeyStore;
|
||||
import android.security.keymaster.KeymasterDefs;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
@@ -857,4 +858,43 @@ public abstract class KeyProperties {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This value indicates the implicit keystore namespace of the calling application.
|
||||
* It is used by default. Only select system components can choose a different namespace
|
||||
* which it must be configured in SEPolicy.
|
||||
* @hide
|
||||
*/
|
||||
public static final int NAMESPACE_APPLICATION = -1;
|
||||
|
||||
/**
|
||||
* For legacy support, translate namespaces into known UIDs.
|
||||
* @hide
|
||||
*/
|
||||
public static int namespaceToLegacyUid(int namespace) {
|
||||
switch (namespace) {
|
||||
case NAMESPACE_APPLICATION:
|
||||
return KeyStore.UID_SELF;
|
||||
// TODO Translate WIFI and VPN UIDs once the namespaces are defined.
|
||||
// b/171305388 and b/171305607
|
||||
default:
|
||||
throw new IllegalArgumentException("No UID corresponding to namespace "
|
||||
+ namespace);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For legacy support, translate namespaces into known UIDs.
|
||||
* @hide
|
||||
*/
|
||||
public static int legacyUidToNamespace(int uid) {
|
||||
switch (uid) {
|
||||
case KeyStore.UID_SELF:
|
||||
return NAMESPACE_APPLICATION;
|
||||
// TODO Translate WIFI and VPN UIDs once the namespaces are defined.
|
||||
// b/171305388 and b/171305607
|
||||
default:
|
||||
throw new IllegalArgumentException("No namespace corresponding to uid "
|
||||
+ uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user