diff --git a/api/current.txt b/api/current.txt index 948b68aa147be..fac703e006bdc 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28353,15 +28353,67 @@ package android.security { ctor public KeyChainException(java.lang.Throwable); } + public final deprecated class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { + method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); + method public android.content.Context getContext(); + method public java.util.Date getEndDate(); + method public int getKeySize(); + method public java.lang.String getKeyType(); + method public java.lang.String getKeystoreAlias(); + method public java.math.BigInteger getSerialNumber(); + method public java.util.Date getStartDate(); + method public javax.security.auth.x500.X500Principal getSubjectDN(); + method public boolean isEncryptionRequired(); + } + + public static final deprecated class KeyPairGeneratorSpec.Builder { + ctor public KeyPairGeneratorSpec.Builder(android.content.Context); + method public android.security.KeyPairGeneratorSpec build(); + method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); + method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String); + method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired(); + method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date); + method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int); + method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException; + method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger); + method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date); + method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal); + } + + public final deprecated class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter { + method public android.content.Context getContext(); + method public boolean isEncryptionRequired(); + } + + public static final deprecated class KeyStoreParameter.Builder { + ctor public KeyStoreParameter.Builder(android.content.Context); + method public android.security.KeyStoreParameter build(); + method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean); + } + + public class NetworkSecurityPolicy { + method public static android.security.NetworkSecurityPolicy getInstance(); + method public boolean isCleartextTrafficPermitted(); + } + +} + +package android.security.keystore { + public class KeyExpiredException extends java.security.InvalidKeyException { ctor public KeyExpiredException(); ctor public KeyExpiredException(java.lang.String); ctor public KeyExpiredException(java.lang.String, java.lang.Throwable); } - public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { + public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec { + method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); + method public java.util.Date getCertificateNotAfter(); + method public java.util.Date getCertificateNotBefore(); + method public java.math.BigInteger getCertificateSerialNumber(); + method public javax.security.auth.x500.X500Principal getCertificateSubject(); + method public java.lang.String[] getDigests(); method public java.lang.String[] getEncryptionPaddings(); method public int getKeySize(); method public java.util.Date getKeyValidityForConsumptionEnd(); @@ -28369,28 +28421,53 @@ package android.security { method public java.util.Date getKeyValidityStart(); method public java.lang.String getKeystoreAlias(); method public int getPurposes(); + method public java.lang.String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isEncryptionRequired(); + method public boolean isDigestsSpecified(); + method public boolean isEncryptionAtRestRequired(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUserAuthenticationRequired(); } - public static class KeyGeneratorSpec.Builder { - ctor public KeyGeneratorSpec.Builder(android.content.Context); - method public android.security.KeyGeneratorSpec build(); - method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String); - method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(); - method public android.security.KeyGeneratorSpec.Builder setKeySize(int); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setPurposes(int); - method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int); + public static final class KeyGenParameterSpec.Builder { + ctor public KeyGenParameterSpec.Builder(java.lang.String, int); + method public android.security.keystore.KeyGenParameterSpec build(); + method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); + method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(java.math.BigInteger); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(javax.security.auth.x500.X500Principal); + method public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionAtRestRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeySize(int); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int); + } + + public class KeyInfo implements java.security.spec.KeySpec { + method public java.lang.String[] getBlockModes(); + method public java.lang.String[] getDigests(); + method public java.lang.String[] getEncryptionPaddings(); + method public int getKeySize(); + method public java.util.Date getKeyValidityForConsumptionEnd(); + method public java.util.Date getKeyValidityForOriginationEnd(); + method public java.util.Date getKeyValidityStart(); + method public java.lang.String getKeystoreAlias(); + method public int getOrigin(); + method public int getPurposes(); + method public java.lang.String[] getSignaturePaddings(); + method public int getUserAuthenticationValidityDurationSeconds(); + method public boolean isInsideSecureHardware(); + method public boolean isUserAuthenticationRequired(); + method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware(); } public class KeyNotYetValidException extends java.security.InvalidKeyException { @@ -28399,63 +28476,13 @@ package android.security { ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable); } - public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { - method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); - method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); - method public java.lang.String[] getDigests(); - method public java.lang.String[] getEncryptionPaddings(); - method public java.util.Date getEndDate(); - method public int getKeySize(); - method public java.lang.String getKeyType(); - method public java.util.Date getKeyValidityForConsumptionEnd(); - method public java.util.Date getKeyValidityForOriginationEnd(); - method public java.util.Date getKeyValidityStart(); - method public java.lang.String getKeystoreAlias(); - method public int getPurposes(); - method public java.math.BigInteger getSerialNumber(); - method public java.lang.String[] getSignaturePaddings(); - method public java.util.Date getStartDate(); - method public javax.security.auth.x500.X500Principal getSubjectDN(); - method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isEncryptionRequired(); - method public boolean isRandomizedEncryptionRequired(); - method public boolean isUserAuthenticationRequired(); - } - - public static final class KeyPairGeneratorSpec.Builder { - ctor public KeyPairGeneratorSpec.Builder(android.content.Context); - method public android.security.KeyPairGeneratorSpec build(); - method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); - method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String); - method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired(); - method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int); - method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException; - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int); - method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger); - method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal); - method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int); - } - public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException { ctor public KeyPermanentlyInvalidatedException(); ctor public KeyPermanentlyInvalidatedException(java.lang.String); ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable); } - public abstract class KeyStoreKeyProperties { + public abstract class KeyProperties { field public static final java.lang.String BLOCK_MODE_CBC = "CBC"; field public static final java.lang.String BLOCK_MODE_CTR = "CTR"; field public static final java.lang.String BLOCK_MODE_ECB = "ECB"; @@ -28490,29 +28517,10 @@ package android.security { field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS"; } - public class KeyStoreKeySpec implements java.security.spec.KeySpec { + public final class KeyProtection implements java.security.KeyStore.ProtectionParameter { method public java.lang.String[] getBlockModes(); method public java.lang.String[] getDigests(); method public java.lang.String[] getEncryptionPaddings(); - method public int getKeySize(); - method public java.util.Date getKeyValidityForConsumptionEnd(); - method public java.util.Date getKeyValidityForOriginationEnd(); - method public java.util.Date getKeyValidityStart(); - method public java.lang.String getKeystoreAlias(); - method public int getOrigin(); - method public int getPurposes(); - method public java.lang.String[] getSignaturePaddings(); - method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isInsideSecureHardware(); - method public boolean isUserAuthenticationRequired(); - method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware(); - } - - public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter { - method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); - method public java.lang.String[] getDigests(); - method public java.lang.String[] getEncryptionPaddings(); method public java.util.Date getKeyValidityForConsumptionEnd(); method public java.util.Date getKeyValidityForOriginationEnd(); method public java.util.Date getKeyValidityStart(); @@ -28520,32 +28528,26 @@ package android.security { method public java.lang.String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDigestsSpecified(); - method public boolean isEncryptionRequired(); + method public boolean isEncryptionAtRestRequired(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUserAuthenticationRequired(); } - public static final class KeyStoreParameter.Builder { - ctor public KeyStoreParameter.Builder(android.content.Context); - method public android.security.KeyStoreParameter build(); - method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean); - method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyStoreParameter.Builder setPurposes(int); - method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int); - } - - public class NetworkSecurityPolicy { - method public static android.security.NetworkSecurityPolicy getInstance(); - method public boolean isCleartextTrafficPermitted(); + public static final class KeyProtection.Builder { + ctor public KeyProtection.Builder(int); + method public android.security.keystore.KeyProtection build(); + method public android.security.keystore.KeyProtection.Builder setBlockModes(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setDigests(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setEncryptionAtRestRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setEncryptionPaddings(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setKeyValidityEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityForConsumptionEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int); } public class UserNotAuthenticatedException extends java.security.InvalidKeyException { diff --git a/api/system-current.txt b/api/system-current.txt index 9ce9d2a306846..23187048f2795 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -30378,15 +30378,67 @@ package android.security { ctor public KeyChainException(java.lang.Throwable); } + public final deprecated class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { + method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); + method public android.content.Context getContext(); + method public java.util.Date getEndDate(); + method public int getKeySize(); + method public java.lang.String getKeyType(); + method public java.lang.String getKeystoreAlias(); + method public java.math.BigInteger getSerialNumber(); + method public java.util.Date getStartDate(); + method public javax.security.auth.x500.X500Principal getSubjectDN(); + method public boolean isEncryptionRequired(); + } + + public static final deprecated class KeyPairGeneratorSpec.Builder { + ctor public KeyPairGeneratorSpec.Builder(android.content.Context); + method public android.security.KeyPairGeneratorSpec build(); + method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); + method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String); + method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired(); + method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date); + method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int); + method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException; + method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger); + method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date); + method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal); + } + + public final deprecated class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter { + method public android.content.Context getContext(); + method public boolean isEncryptionRequired(); + } + + public static final deprecated class KeyStoreParameter.Builder { + ctor public KeyStoreParameter.Builder(android.content.Context); + method public android.security.KeyStoreParameter build(); + method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean); + } + + public class NetworkSecurityPolicy { + method public static android.security.NetworkSecurityPolicy getInstance(); + method public boolean isCleartextTrafficPermitted(); + } + +} + +package android.security.keystore { + public class KeyExpiredException extends java.security.InvalidKeyException { ctor public KeyExpiredException(); ctor public KeyExpiredException(java.lang.String); ctor public KeyExpiredException(java.lang.String, java.lang.Throwable); } - public class KeyGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { + public final class KeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec { + method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); + method public java.util.Date getCertificateNotAfter(); + method public java.util.Date getCertificateNotBefore(); + method public java.math.BigInteger getCertificateSerialNumber(); + method public javax.security.auth.x500.X500Principal getCertificateSubject(); + method public java.lang.String[] getDigests(); method public java.lang.String[] getEncryptionPaddings(); method public int getKeySize(); method public java.util.Date getKeyValidityForConsumptionEnd(); @@ -30394,28 +30446,53 @@ package android.security { method public java.util.Date getKeyValidityStart(); method public java.lang.String getKeystoreAlias(); method public int getPurposes(); + method public java.lang.String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isEncryptionRequired(); + method public boolean isDigestsSpecified(); + method public boolean isEncryptionAtRestRequired(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUserAuthenticationRequired(); } - public static class KeyGeneratorSpec.Builder { - ctor public KeyGeneratorSpec.Builder(android.content.Context); - method public android.security.KeyGeneratorSpec build(); - method public android.security.KeyGeneratorSpec.Builder setAlias(java.lang.String); - method public android.security.KeyGeneratorSpec.Builder setBlockModes(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyGeneratorSpec.Builder setEncryptionRequired(); - method public android.security.KeyGeneratorSpec.Builder setKeySize(int); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyGeneratorSpec.Builder setPurposes(int); - method public android.security.KeyGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int); + public static final class KeyGenParameterSpec.Builder { + ctor public KeyGenParameterSpec.Builder(java.lang.String, int); + method public android.security.keystore.KeyGenParameterSpec build(); + method public android.security.keystore.KeyGenParameterSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); + method public android.security.keystore.KeyGenParameterSpec.Builder setBlockModes(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotAfter(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateNotBefore(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSerialNumber(java.math.BigInteger); + method public android.security.keystore.KeyGenParameterSpec.Builder setCertificateSubject(javax.security.auth.x500.X500Principal); + method public android.security.keystore.KeyGenParameterSpec.Builder setDigests(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionAtRestRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setEncryptionPaddings(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeySize(int); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date); + method public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); + method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationRequired(boolean); + method public android.security.keystore.KeyGenParameterSpec.Builder setUserAuthenticationValidityDurationSeconds(int); + } + + public class KeyInfo implements java.security.spec.KeySpec { + method public java.lang.String[] getBlockModes(); + method public java.lang.String[] getDigests(); + method public java.lang.String[] getEncryptionPaddings(); + method public int getKeySize(); + method public java.util.Date getKeyValidityForConsumptionEnd(); + method public java.util.Date getKeyValidityForOriginationEnd(); + method public java.util.Date getKeyValidityStart(); + method public java.lang.String getKeystoreAlias(); + method public int getOrigin(); + method public int getPurposes(); + method public java.lang.String[] getSignaturePaddings(); + method public int getUserAuthenticationValidityDurationSeconds(); + method public boolean isInsideSecureHardware(); + method public boolean isUserAuthenticationRequired(); + method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware(); } public class KeyNotYetValidException extends java.security.InvalidKeyException { @@ -30424,63 +30501,13 @@ package android.security { ctor public KeyNotYetValidException(java.lang.String, java.lang.Throwable); } - public final class KeyPairGeneratorSpec implements java.security.spec.AlgorithmParameterSpec { - method public java.security.spec.AlgorithmParameterSpec getAlgorithmParameterSpec(); - method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); - method public java.lang.String[] getDigests(); - method public java.lang.String[] getEncryptionPaddings(); - method public java.util.Date getEndDate(); - method public int getKeySize(); - method public java.lang.String getKeyType(); - method public java.util.Date getKeyValidityForConsumptionEnd(); - method public java.util.Date getKeyValidityForOriginationEnd(); - method public java.util.Date getKeyValidityStart(); - method public java.lang.String getKeystoreAlias(); - method public int getPurposes(); - method public java.math.BigInteger getSerialNumber(); - method public java.lang.String[] getSignaturePaddings(); - method public java.util.Date getStartDate(); - method public javax.security.auth.x500.X500Principal getSubjectDN(); - method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isEncryptionRequired(); - method public boolean isRandomizedEncryptionRequired(); - method public boolean isUserAuthenticationRequired(); - } - - public static final class KeyPairGeneratorSpec.Builder { - ctor public KeyPairGeneratorSpec.Builder(android.content.Context); - method public android.security.KeyPairGeneratorSpec build(); - method public android.security.KeyPairGeneratorSpec.Builder setAlgorithmParameterSpec(java.security.spec.AlgorithmParameterSpec); - method public android.security.KeyPairGeneratorSpec.Builder setAlias(java.lang.String); - method public android.security.KeyPairGeneratorSpec.Builder setBlockModes(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setDigests(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setEncryptionRequired(); - method public android.security.KeyPairGeneratorSpec.Builder setEndDate(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeySize(int); - method public android.security.KeyPairGeneratorSpec.Builder setKeyType(java.lang.String) throws java.security.NoSuchAlgorithmException; - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setPurposes(int); - method public android.security.KeyPairGeneratorSpec.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyPairGeneratorSpec.Builder setSerialNumber(java.math.BigInteger); - method public android.security.KeyPairGeneratorSpec.Builder setSignaturePaddings(java.lang.String...); - method public android.security.KeyPairGeneratorSpec.Builder setStartDate(java.util.Date); - method public android.security.KeyPairGeneratorSpec.Builder setSubject(javax.security.auth.x500.X500Principal); - method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyPairGeneratorSpec.Builder setUserAuthenticationValidityDurationSeconds(int); - } - public class KeyPermanentlyInvalidatedException extends java.security.InvalidKeyException { ctor public KeyPermanentlyInvalidatedException(); ctor public KeyPermanentlyInvalidatedException(java.lang.String); ctor public KeyPermanentlyInvalidatedException(java.lang.String, java.lang.Throwable); } - public abstract class KeyStoreKeyProperties { + public abstract class KeyProperties { field public static final java.lang.String BLOCK_MODE_CBC = "CBC"; field public static final java.lang.String BLOCK_MODE_CTR = "CTR"; field public static final java.lang.String BLOCK_MODE_ECB = "ECB"; @@ -30515,29 +30542,10 @@ package android.security { field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS"; } - public class KeyStoreKeySpec implements java.security.spec.KeySpec { + public final class KeyProtection implements java.security.KeyStore.ProtectionParameter { method public java.lang.String[] getBlockModes(); method public java.lang.String[] getDigests(); method public java.lang.String[] getEncryptionPaddings(); - method public int getKeySize(); - method public java.util.Date getKeyValidityForConsumptionEnd(); - method public java.util.Date getKeyValidityForOriginationEnd(); - method public java.util.Date getKeyValidityStart(); - method public java.lang.String getKeystoreAlias(); - method public int getOrigin(); - method public int getPurposes(); - method public java.lang.String[] getSignaturePaddings(); - method public int getUserAuthenticationValidityDurationSeconds(); - method public boolean isInsideSecureHardware(); - method public boolean isUserAuthenticationRequired(); - method public boolean isUserAuthenticationRequirementEnforcedBySecureHardware(); - } - - public final class KeyStoreParameter implements java.security.KeyStore.ProtectionParameter { - method public java.lang.String[] getBlockModes(); - method public android.content.Context getContext(); - method public java.lang.String[] getDigests(); - method public java.lang.String[] getEncryptionPaddings(); method public java.util.Date getKeyValidityForConsumptionEnd(); method public java.util.Date getKeyValidityForOriginationEnd(); method public java.util.Date getKeyValidityStart(); @@ -30545,32 +30553,26 @@ package android.security { method public java.lang.String[] getSignaturePaddings(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDigestsSpecified(); - method public boolean isEncryptionRequired(); + method public boolean isEncryptionAtRestRequired(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUserAuthenticationRequired(); } - public static final class KeyStoreParameter.Builder { - ctor public KeyStoreParameter.Builder(android.content.Context); - method public android.security.KeyStoreParameter build(); - method public android.security.KeyStoreParameter.Builder setBlockModes(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setDigests(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setEncryptionPaddings(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setEncryptionRequired(boolean); - method public android.security.KeyStoreParameter.Builder setKeyValidityEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityForConsumptionEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityForOriginationEnd(java.util.Date); - method public android.security.KeyStoreParameter.Builder setKeyValidityStart(java.util.Date); - method public android.security.KeyStoreParameter.Builder setPurposes(int); - method public android.security.KeyStoreParameter.Builder setRandomizedEncryptionRequired(boolean); - method public android.security.KeyStoreParameter.Builder setSignaturePaddings(java.lang.String...); - method public android.security.KeyStoreParameter.Builder setUserAuthenticationRequired(boolean); - method public android.security.KeyStoreParameter.Builder setUserAuthenticationValidityDurationSeconds(int); - } - - public class NetworkSecurityPolicy { - method public static android.security.NetworkSecurityPolicy getInstance(); - method public boolean isCleartextTrafficPermitted(); + public static final class KeyProtection.Builder { + ctor public KeyProtection.Builder(int); + method public android.security.keystore.KeyProtection build(); + method public android.security.keystore.KeyProtection.Builder setBlockModes(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setDigests(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setEncryptionAtRestRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setEncryptionPaddings(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setKeyValidityEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityForConsumptionEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date); + method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...); + method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean); + method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int); } public class UserNotAuthenticatedException extends java.security.InvalidKeyException { diff --git a/docs/html/training/articles/keystore.jd b/docs/html/training/articles/keystore.jd index fea3b2c8a7df1..4005a05efc2b3 100644 --- a/docs/html/training/articles/keystore.jd +++ b/docs/html/training/articles/keystore.jd @@ -88,7 +88,7 @@ and {@link java.security.KeyPairGenerator} or

Generating a New Secret Key

To generate the key, use a {@link javax.crypto.KeyGenerator} with - {@link android.security.KeyGeneratorSpec}. + {@link android.security.keystore.KeyGenParameterSpec}.

Working with Keystore Entries

diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java index ea90ca3998165..e9f83200b270d 100644 --- a/keystore/java/android/security/AndroidKeyPairGenerator.java +++ b/keystore/java/android/security/AndroidKeyPairGenerator.java @@ -16,6 +16,10 @@ package android.security; +import android.annotation.NonNull; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; + import com.android.org.bouncycastle.x509.X509V3CertificateGenerator; import com.android.org.conscrypt.NativeConstants; import com.android.org.conscrypt.OpenSSLEngine; @@ -36,6 +40,7 @@ import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.X509EncodedKeySpec; +import java.util.Locale; /** * Provides a way to create instances of a KeyPair which will be placed in the @@ -54,13 +59,13 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { public static class RSA extends AndroidKeyPairGenerator { public RSA() { - super(KeyStoreKeyProperties.KEY_ALGORITHM_RSA); + super(KeyProperties.KEY_ALGORITHM_RSA); } } public static class EC extends AndroidKeyPairGenerator { public EC() { - super(KeyStoreKeyProperties.KEY_ALGORITHM_EC); + super(KeyProperties.KEY_ALGORITHM_EC); } } @@ -80,18 +85,18 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { private final String mAlgorithm; - private android.security.KeyStore mKeyStore; + private KeyStore mKeyStore; - private KeyPairGeneratorSpec mSpec; - private @KeyStoreKeyProperties.KeyAlgorithmEnum String mKeyAlgorithm; + private KeyGenParameterSpec mSpec; + private @KeyProperties.KeyAlgorithmEnum String mKeyAlgorithm; private int mKeyType; private int mKeySize; - protected AndroidKeyPairGenerator(@KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) { + protected AndroidKeyPairGenerator(@KeyProperties.KeyAlgorithmEnum String algorithm) { mAlgorithm = algorithm; } - @KeyStoreKeyProperties.KeyAlgorithmEnum String getAlgorithm() { + @KeyProperties.KeyAlgorithmEnum String getAlgorithm() { return mAlgorithm; } @@ -113,15 +118,16 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { @Override public KeyPair generateKeyPair() { if (mKeyStore == null || mSpec == null) { - throw new IllegalStateException( - "Must call initialize with an android.security.KeyPairGeneratorSpec first"); + throw new IllegalStateException("Not initialized"); + } - if (((mSpec.getFlags() & KeyStore.FLAG_ENCRYPTED) != 0) + final int flags = mSpec.getFlags(); + if (((flags & KeyStore.FLAG_ENCRYPTED) != 0) && (mKeyStore.state() != KeyStore.State.UNLOCKED)) { throw new IllegalStateException( - "Android keystore must be in initialized and unlocked state " - + "if encryption is required"); + "Encryption at rest using secure lock screen credential requested for key pair" + + ", but the user has not yet entered the credential"); } final String alias = mSpec.getKeystoreAlias(); @@ -131,8 +137,9 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { byte[][] args = getArgsForKeyType(mKeyType, mSpec.getAlgorithmParameterSpec()); final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias; + if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, mKeyType, mKeySize, - mSpec.getFlags(), args)) { + flags, args)) { throw new IllegalStateException("could not generate key in keystore"); } @@ -175,7 +182,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { } if (!mKeyStore.put(Credentials.USER_CERTIFICATE + alias, certBytes, KeyStore.UID_SELF, - mSpec.getFlags())) { + flags)) { Credentials.deleteAllTypesForAlias(mKeyStore, alias); throw new IllegalStateException("Can't store certificate in AndroidKeyStore"); } @@ -188,17 +195,17 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { throws Exception { final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); certGen.setPublicKey(publicKey); - certGen.setSerialNumber(mSpec.getSerialNumber()); - certGen.setSubjectDN(mSpec.getSubjectDN()); - certGen.setIssuerDN(mSpec.getSubjectDN()); - certGen.setNotBefore(mSpec.getStartDate()); - certGen.setNotAfter(mSpec.getEndDate()); + certGen.setSerialNumber(mSpec.getCertificateSerialNumber()); + certGen.setSubjectDN(mSpec.getCertificateSubject()); + certGen.setIssuerDN(mSpec.getCertificateSubject()); + certGen.setNotBefore(mSpec.getCertificateNotBefore()); + certGen.setNotAfter(mSpec.getCertificateNotAfter()); certGen.setSignatureAlgorithm(getDefaultSignatureAlgorithmForKeyAlgorithm(mKeyAlgorithm)); return certGen.generate(privateKey); } - private @KeyStoreKeyProperties.KeyAlgorithmEnum String getKeyAlgorithm( - KeyPairGeneratorSpec spec) { + @NonNull + private @KeyProperties.KeyAlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) { String result = spec.getKeyType(); if (result != null) { return result; @@ -250,10 +257,10 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { } private static String getDefaultSignatureAlgorithmForKeyAlgorithm( - @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) { - if (KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) { + @KeyProperties.KeyAlgorithmEnum String algorithm) { + if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) { return "sha256WithRSA"; - } else if (KeyStoreKeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) { + } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) { return "sha256WithECDSA"; } else { throw new IllegalArgumentException("Unsupported key type " + algorithm); @@ -282,14 +289,86 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { throws InvalidAlgorithmParameterException { if (params == null) { throw new InvalidAlgorithmParameterException( - "must supply params of type android.security.KeyPairGeneratorSpec"); - } else if (!(params instanceof KeyPairGeneratorSpec)) { - throw new InvalidAlgorithmParameterException( - "params must be of type android.security.KeyPairGeneratorSpec"); + "Must supply params of type " + KeyGenParameterSpec.class.getName() + + " or " + KeyPairGeneratorSpec.class.getName()); + } + + String keyAlgorithm; + KeyGenParameterSpec spec; + if (params instanceof KeyPairGeneratorSpec) { + KeyPairGeneratorSpec legacySpec = (KeyPairGeneratorSpec) params; + try { + KeyGenParameterSpec.Builder specBuilder; + keyAlgorithm = getKeyAlgorithm(legacySpec).toUpperCase(Locale.US); + if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { + specBuilder = new KeyGenParameterSpec.Builder( + legacySpec.getKeystoreAlias(), + KeyProperties.PURPOSE_SIGN + | KeyProperties.PURPOSE_VERIFY); + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); + } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { + specBuilder = new KeyGenParameterSpec.Builder( + legacySpec.getKeystoreAlias(), + KeyProperties.PURPOSE_ENCRYPT + | KeyProperties.PURPOSE_DECRYPT + | KeyProperties.PURPOSE_SIGN + | KeyProperties.PURPOSE_VERIFY); + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); + specBuilder.setSignaturePaddings( + KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); + specBuilder.setBlockModes(KeyProperties.BLOCK_MODE_ECB); + specBuilder.setEncryptionPaddings( + KeyProperties.ENCRYPTION_PADDING_NONE, + KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); + // Disable randomized encryption requirement to support encryption padding NONE + // above. + specBuilder.setRandomizedEncryptionRequired(false); + } else { + throw new InvalidAlgorithmParameterException( + "Unsupported key algorithm: " + keyAlgorithm); + } + + if (legacySpec.getKeySize() != -1) { + specBuilder.setKeySize(legacySpec.getKeySize()); + } + if (legacySpec.getAlgorithmParameterSpec() != null) { + specBuilder.setAlgorithmParameterSpec(legacySpec.getAlgorithmParameterSpec()); + } + specBuilder.setCertificateSubject(legacySpec.getSubjectDN()); + specBuilder.setCertificateSerialNumber(legacySpec.getSerialNumber()); + specBuilder.setCertificateNotBefore(legacySpec.getStartDate()); + specBuilder.setCertificateNotAfter(legacySpec.getEndDate()); + specBuilder.setEncryptionAtRestRequired(legacySpec.isEncryptionRequired()); + specBuilder.setUserAuthenticationRequired(false); + + spec = specBuilder.build(); + } catch (NullPointerException | IllegalArgumentException e) { + throw new InvalidAlgorithmParameterException(e); + } + } else if (params instanceof KeyGenParameterSpec) { + spec = (KeyGenParameterSpec) params; + keyAlgorithm = getAlgorithm(); + } else { + throw new InvalidAlgorithmParameterException( + "Unsupported params class: " + params.getClass().getName() + + ". Supported: " + KeyGenParameterSpec.class.getName() + + ", " + KeyPairGeneratorSpec.class); } - KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params; - @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithm = getKeyAlgorithm(spec); int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm); if (keyType == -1) { throw new InvalidAlgorithmParameterException( @@ -300,7 +379,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { keySize = getDefaultKeySize(keyType); if (keySize == -1) { throw new InvalidAlgorithmParameterException( - "Unsupported key algorithm: " + keyAlgorithm); + "Unsupported key algorithm: " + keyAlgorithm); } } checkCorrectParametersSpec(keyType, keySize, spec.getAlgorithmParameterSpec()); @@ -310,6 +389,6 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi { mKeyType = keyType; mKeySize = keySize; mSpec = spec; - mKeyStore = android.security.KeyStore.getInstance(); + mKeyStore = KeyStore.getInstance(); } } diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java index b8346410ae239..69bf877c3f947 100644 --- a/keystore/java/android/security/AndroidKeyStore.java +++ b/keystore/java/android/security/AndroidKeyStore.java @@ -24,6 +24,8 @@ import libcore.util.EmptyArray; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; +import android.security.keystore.KeyProperties; +import android.security.keystore.KeyProtection; import android.util.Log; import java.io.ByteArrayInputStream; @@ -129,11 +131,10 @@ public class AndroidKeyStore extends KeyStoreSpi { keymasterDigest = keymasterDigests.get(0); } - @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithmString; + @KeyProperties.KeyAlgorithmEnum String keyAlgorithmString; try { - keyAlgorithmString = - KeyStoreKeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm( - keymasterAlgorithm, keymasterDigest); + keyAlgorithmString = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm( + keymasterAlgorithm, keymasterDigest); } catch (IllegalArgumentException e) { throw (UnrecoverableKeyException) new UnrecoverableKeyException("Unsupported secret key type").initCause(e); @@ -270,7 +271,70 @@ public class AndroidKeyStore extends KeyStoreSpi { } private void setPrivateKeyEntry(String alias, PrivateKey key, Certificate[] chain, - KeyStoreParameter params) throws KeyStoreException { + java.security.KeyStore.ProtectionParameter param) throws KeyStoreException { + KeyProtection spec; + if (param instanceof KeyStoreParameter) { + KeyStoreParameter legacySpec = (KeyStoreParameter) param; + try { + String keyAlgorithm = key.getAlgorithm(); + KeyProtection.Builder specBuilder; + if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) { + specBuilder = + new KeyProtection.Builder( + KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY); + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); + } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) { + specBuilder = + new KeyProtection.Builder( + KeyProperties.PURPOSE_ENCRYPT + | KeyProperties.PURPOSE_DECRYPT + | KeyProperties.PURPOSE_SIGN + | KeyProperties.PURPOSE_VERIFY); + specBuilder.setDigests( + KeyProperties.DIGEST_NONE, + KeyProperties.DIGEST_MD5, + KeyProperties.DIGEST_SHA1, + KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, + KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512); + specBuilder.setSignaturePaddings( + KeyProperties.SIGNATURE_PADDING_RSA_PKCS1); + specBuilder.setBlockModes(KeyProperties.BLOCK_MODE_ECB); + specBuilder.setEncryptionPaddings( + KeyProperties.ENCRYPTION_PADDING_NONE, + KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1); + // Disable randomized encryption requirement to support encryption padding NONE + // above. + specBuilder.setRandomizedEncryptionRequired(false); + } else { + throw new KeyStoreException("Unsupported key algorithm: " + keyAlgorithm); + } + specBuilder.setEncryptionAtRestRequired(legacySpec.isEncryptionRequired()); + specBuilder.setUserAuthenticationRequired(false); + + spec = specBuilder.build(); + } catch (NullPointerException | IllegalArgumentException e) { + throw new KeyStoreException("Unsupported protection parameter", e); + } + } else if (param instanceof KeyProtection) { + spec = (KeyProtection) param; + } else if (param != null) { + throw new KeyStoreException( + "Unsupported protection parameter class:" + param.getClass().getName() + + ". Supported: " + KeyStoreParameter.class.getName() + ", " + + KeyProtection.class.getName()); + } else { + spec = null; + } + byte[] keyBytes = null; final String pkeyAlias; @@ -383,7 +447,7 @@ public class AndroidKeyStore extends KeyStoreSpi { Credentials.deleteSecretKeyTypeForAlias(mKeyStore, alias); } - final int flags = (params == null) ? 0 : params.getFlags(); + final int flags = (spec == null) ? 0 : spec.getFlags(); if (shouldReplacePrivateKey && !mKeyStore.importKey(Credentials.USER_PRIVATE_KEY + alias, keyBytes, @@ -402,8 +466,16 @@ public class AndroidKeyStore extends KeyStoreSpi { } } - private void setSecretKeyEntry(String entryAlias, SecretKey key, KeyStoreParameter params) + private void setSecretKeyEntry(String entryAlias, SecretKey key, + java.security.KeyStore.ProtectionParameter param) throws KeyStoreException { + if ((param != null) && (!(param instanceof KeyProtection))) { + throw new KeyStoreException( + "Unsupported protection parameter class: " + param.getClass().getName() + + ". Supported: " + KeyProtection.class.getName()); + } + KeyProtection params = (KeyProtection) param; + if (key instanceof KeyStoreSecretKey) { // KeyStore-backed secret key. It cannot be duplicated into another entry and cannot // overwrite its own entry. @@ -453,10 +525,9 @@ public class AndroidKeyStore extends KeyStoreSpi { int keymasterAlgorithm; int keymasterDigest; try { - keymasterAlgorithm = KeyStoreKeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm( - keyAlgorithmString); - keymasterDigest = - KeyStoreKeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString); + keymasterAlgorithm = + KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(keyAlgorithmString); + keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString); } catch (IllegalArgumentException e) { throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString); } @@ -467,7 +538,7 @@ public class AndroidKeyStore extends KeyStoreSpi { int[] keymasterDigests; if (params.isDigestsSpecified()) { // Digest(s) specified in parameters - keymasterDigests = KeyStoreKeyProperties.Digest.allToKeymaster(params.getDigests()); + keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); if (keymasterDigest != -1) { // Digest also specified in the JCA key algorithm name. if (!com.android.internal.util.ArrayUtils.contains( @@ -509,33 +580,32 @@ public class AndroidKeyStore extends KeyStoreSpi { } } - @KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes(); + @KeyProperties.PurposeEnum int purposes = params.getPurposes(); int[] keymasterBlockModes = - KeyStoreKeyProperties.BlockMode.allToKeymaster(params.getBlockModes()); - if (((purposes & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0) + KeyProperties.BlockMode.allToKeymaster(params.getBlockModes()); + if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (params.isRandomizedEncryptionRequired())) { for (int keymasterBlockMode : keymasterBlockModes) { if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) { throw new KeyStoreException( "Randomized encryption (IND-CPA) required but may be violated by block" + " mode: " - + KeyStoreKeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) - + ". See KeyStoreParameter documentation."); + + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + + ". See KeyProtection documentation."); } } } - for (int keymasterPurpose : KeyStoreKeyProperties.Purpose.allToKeymaster(purposes)) { + for (int keymasterPurpose : KeyProperties.Purpose.allToKeymaster(purposes)) { args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose); } args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes); if (params.getSignaturePaddings().length > 0) { throw new KeyStoreException("Signature paddings not supported for symmetric keys"); } - int[] keymasterPaddings = KeyStoreKeyProperties.EncryptionPadding.allToKeymaster( + int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster( params.getEncryptionPaddings()); args.addInts(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings); KeymasterUtils.addUserAuthArgs(args, - params.getContext(), params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, @@ -551,7 +621,7 @@ public class AndroidKeyStore extends KeyStoreSpi { // TODO: Remove this once keymaster does not require us to specify the size of imported key. args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, keyMaterial.length * 8); - if (((purposes & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0) + if (((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!params.isRandomizedEncryptionRequired())) { // Permit caller-provided IV when encrypting with this key args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); @@ -789,19 +859,12 @@ public class AndroidKeyStore extends KeyStoreSpi { return; } - if (param != null && !(param instanceof KeyStoreParameter)) { - throw new KeyStoreException( - "protParam should be android.security.KeyStoreParameter; was: " - + param.getClass().getName()); - } - if (entry instanceof PrivateKeyEntry) { PrivateKeyEntry prE = (PrivateKeyEntry) entry; - setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(), - (KeyStoreParameter) param); + setPrivateKeyEntry(alias, prE.getPrivateKey(), prE.getCertificateChain(), param); } else if (entry instanceof SecretKeyEntry) { SecretKeyEntry secE = (SecretKeyEntry) entry; - setSecretKeyEntry(alias, secE.getSecretKey(), (KeyStoreParameter) param); + setSecretKeyEntry(alias, secE.getSecretKey(), param); } else { throw new KeyStoreException( "Entry must be a PrivateKeyEntry, SecretKeyEntry or TrustedCertificateEntry" diff --git a/keystore/java/android/security/ArrayUtils.java b/keystore/java/android/security/ArrayUtils.java index 2047d3fc0be50..71b99d035dd11 100644 --- a/keystore/java/android/security/ArrayUtils.java +++ b/keystore/java/android/security/ArrayUtils.java @@ -5,7 +5,7 @@ import libcore.util.EmptyArray; /** * @hide */ -abstract class ArrayUtils { +public abstract class ArrayUtils { private ArrayUtils() {} public static String[] nullToEmpty(String[] array) { diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java index 3853ecad12e1d..19b62a653e5ba 100644 --- a/keystore/java/android/security/KeyChain.java +++ b/keystore/java/android/security/KeyChain.java @@ -28,6 +28,8 @@ import android.os.Looper; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; +import android.security.keystore.KeyProperties; + import java.io.ByteArrayInputStream; import java.io.Closeable; import java.security.InvalidKeyException; @@ -266,7 +268,7 @@ public final class KeyChain { */ public static void choosePrivateKeyAlias(@NonNull Activity activity, @NonNull KeyChainAliasCallback response, - @KeyStoreKeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers, + @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers, @Nullable String host, int port, @Nullable String alias) { choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias); } @@ -312,7 +314,7 @@ public final class KeyChain { */ public static void choosePrivateKeyAlias(@NonNull Activity activity, @NonNull KeyChainAliasCallback response, - @KeyStoreKeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers, + @KeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers, @Nullable String host, int port, @Nullable String url, @Nullable String alias) { /* * TODO currently keyTypes, issuers are unused. They are meant @@ -439,10 +441,10 @@ public final class KeyChain { * "RSA"). */ public static boolean isKeyAlgorithmSupported( - @NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) { + @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) { final String algUpper = algorithm.toUpperCase(Locale.US); - return KeyStoreKeyProperties.KEY_ALGORITHM_EC.equals(algUpper) - || KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equals(algUpper); + return KeyProperties.KEY_ALGORITHM_EC.equals(algUpper) + || KeyProperties.KEY_ALGORITHM_RSA.equals(algUpper); } /** @@ -453,7 +455,7 @@ public final class KeyChain { * that makes it non-exportable. */ public static boolean isBoundKeyAlgorithm( - @NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) { + @NonNull @KeyProperties.KeyAlgorithmEnum String algorithm) { if (!isKeyAlgorithmSupported(algorithm)) { return false; } diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java index b07c05238ded1..efbce41f9dc70 100644 --- a/keystore/java/android/security/KeyPairGeneratorSpec.java +++ b/keystore/java/android/security/KeyPairGeneratorSpec.java @@ -17,14 +17,14 @@ package android.security; import android.app.KeyguardManager; -import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; import android.text.TextUtils; import java.math.BigInteger; -import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.cert.Certificate; @@ -34,72 +34,32 @@ import java.util.Date; import javax.security.auth.x500.X500Principal; /** - * {@link AlgorithmParameterSpec} for initializing a {@link KeyPairGenerator} of the - * Android KeyStore facility. This class - * specifies whether user authentication is required for using the private key, what uses the - * private key is authorized for (e.g., only for signing -- decryption not permitted), whether the - * private key should be encrypted at rest, the private key's and validity start and end dates. + * This provides the required parameters needed for initializing the + * {@code KeyPairGenerator} that works with + * Android KeyStore + * facility. The Android KeyStore facility is accessed through a + * {@link java.security.KeyPairGenerator} API using the {@code AndroidKeyStore} + * provider. The {@code context} passed in may be used to pop up some UI to ask + * the user to unlock or initialize the Android KeyStore facility. + *

+ * After generation, the {@code keyStoreAlias} is used with the + * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)} + * interface to retrieve the {@link PrivateKey} and its associated + * {@link Certificate} chain. + *

+ * The KeyPair generator will create a self-signed certificate with the subject + * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer + * Distinguished Name along with the other parameters specified with the + * {@link Builder}. + *

+ * The self-signed X.509 certificate may be replaced at a later time by a + * certificate signed by a real Certificate Authority. * - *

To generate a key pair, create an instance of this class using the {@link Builder}, initialize - * a {@code KeyPairGenerator} of the desired key type (e.g., {@code EC} or {@code RSA}) from the - * {@code AndroidKeyStore} provider with the {@code KeyPairGeneratorSpec} instance, and then - * generate a key pair using {@link KeyPairGenerator#generateKeyPair()}. - * - *

The generated key pair will be returned by the {@code KeyPairGenerator} and also stored in the - * Android KeyStore under the alias specified in this {@code KeyPairGeneratorSpec}. To obtain the - * private key from the Android KeyStore use - * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or - * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}. - * To obtain the public key from the Android KeyStore use - * {@link java.security.KeyStore#getCertificate(String)} and then - * {@link Certificate#getPublicKey()}. - * - *

A self-signed X.509 certificate will be also generated and stored in the Android KeyStore. - * This is because the {@link java.security.KeyStore} abstraction does not support storing key pairs - * without a certificate. The subject, serial number, and validity dates of the certificate can be - * specified in this {@code KeyPairGeneratorSpec}. The self-signed certificate may be replaced at a - * later time by a certificate signed by a Certificate Authority (CA). - * - *

NOTE: The key material of the private keys generating using the {@code KeyPairGeneratorSpec} - * is not accessible. The key material of the public keys is accessible. - * - *

Example

- * The following example illustrates how to generate an EC key pair in the Android KeyStore under - * alias {@code key2} authorized to be used only for signing using SHA-256, SHA-384, or SHA-512 - * digest and only if the user has been authenticated within the last five minutes. - *
 {@code
- * KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
- *         KeyStoreKeyProperties.KEY_ALGORITHM_EC,
- *         "AndroidKeyStore");
- * keyPairGenerator.initialize(
- *         new KeyGeneratorSpec.Builder(context)
- *                 .setAlias("key2")
- *                 .setPurposes(KeyStoreKeyProperties.PURPOSE_SIGN
- *                         | KeyStoreKeyProperties.PURPOSE_VERIFY)
- *                 .setDigests(KeyStoreKeyProperties.DIGEST_SHA256
- *                         | KeyStoreKeyProperties.DIGEST_SHA384
- *                         | KeyStoreKeyProperties.DIGEST_SHA512)
- *                 // Only permit this key to be used if the user authenticated
- *                 // within the last five minutes.
- *                 .setUserAuthenticationRequired(true)
- *                 .setUserAuthenticationValidityDurationSeconds(5 * 60)
- *                 .build());
- * KeyPair keyPair = keyPairGenerator.generateKey();
- *
- * // The key pair can also be obtained from the Android KeyStore any time as follows:
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * PrivateKey privateKey = (PrivateKey) keyStore.getKey("key2", null);
- * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * }
+ * @deprecated Use {@link KeyGenParameterSpec} instead. */ +@Deprecated public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { - private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake"); - private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1"); - private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970 - private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048 - private final Context mContext; private final String mKeystoreAlias; @@ -120,28 +80,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { private final int mFlags; - private final Date mKeyValidityStart; - - private final Date mKeyValidityForOriginationEnd; - - private final Date mKeyValidityForConsumptionEnd; - - private final @KeyStoreKeyProperties.PurposeEnum int mPurposes; - - private final @KeyStoreKeyProperties.DigestEnum String[] mDigests; - - private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; - - private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; - - private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes; - - private final boolean mRandomizedEncryptionRequired; - - private final boolean mUserAuthenticationRequired; - - private final int mUserAuthenticationValidityDurationSeconds; - /** * Parameter specification for the "{@code AndroidKeyPairGenerator}" * instance of the {@link java.security.KeyPairGenerator} API. The @@ -162,7 +100,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { * @param context Android context for the activity * @param keyStoreAlias name to use for the generated key in the Android * keystore - * @param keyType key algorithm to use (EC, RSA) + * @param keyType key algorithm to use (RSA, DSA, EC) * @param keySize size of key to generate * @param spec the underlying key type parameters * @param subjectDN X.509 v3 Subject Distinguished Name @@ -176,39 +114,21 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { */ public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, - Date startDate, Date endDate, int flags, - Date keyValidityStart, - Date keyValidityForOriginationEnd, - Date keyValidityForConsumptionEnd, - @KeyStoreKeyProperties.PurposeEnum int purposes, - @KeyStoreKeyProperties.DigestEnum String[] digests, - @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, - @KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings, - @KeyStoreKeyProperties.BlockModeEnum String[] blockModes, - boolean randomizedEncryptionRequired, - boolean userAuthenticationRequired, - int userAuthenticationValidityDurationSeconds) { + Date startDate, Date endDate, int flags) { if (context == null) { throw new IllegalArgumentException("context == null"); } else if (TextUtils.isEmpty(keyStoreAlias)) { throw new IllegalArgumentException("keyStoreAlias must not be empty"); - } else if ((userAuthenticationValidityDurationSeconds < 0) - && (userAuthenticationValidityDurationSeconds != -1)) { - throw new IllegalArgumentException( - "userAuthenticationValidityDurationSeconds must not be negative"); - } - - if (subjectDN == null) { - subjectDN = DEFAULT_CERT_SUBJECT; - } - if (startDate == null) { - startDate = DEFAULT_CERT_NOT_BEFORE; - } - if (endDate == null) { - endDate = DEFAULT_CERT_NOT_AFTER; - } - if (serialNumber == null) { - serialNumber = DEFAULT_CERT_SERIAL_NUMBER; + } else if (subjectDN == null) { + throw new IllegalArgumentException("subjectDN == null"); + } else if (serialNumber == null) { + throw new IllegalArgumentException("serialNumber == null"); + } else if (startDate == null) { + throw new IllegalArgumentException("startDate == null"); + } else if (endDate == null) { + throw new IllegalArgumentException("endDate == null"); + } else if (endDate.before(startDate)) { + throw new IllegalArgumentException("endDate < startDate"); } if (endDate.before(startDate)) { @@ -225,50 +145,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { mStartDate = startDate; mEndDate = endDate; mFlags = flags; - mKeyValidityStart = keyValidityStart; - mKeyValidityForOriginationEnd = keyValidityForOriginationEnd; - mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd; - mPurposes = purposes; - mDigests = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(digests)); - mEncryptionPaddings = - ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); - mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); - mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); - mRandomizedEncryptionRequired = randomizedEncryptionRequired; - mUserAuthenticationRequired = userAuthenticationRequired; - mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; - } - - /** - * TODO: Remove this constructor once tests are switched over to the new one above. - * @hide - */ - public KeyPairGeneratorSpec(Context context, String keyStoreAlias, String keyType, int keySize, - AlgorithmParameterSpec spec, X500Principal subjectDN, BigInteger serialNumber, - Date startDate, Date endDate, int flags) { - - this(context, - keyStoreAlias, - keyType, - keySize, - spec, - subjectDN, - serialNumber, - startDate, - endDate, - flags, - startDate, - endDate, - endDate, - 0, // purposes - null, // digests - null, // encryption paddings - null, // signature paddings - null, // block modes - false, // randomized encryption required - false, // user authentication required - -1 // user authentication validity duration (seconds) - ); } /** @@ -288,10 +164,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See - * {@link KeyStoreKeyProperties}.{@code KEY_ALGORITHM} constants. + * {@link KeyProperties}.{@code KEY_ALGORITHM} constants. */ @Nullable - public @KeyStoreKeyProperties.KeyAlgorithmEnum String getKeyType() { + public @KeyProperties.KeyAlgorithmEnum String getKeyType() { return mKeyType; } @@ -352,147 +228,26 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * @hide */ - int getFlags() { + public int getFlags() { return mFlags; } /** * Returns {@code true} if the key must be encrypted at rest. This will protect the key pair * with the secure lock screen credential (e.g., password, PIN, or pattern). + * + *

Note that encrypting the key at rest requires that the secure lock screen (e.g., password, + * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be + * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device + * Administrator). Finally, this key cannot be used until the user unlocks the secure lock + * screen after boot. + * + * @see KeyguardManager#isDeviceSecure() */ public boolean isEncryptionRequired() { return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; } - /** - * Gets the time instant before which the key pair is not yet valid. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityStart() { - return mKeyValidityStart; - } - - /** - * Gets the time instant after which the key pair is no longer valid for decryption and - * verification. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityForConsumptionEnd() { - return mKeyValidityForConsumptionEnd; - } - - /** - * Gets the time instant after which the key pair is no longer valid for encryption and signing. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityForOriginationEnd() { - return mKeyValidityForOriginationEnd; - } - - /** - * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. - * Attempts to use the key for any other purpose will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags. - */ - public @KeyStoreKeyProperties.PurposeEnum int getPurposes() { - return mPurposes; - } - - /** - * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384} with which the key - * can be used. - * - * @see KeyStoreKeyProperties.Digest - */ - @NonNull - public @KeyStoreKeyProperties.DigestEnum String[] getDigests() { - return ArrayUtils.cloneIfNotEmpty(mDigests); - } - - /** - * Gets the set of padding schemes (e.g., {@code OEAPPadding}, {@code PKCS1Padding}, - * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use - * the key with any other padding scheme will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants. - */ - @NonNull - public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { - return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); - } - - /** - * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key - * can be used when signing/verifying. Attempts to use the key with any other padding scheme - * will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants. - */ - @NonNull - public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { - return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); - } - - /** - * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used - * when encrypting/decrypting. Attempts to use the key with any other block modes will be - * rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants. - */ - @NonNull - public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() { - return ArrayUtils.cloneIfNotEmpty(mBlockModes); - } - - /** - * Returns {@code true} if encryption using this key must be sufficiently randomized to produce - * different ciphertexts for the same plaintext every time. The formal cryptographic property - * being required is indistinguishability under chosen-plaintext attack ({@code - * IND-CPA}). This property is important because it mitigates several classes of - * weaknesses due to which ciphertext may leak information about plaintext. For example, if a - * given plaintext always produces the same ciphertext, an attacker may see the repeated - * ciphertexts and be able to deduce something about the plaintext. - */ - public boolean isRandomizedEncryptionRequired() { - return mRandomizedEncryptionRequired; - } - - /** - * Returns {@code true} if user authentication is required for this key to be used. - * - *

This restriction applies only to private key operations. Public key operations are not - * restricted. - * - * @see #getUserAuthenticationValidityDurationSeconds() - */ - public boolean isUserAuthenticationRequired() { - return mUserAuthenticationRequired; - } - - /** - * Gets the duration of time (seconds) for which this key can be used after the user is - * successfully authenticated. This has effect only if user authentication is required. - * - *

This restriction applies only to private key operations. Public key operations are not - * restricted. - * - * @return duration in seconds or {@code -1} if authentication is required for every use of the - * key. - * - * @see #isUserAuthenticationRequired() - */ - public int getUserAuthenticationValidityDurationSeconds() { - return mUserAuthenticationValidityDurationSeconds; - } - /** * Builder class for {@link KeyPairGeneratorSpec} objects. *

@@ -513,7 +268,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { * .setSubject(new X500Principal("CN=myKey")).setSerial(BigInteger.valueOf(1337)) * .setStartDate(start.getTime()).setEndDate(end.getTime()).build(); * + * + * @deprecated Use {@link KeyGenParameterSpec.Builder} instead. */ + @Deprecated public final static class Builder { private final Context mContext; @@ -535,28 +293,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { private int mFlags; - private Date mKeyValidityStart; - - private Date mKeyValidityForOriginationEnd; - - private Date mKeyValidityForConsumptionEnd; - - private @KeyStoreKeyProperties.PurposeEnum int mPurposes; - - private @KeyStoreKeyProperties.DigestEnum String[] mDigests; - - private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; - - private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; - - private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes; - - private boolean mRandomizedEncryptionRequired = true; - - private boolean mUserAuthenticationRequired; - - private int mUserAuthenticationValidityDurationSeconds = -1; - /** * Creates a new instance of the {@code Builder} with the given * {@code context}. The {@code context} passed in may be used to pop up @@ -586,11 +322,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the type of key pair (e.g., {@code EC}, {@code RSA}) of the key pair to be - * generated. See {@link KeyStoreKeyProperties}.{@code KEY_ALGORITHM} constants. + * generated. See {@link KeyProperties}.{@code KEY_ALGORITHM} constants. * */ @NonNull - public Builder setKeyType(@NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String keyType) + public Builder setKeyType(@NonNull @KeyProperties.KeyAlgorithmEnum String keyType) throws NoSuchAlgorithmException { if (keyType == null) { throw new NullPointerException("keyType == null"); @@ -632,10 +368,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the subject used for the self-signed certificate of the * generated key pair. - * - *

The subject must be specified on API Level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On - * newer platforms the subject defaults to {@code CN=fake} if not specified. */ @NonNull public Builder setSubject(@NonNull X500Principal subject) { @@ -649,10 +381,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the serial number used for the self-signed certificate of the * generated key pair. - * - *

The serial number must be specified on API Level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On - * newer platforms the serial number defaults to {@code 1} if not specified. */ @NonNull public Builder setSerialNumber(@NonNull BigInteger serialNumber) { @@ -666,10 +394,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the start of the validity period for the self-signed certificate * of the generated key pair. - * - *

The date must be specified on API Level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On - * newer platforms the date defaults to {@code Jan 1 1970} if not specified. */ @NonNull public Builder setStartDate(@NonNull Date startDate) { @@ -683,10 +407,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { /** * Sets the end of the validity period for the self-signed certificate * of the generated key pair. - * - *

The date must be specified on API Level - * {@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1 LOLLIPOP_MR1} and older platforms. On - * newer platforms the date defaults to {@code Jan 1 2048} if not specified. */ @NonNull public Builder setEndDate(@NonNull Date endDate) { @@ -715,239 +435,6 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { return this; } - /** - * Sets the time instant before which the key is not yet valid. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect. - * - * @see #setKeyValidityEnd(Date) - */ - @NonNull - public Builder setKeyValidityStart(Date startDate) { - mKeyValidityStart = startDate; - return this; - } - - /** - * Sets the time instant after which the key is no longer valid. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect. - * - * @see #setKeyValidityStart(Date) - * @see #setKeyValidityForConsumptionEnd(Date) - * @see #setKeyValidityForOriginationEnd(Date) - */ - @NonNull - public Builder setKeyValidityEnd(Date endDate) { - setKeyValidityForOriginationEnd(endDate); - setKeyValidityForConsumptionEnd(endDate); - return this; - } - - /** - * Sets the time instant after which the key is no longer valid for encryption and signing. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect. - * - * @see #setKeyValidityForConsumptionEnd(Date) - */ - @NonNull - public Builder setKeyValidityForOriginationEnd(Date endDate) { - mKeyValidityForOriginationEnd = endDate; - return this; - } - - /** - * Sets the time instant after which the key is no longer valid for decryption and - * verification. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect. - * - * @see #setKeyValidityForOriginationEnd(Date) - */ - @NonNull - public Builder setKeyValidityForConsumptionEnd(Date endDate) { - mKeyValidityForConsumptionEnd = endDate; - return this; - } - - /** - * Sets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. - * Attempts to use the key for any other purpose will be rejected. - * - *

This must be specified for all keys. There is no default. - * - *

If the set of purposes for which the key can be used does not contain - * {@link KeyStoreKeyProperties#PURPOSE_SIGN}, the self-signed certificate generated by - * {@link KeyPairGenerator} of {@code AndroidKeyStore} provider will contain an invalid - * signature. This is OK if the certificate is only used for obtaining the public key from - * Android KeyStore. - * - *

NOTE: This has currently no effect. - * - *

See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags. - */ - @NonNull - public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) { - mPurposes = purposes; - return this; - } - - /** - * Sets the set of digests algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which - * the key can be used when signing/verifying. Attempts to use the key with any other digest - * algorithm will be rejected. - * - *

This must be specified for keys which are used for signing/verification. - * - *

NOTE: This has currently no effect. - * - * @see KeyStoreKeyProperties.Digest - */ - @NonNull - public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) { - mDigests = ArrayUtils.cloneIfNotEmpty(digests); - return this; - } - - /** - * Sets the set of padding schemes (e.g., {@code OAEPPadding}, {@code PKCS1Padding}, - * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to - * use the key with any other padding scheme will be rejected. - * - *

This must be specified for keys which are used for encryption/decryption. - * - *

NOTE: This has currently no effect. - * - *

See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants. - */ - @NonNull - public Builder setEncryptionPaddings( - @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) { - mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings); - return this; - } - - /** - * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key - * can be used when signing/verifying. Attempts to use the key with any other padding scheme - * will be rejected. - * - *

This must be specified for RSA keys which are used for signing/verification. - * - *

NOTE: This has currently no effect. - * - *

See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants. - */ - @NonNull - public Builder setSignaturePaddings( - @KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) { - mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings); - return this; - } - - /** - * Sets the set of block modes (e.g., {@code ECB}, {@code CBC}, {@code CTR}) with which the - * key can be used when encrypting/decrypting. Attempts to use the key with any other block - * modes will be rejected. - * - *

This must be specified for encryption/decryption keys. - * - *

NOTE: This has currently no effect. - * - *

See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants. - */ - @NonNull - public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) { - mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes); - return this; - } - - /** - * Sets whether encryption using this key must be sufficiently randomized to produce - * different ciphertexts for the same plaintext every time. The formal cryptographic - * property being required is indistinguishability under chosen-plaintext attack - * ({@code IND-CPA}). This property is important because it mitigates several classes - * of weaknesses due to which ciphertext may leak information about plaintext. For example, - * if a given plaintext always produces the same ciphertext, an attacker may see the - * repeated ciphertexts and be able to deduce something about the plaintext. - * - *

By default, {@code IND-CPA} is required. - * - *

When {@code IND-CPA} is required, encryption/decryption transformations which do not - * offer {@code IND-CPA}, such as RSA without padding, are prohibited. - * - *

Before disabling this requirement, consider the following approaches instead: - *

- * - *

NOTE: This has currently no effect. - */ - @NonNull - public Builder setRandomizedEncryptionRequired(boolean required) { - mRandomizedEncryptionRequired = required; - return this; - } - - /** - * Sets whether user authentication is required to use this key. - * - *

By default, the key can be used without user authentication. - * - *

When user authentication is required, the user authorizes the use of the key by - * authenticating to this Android device using a subset of their secure lock screen - * credentials. Different authentication methods are used depending on whether the every - * use of the key must be authenticated (as specified by - * {@link #setUserAuthenticationValidityDurationSeconds(int)}). - * More - * information. - * - *

This restriction applies only to private key operations. Public key operations are not - * restricted. - * - *

NOTE: This has currently no effect. - * - * @see #setUserAuthenticationValidityDurationSeconds(int) - */ - @NonNull - public Builder setUserAuthenticationRequired(boolean required) { - mUserAuthenticationRequired = required; - return this; - } - - /** - * Sets the duration of time (seconds) for which this key can be used after the user is - * successfully authenticated. This has effect only if user authentication is required. - * - *

By default, the user needs to authenticate for every use of the key. - * - *

This restriction applies only to private key operations. Public key operations are not - * restricted. - * - *

NOTE: This has currently no effect. - * - * @param seconds duration in seconds or {@code -1} if the user needs to authenticate for - * every use of the key. - * - * @see #setUserAuthenticationRequired(boolean) - */ - @NonNull - public Builder setUserAuthenticationValidityDurationSeconds( - @IntRange(from = -1) int seconds) { - mUserAuthenticationValidityDurationSeconds = seconds; - return this; - } - /** * Builds the instance of the {@code KeyPairGeneratorSpec}. * @@ -965,18 +452,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec { mSerialNumber, mStartDate, mEndDate, - mFlags, - mKeyValidityStart, - mKeyValidityForOriginationEnd, - mKeyValidityForConsumptionEnd, - mPurposes, - mDigests, - mEncryptionPaddings, - mSignaturePaddings, - mBlockModes, - mRandomizedEncryptionRequired, - mUserAuthenticationRequired, - mUserAuthenticationValidityDurationSeconds); + mFlags); } } } diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index caa4fec4548eb..72c74dffc448d 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -35,6 +35,11 @@ import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterBlob; import android.security.keymaster.KeymasterDefs; import android.security.keymaster.OperationResult; +import android.security.keystore.KeyExpiredException; +import android.security.keystore.KeyNotYetValidException; +import android.security.keystore.KeyPermanentlyInvalidatedException; +import android.security.keystore.KeyProperties; +import android.security.keystore.UserNotAuthenticatedException; import android.util.Log; import java.security.InvalidKeyException; @@ -101,10 +106,10 @@ public class KeyStore { private KeyStore(IKeystoreService binder) { mBinder = binder; - mContext = getContext(); + mContext = getApplicationContext(); } - private static Context getContext() { + static Context getApplicationContext() { ActivityThread activityThread = ActivityThread.currentActivityThread(); if (activityThread == null) { throw new IllegalStateException( @@ -131,10 +136,10 @@ public class KeyStore { return mToken; } - static int getKeyTypeForAlgorithm(@KeyStoreKeyProperties.KeyAlgorithmEnum String keyType) { - if (KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) { + static int getKeyTypeForAlgorithm(@KeyProperties.KeyAlgorithmEnum String keyType) { + if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) { return NativeConstants.EVP_PKEY_RSA; - } else if (KeyStoreKeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyType)) { + } else if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyType)) { return NativeConstants.EVP_PKEY_EC; } else { return -1; diff --git a/keystore/java/android/security/KeyStoreCipherSpi.java b/keystore/java/android/security/KeyStoreCipherSpi.java index 4eeca47a6b5c1..b0f1695188c2a 100644 --- a/keystore/java/android/security/KeyStoreCipherSpi.java +++ b/keystore/java/android/security/KeyStoreCipherSpi.java @@ -20,6 +20,7 @@ import android.os.IBinder; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; import android.security.keymaster.OperationResult; +import android.security.keystore.KeyProperties; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; @@ -496,7 +497,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry if ((mIv != null) && (mIv.length > 0)) { try { AlgorithmParameters params = - AlgorithmParameters.getInstance(KeyStoreKeyProperties.KEY_ALGORITHM_AES); + AlgorithmParameters.getInstance(KeyProperties.KEY_ALGORITHM_AES); params.init(new IvParameterSpec(mIv)); return params; } catch (NoSuchAlgorithmException e) { diff --git a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/KeyStoreCryptoOperationUtils.java index 311278bab16b8..c9bdd41676dde 100644 --- a/keystore/java/android/security/KeyStoreCryptoOperationUtils.java +++ b/keystore/java/android/security/KeyStoreCryptoOperationUtils.java @@ -17,6 +17,7 @@ package android.security; import android.security.keymaster.KeymasterDefs; +import android.security.keystore.UserNotAuthenticatedException; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java index d734d66d95fde..feec00f7b77b5 100644 --- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java @@ -19,11 +19,16 @@ package android.security; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterDefs; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProperties; + +import libcore.util.EmptyArray; import java.security.InvalidAlgorithmParameterException; import java.security.ProviderException; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; +import java.util.Arrays; import java.util.Date; import javax.crypto.KeyGeneratorSpi; @@ -96,13 +101,14 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { private final int mKeymasterDigest; private final int mDefaultKeySizeBits; - private KeyGeneratorSpec mSpec; + private KeyGenParameterSpec mSpec; private SecureRandom mRng; protected int mKeySizeBits; private int[] mKeymasterPurposes; private int[] mKeymasterBlockModes; private int[] mKeymasterPaddings; + private int[] mKeymasterDigests; protected KeyStoreKeyGeneratorSpi( int keymasterAlgorithm, @@ -129,14 +135,14 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { @Override protected void engineInit(SecureRandom random) { - throw new UnsupportedOperationException("Cannot initialize without an " - + KeyGeneratorSpec.class.getName() + " parameter"); + throw new UnsupportedOperationException("Cannot initialize without a " + + KeyGenParameterSpec.class.getName() + " parameter"); } @Override protected void engineInit(int keySize, SecureRandom random) { throw new UnsupportedOperationException("Cannot initialize without a " - + KeyGeneratorSpec.class.getName() + " parameter"); + + KeyGenParameterSpec.class.getName() + " parameter"); } @Override @@ -146,11 +152,11 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { boolean success = false; try { - if ((params == null) || (!(params instanceof KeyGeneratorSpec))) { - throw new InvalidAlgorithmParameterException("Cannot initialize without an " - + KeyGeneratorSpec.class.getName() + " parameter"); + if ((params == null) || (!(params instanceof KeyGenParameterSpec))) { + throw new InvalidAlgorithmParameterException("Cannot initialize without a " + + KeyGenParameterSpec.class.getName() + " parameter"); } - KeyGeneratorSpec spec = (KeyGeneratorSpec) params; + KeyGenParameterSpec spec = (KeyGenParameterSpec) params; if (spec.getKeystoreAlias() == null) { throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided"); } @@ -168,13 +174,11 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { } try { - mKeymasterPurposes = - KeyStoreKeyProperties.Purpose.allToKeymaster(spec.getPurposes()); - mKeymasterPaddings = KeyStoreKeyProperties.EncryptionPadding.allToKeymaster( + mKeymasterPurposes = KeyProperties.Purpose.allToKeymaster(spec.getPurposes()); + mKeymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster( spec.getEncryptionPaddings()); - mKeymasterBlockModes = - KeyStoreKeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()); - if (((spec.getPurposes() & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0) + mKeymasterBlockModes = KeyProperties.BlockMode.allToKeymaster(spec.getBlockModes()); + if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (spec.isRandomizedEncryptionRequired())) { for (int keymasterBlockMode : mKeymasterBlockModes) { if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible( @@ -182,14 +186,55 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { throw new InvalidAlgorithmParameterException( "Randomized encryption (IND-CPA) required but may be violated" + " by block mode: " - + KeyStoreKeyProperties.BlockMode.fromKeymaster( - keymasterBlockMode) - + ". See " + KeyGeneratorSpec.class.getName() + + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + + ". See " + KeyGenParameterSpec.class.getName() + " documentation."); } } } - } catch (IllegalArgumentException e) { + if (spec.isDigestsSpecified()) { + // Digest(s) explicitly specified in the spec + mKeymasterDigests = KeyProperties.Digest.allToKeymaster(spec.getDigests()); + if (mKeymasterDigest != -1) { + // Key algorithm implies a digest -- ensure it's specified in the spec as + // first digest. + if (!com.android.internal.util.ArrayUtils.contains( + mKeymasterDigests, mKeymasterDigest)) { + throw new InvalidAlgorithmParameterException( + "Digests specified in algorithm parameters (" + + Arrays.asList(spec.getDigests()) + ") must include " + + " the digest " + + KeyProperties.Digest.fromKeymaster(mKeymasterDigest) + + " implied by key algorithm"); + } + if (mKeymasterDigests[0] != mKeymasterDigest) { + // The first digest is not the one implied by the key algorithm. + // Swap the implied digest with the first one. + for (int i = 0; i < mKeymasterDigests.length; i++) { + if (mKeymasterDigests[i] == mKeymasterDigest) { + mKeymasterDigests[i] = mKeymasterDigests[0]; + mKeymasterDigests[0] = mKeymasterDigest; + break; + } + } + } + } + } else { + // No digest specified in the spec + if (mKeymasterDigest != -1) { + // Key algorithm implies a digest -- use that digest + mKeymasterDigests = new int[] {mKeymasterDigest}; + } else { + mKeymasterDigests = EmptyArray.INT; + } + } + if (mKeymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { + if (mKeymasterDigests.length == 0) { + throw new InvalidAlgorithmParameterException( + "At least one digest algorithm must be specified"); + } + } + } catch (IllegalStateException | IllegalArgumentException e) { throw new InvalidAlgorithmParameterException(e); } @@ -212,29 +257,26 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { @Override protected SecretKey engineGenerateKey() { - KeyGeneratorSpec spec = mSpec; + KeyGenParameterSpec spec = mSpec; if (spec == null) { throw new IllegalStateException("Not initialized"); } - if ((spec.isEncryptionRequired()) + if ((spec.isEncryptionAtRestRequired()) && (mKeyStore.state() != KeyStore.State.UNLOCKED)) { throw new IllegalStateException( - "Android KeyStore must be in initialized and unlocked state if encryption is" - + " required"); + "Requested to import a key which must be encrypted at rest using secure lock" + + " screen credential, but the credential hasn't yet been entered by the user"); } KeymasterArguments args = new KeymasterArguments(); args.addInt(KeymasterDefs.KM_TAG_KEY_SIZE, mKeySizeBits); args.addInt(KeymasterDefs.KM_TAG_ALGORITHM, mKeymasterAlgorithm); - if (mKeymasterDigest != -1) { - args.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest); - } args.addInts(KeymasterDefs.KM_TAG_PURPOSE, mKeymasterPurposes); args.addInts(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes); args.addInts(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings); + args.addInts(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests); KeymasterUtils.addUserAuthArgs(args, - spec.getContext(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); args.addDate(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, @@ -247,7 +289,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { (spec.getKeyValidityForConsumptionEnd() != null) ? spec.getKeyValidityForConsumptionEnd() : new Date(Long.MAX_VALUE)); - if (((spec.getPurposes() & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0) + if (((spec.getPurposes() & KeyProperties.PURPOSE_ENCRYPT) != 0) && (!spec.isRandomizedEncryptionRequired())) { // Permit caller-provided IV when encrypting with this key args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); @@ -265,9 +307,9 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { throw new ProviderException( "Keystore operation failed", KeyStore.getKeyStoreException(errorCode)); } - @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA; + @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA; try { - keyAlgorithmJCA = KeyStoreKeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm( + keyAlgorithmJCA = KeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm( mKeymasterAlgorithm, mKeymasterDigest); } catch (IllegalArgumentException e) { throw new ProviderException("Failed to obtain JCA secret key algorithm name", e); diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java index a7fab80d29d19..174e03f842dab 100644 --- a/keystore/java/android/security/KeyStoreParameter.java +++ b/keystore/java/android/security/KeyStoreParameter.java @@ -16,145 +16,51 @@ package android.security; -import android.annotation.IntRange; import android.annotation.NonNull; -import android.annotation.Nullable; import android.app.KeyguardManager; import android.content.Context; +import android.security.keystore.KeyGenParameterSpec; +import android.security.keystore.KeyProtection; -import java.security.Key; +import java.security.KeyPairGenerator; import java.security.KeyStore.ProtectionParameter; -import java.security.cert.Certificate; -import java.util.Date; - -import javax.crypto.Cipher; /** - * Parameters specifying how to secure and restrict the use of a key or key pair being imported into - * the Android KeyStore facility. This class - * specifies whether user authentication is required for using the key, what uses the key is - * authorized for (e.g., only in {@code CTR} mode, or only for signing -- decryption not permitted), - * whether the key should be encrypted at rest, the key's and validity start and end dates. + * This provides the optional parameters that can be specified for + * {@code KeyStore} entries that work with + * Android KeyStore + * facility. The Android KeyStore facility is accessed through a + * {@link java.security.KeyStore} API using the {@code AndroidKeyStore} + * provider. The {@code context} passed in may be used to pop up some UI to ask + * the user to unlock or initialize the Android KeyStore facility. + *

+ * Any entries placed in the {@code KeyStore} may be retrieved later. Note that + * there is only one logical instance of the {@code KeyStore} per application + * UID so apps using the {@code sharedUid} facility will also share a + * {@code KeyStore}. + *

+ * Keys may be generated using the {@link KeyPairGenerator} facility with a + * {@link KeyPairGeneratorSpec} to specify the entry's {@code alias}. A + * self-signed X.509 certificate will be attached to generated entries, but that + * may be replaced at a later time by a certificate signed by a real Certificate + * Authority. * - *

To import a key or key pair into the Android KeyStore, create an instance of this class using - * the {@link Builder} and pass the instance into {@link java.security.KeyStore#setEntry(String, java.security.KeyStore.Entry, ProtectionParameter) KeyStore.setEntry} - * with the key or key pair being imported. - * - *

To obtain the secret/symmetric or private key from the Android KeyStore use - * {@link java.security.KeyStore#getKey(String, char[]) KeyStore.getKey(String, null)} or - * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter) KeyStore.getEntry(String, null)}. - * To obtain the public key from the Android KeyStore use - * {@link java.security.KeyStore#getCertificate(String)} and then - * {@link Certificate#getPublicKey()}. - * - *

NOTE: The key material of keys stored in the Android KeyStore is not accessible. - * - *

Example: Symmetric Key

- * The following example illustrates how to import an AES key into the Android KeyStore under alias - * {@code key1} authorized to be used only for encryption/decryption in CBC mode with PKCS#7 - * padding. The key must export its key material via {@link Key#getEncoded()} in {@code RAW} format. - *
 {@code
- * SecretKey key = ...; // AES key
- *
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * keyStore.setEntry(
- *         "key1",
- *         new KeyStore.SecretKeyEntry(key),
- *         new KeyStoreParameter.Builder(context)
- *                 .setPurposes(KeyStoreKeyProperties.PURPOSE_ENCRYPT
- *                         | KeyStoreKeyProperties.PURPOSE_DECRYPT)
- *                 .setBlockMode(KeyStoreKeyProperties.BLOCK_MODE_CBC)
- *                 .setEncryptionPaddings(
- *                         KeyStoreKeyProperties.ENCRYPTION_PADDING_PKCS7)
- *                 .build());
- * // Key imported, obtain a reference to it.
- * SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
- * // The original key can now be thrown away.
- * }
- * - *

Example: Asymmetric Key Pair

- * The following example illustrates how to import an EC key pair into the Android KeyStore under - * alias {@code key2} authorized to be used only for signing with SHA-256 digest and only if - * the user has been authenticated within the last ten minutes. Both the private and the public key - * must export their key material via {@link Key#getEncoded()} in {@code PKCS#8} and {@code X.509} - * format respectively. - *
 {@code
- * PrivateKey privateKey = ...;   // EC private key
- * Certificate[] certChain = ...; // Certificate chain with the first certificate
- *                                // containing the corresponding EC public key.
- *
- * KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
- * keyStore.load(null);
- * keyStore.setEntry(
- *         "key2",
- *         new KeyStore.PrivateKeyEntry(privateKey, certChain),
- *         new KeyStoreParameter.Builder(context)
- *                 .setPurposes(KeyStoreKeyProperties.PURPOSE_SIGN)
- *                 .setDigests(KeyStoreKeyProperties.DIGEST_SHA256)
- *                 // Only permit this key to be used if the user
- *                 // authenticated within the last ten minutes.
- *                 .setUserAuthenticationRequired(true)
- *                 .setUserAuthenticationValidityDurationSeconds(10 * 60)
- *                 .build());
- * // Key pair imported, obtain a reference to it.
- * PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey("key2", null);
- * PublicKey publicKey = keyStore.getCertificate("key2").getPublicKey();
- * // The original private key can now be thrown away.
- * }
+ * @deprecated Use {@link KeyProtection} instead. */ +@Deprecated public final class KeyStoreParameter implements ProtectionParameter { private final Context mContext; private final int mFlags; - private final Date mKeyValidityStart; - private final Date mKeyValidityForOriginationEnd; - private final Date mKeyValidityForConsumptionEnd; - private final @KeyStoreKeyProperties.PurposeEnum int mPurposes; - private final @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; - private final @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; - private final @KeyStoreKeyProperties.DigestEnum String[] mDigests; - private final @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes; - private final boolean mRandomizedEncryptionRequired; - private final boolean mUserAuthenticationRequired; - private final int mUserAuthenticationValidityDurationSeconds; private KeyStoreParameter( Context context, - int flags, - Date keyValidityStart, - Date keyValidityForOriginationEnd, - Date keyValidityForConsumptionEnd, - @KeyStoreKeyProperties.PurposeEnum int purposes, - @KeyStoreKeyProperties.EncryptionPaddingEnum String[] encryptionPaddings, - @KeyStoreKeyProperties.SignaturePaddingEnum String[] signaturePaddings, - @KeyStoreKeyProperties.DigestEnum String[] digests, - @KeyStoreKeyProperties.BlockModeEnum String[] blockModes, - boolean randomizedEncryptionRequired, - boolean userAuthenticationRequired, - int userAuthenticationValidityDurationSeconds) { + int flags) { if (context == null) { throw new IllegalArgumentException("context == null"); - } else if ((userAuthenticationValidityDurationSeconds < 0) - && (userAuthenticationValidityDurationSeconds != -1)) { - throw new IllegalArgumentException( - "userAuthenticationValidityDurationSeconds must not be negative"); } mContext = context; mFlags = flags; - mKeyValidityStart = keyValidityStart; - mKeyValidityForOriginationEnd = keyValidityForOriginationEnd; - mKeyValidityForConsumptionEnd = keyValidityForConsumptionEnd; - mPurposes = purposes; - mEncryptionPaddings = - ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(encryptionPaddings)); - mSignaturePaddings = - ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(signaturePaddings)); - mDigests = ArrayUtils.cloneIfNotEmpty(digests); - mBlockModes = ArrayUtils.cloneIfNotEmpty(ArrayUtils.nullToEmpty(blockModes)); - mRandomizedEncryptionRequired = randomizedEncryptionRequired; - mUserAuthenticationRequired = userAuthenticationRequired; - mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds; } /** @@ -175,150 +81,19 @@ public final class KeyStoreParameter implements ProtectionParameter { * Returns {@code true} if the {@link java.security.KeyStore} entry must be encrypted at rest. * This will protect the entry with the secure lock screen credential (e.g., password, PIN, or * pattern). + * + *

Note that encrypting the key at rest requires that the secure lock screen (e.g., password, + * PIN, pattern) is set up, otherwise key generation will fail. Moreover, this key will be + * deleted when the secure lock screen is disabled or reset (e.g., by the user or a Device + * Administrator). Finally, this key cannot be used until the user unlocks the secure lock + * screen after boot. + * + * @see KeyguardManager#isDeviceSecure() */ public boolean isEncryptionRequired() { return (mFlags & KeyStore.FLAG_ENCRYPTED) != 0; } - /** - * Gets the time instant before which the key is not yet valid. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityStart() { - return mKeyValidityStart; - } - - /** - * Gets the time instant after which the key is no long valid for decryption and verification. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityForConsumptionEnd() { - return mKeyValidityForConsumptionEnd; - } - - /** - * Gets the time instant after which the key is no long valid for encryption and signing. - * - * @return instant or {@code null} if not restricted. - */ - @Nullable - public Date getKeyValidityForOriginationEnd() { - return mKeyValidityForOriginationEnd; - } - - /** - * Gets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. - * Attempts to use the key for any other purpose will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags. - */ - public @KeyStoreKeyProperties.PurposeEnum int getPurposes() { - return mPurposes; - } - - /** - * Gets the set of padding schemes (e.g., {@code PKCS7Padding}, {@code PKCS1Padding}, - * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to use - * the key with any other padding scheme will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants. - */ - @NonNull - public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() { - return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings); - } - - /** - * Gets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key - * can be used when signing/verifying. Attempts to use the key with any other padding scheme - * will be rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants. - */ - @NonNull - public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() { - return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings); - } - - /** - * Gets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the key - * can be used. - * - * @throws IllegalStateException if this set has not been specified. - * - * @see #isDigestsSpecified() - * @see KeyStoreKeyProperties.Digest - */ - @NonNull - public @KeyStoreKeyProperties.DigestEnum String[] getDigests() { - if (mDigests == null) { - throw new IllegalStateException("Digests not specified"); - } - return ArrayUtils.cloneIfNotEmpty(mDigests); - } - - /** - * Returns {@code true} if the set of digest algorithms with which the key can be used has been - * specified. - * - * @see #getDigests() - */ - @NonNull - public boolean isDigestsSpecified() { - return mDigests != null; - } - - /** - * Gets the set of block modes (e.g., {@code CBC}, {@code CTR}) with which the key can be used - * when encrypting/decrypting. Attempts to use the key with any other block modes will be - * rejected. - * - *

See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants. - */ - @NonNull - public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() { - return ArrayUtils.cloneIfNotEmpty(mBlockModes); - } - - /** - * Returns {@code true} if encryption using this key must be sufficiently randomized to produce - * different ciphertexts for the same plaintext every time. The formal cryptographic property - * being required is indistinguishability under chosen-plaintext attack ({@code - * IND-CPA}). This property is important because it mitigates several classes of - * weaknesses due to which ciphertext may leak information about plaintext. For example, if a - * given plaintext always produces the same ciphertext, an attacker may see the repeated - * ciphertexts and be able to deduce something about the plaintext. - */ - public boolean isRandomizedEncryptionRequired() { - return mRandomizedEncryptionRequired; - } - - /** - * Returns {@code true} if user authentication is required for this key to be used. - * - * @see #getUserAuthenticationValidityDurationSeconds() - */ - public boolean isUserAuthenticationRequired() { - return mUserAuthenticationRequired; - } - - /** - * Gets the duration of time (seconds) for which this key can be used after the user is - * successfully authenticated. This has effect only if user authentication is required. - * - * @return duration in seconds or {@code -1} if authentication is required for every use of the - * key. - * - * @see #isUserAuthenticationRequired() - */ - public int getUserAuthenticationValidityDurationSeconds() { - return mUserAuthenticationValidityDurationSeconds; - } - /** * Builder class for {@link KeyStoreParameter} objects. *

@@ -332,24 +107,16 @@ public final class KeyStoreParameter implements ProtectionParameter { * *

      * KeyStoreParameter params = new KeyStoreParameter.Builder(mContext)
-     *         .setEncryptionRequired(true)
+     *         .setEncryptionRequired()
      *         .build();
      * 
+ * + * @deprecated Use {@link KeyProtection.Builder} instead. */ + @Deprecated public final static class Builder { private final Context mContext; private int mFlags; - private Date mKeyValidityStart; - private Date mKeyValidityForOriginationEnd; - private Date mKeyValidityForConsumptionEnd; - private @KeyStoreKeyProperties.PurposeEnum int mPurposes; - private @KeyStoreKeyProperties.EncryptionPaddingEnum String[] mEncryptionPaddings; - private @KeyStoreKeyProperties.SignaturePaddingEnum String[] mSignaturePaddings; - private @KeyStoreKeyProperties.DigestEnum String[] mDigests; - private @KeyStoreKeyProperties.BlockModeEnum String[] mBlockModes; - private boolean mRandomizedEncryptionRequired = true; - private boolean mUserAuthenticationRequired; - private int mUserAuthenticationValidityDurationSeconds = -1; /** * Creates a new instance of the {@code Builder} with the given @@ -387,244 +154,6 @@ public final class KeyStoreParameter implements ProtectionParameter { return this; } - /** - * Sets the time instant before which the key is not yet valid. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - * @see #setKeyValidityEnd(Date) - */ - @NonNull - public Builder setKeyValidityStart(Date startDate) { - mKeyValidityStart = startDate; - return this; - } - - /** - * Sets the time instant after which the key is no longer valid. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - * @see #setKeyValidityStart(Date) - * @see #setKeyValidityForConsumptionEnd(Date) - * @see #setKeyValidityForOriginationEnd(Date) - */ - @NonNull - public Builder setKeyValidityEnd(Date endDate) { - setKeyValidityForOriginationEnd(endDate); - setKeyValidityForConsumptionEnd(endDate); - return this; - } - - /** - * Sets the time instant after which the key is no longer valid for encryption and signing. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - * @see #setKeyValidityForConsumptionEnd(Date) - */ - @NonNull - public Builder setKeyValidityForOriginationEnd(Date endDate) { - mKeyValidityForOriginationEnd = endDate; - return this; - } - - /** - * Sets the time instant after which the key is no longer valid for decryption and - * verification. - * - *

By default, the key is valid at any instant. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - * @see #setKeyValidityForOriginationEnd(Date) - */ - @NonNull - public Builder setKeyValidityForConsumptionEnd(Date endDate) { - mKeyValidityForConsumptionEnd = endDate; - return this; - } - - /** - * Sets the set of purposes (e.g., encrypt, decrypt, sign) for which the key can be used. - * Attempts to use the key for any other purpose will be rejected. - * - *

This must be specified for all keys. There is no default. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - *

See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags. - */ - @NonNull - public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) { - mPurposes = purposes; - return this; - } - - /** - * Sets the set of padding schemes (e.g., {@code OAEPPadding}, {@code PKCS7Padding}, - * {@code NoPadding}) with which the key can be used when encrypting/decrypting. Attempts to - * use the key with any other padding scheme will be rejected. - * - *

This must be specified for keys which are used for encryption/decryption. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - *

See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants. - */ - @NonNull - public Builder setEncryptionPaddings( - @KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) { - mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings); - return this; - } - - /** - * Sets the set of padding schemes (e.g., {@code PSS}, {@code PKCS#1}) with which the key - * can be used when signing/verifying. Attempts to use the key with any other padding scheme - * will be rejected. - * - *

This must be specified for RSA keys which are used for signing/verification. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - *

See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants. - */ - @NonNull - public Builder setSignaturePaddings( - @KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) { - mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings); - return this; - } - - - /** - * Sets the set of digest algorithms (e.g., {@code SHA-256}, {@code SHA-384}) with which the - * key can be used when signing/verifying or generating MACs. Attempts to use the key with - * any other digest algorithm will be rejected. - * - *

For HMAC keys, the default is the digest algorithm specified in - * {@link Key#getAlgorithm()}. For asymmetric signing keys the set of digest algorithms - * must be specified. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - * @see KeyStoreKeyProperties.Digest - */ - @NonNull - public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) { - mDigests = ArrayUtils.cloneIfNotEmpty(digests); - return this; - } - - /** - * Sets the set of block modes (e.g., {@code CBC}, {@code CTR}, {@code ECB}) with which the - * key can be used when encrypting/decrypting. Attempts to use the key with any other block - * modes will be rejected. - * - *

This must be specified for encryption/decryption keys. - * - *

NOTE: This has currently no effect on asymmetric key pairs. - * - *

See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants. - */ - @NonNull - public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) { - mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes); - return this; - } - - /** - * Sets whether encryption using this key must be sufficiently randomized to produce - * different ciphertexts for the same plaintext every time. The formal cryptographic - * property being required is indistinguishability under chosen-plaintext attack - * ({@code IND-CPA}). This property is important because it mitigates several classes - * of weaknesses due to which ciphertext may leak information about plaintext. For example, - * if a given plaintext always produces the same ciphertext, an attacker may see the - * repeated ciphertexts and be able to deduce something about the plaintext. - * - *

By default, {@code IND-CPA} is required. - * - *

When {@code IND-CPA} is required: - *