Loading keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -239,6 +239,13 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { "At least one digest algorithm must be specified"); "At least one digest algorithm must be specified"); } } } } // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen // not set up). KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); } catch (IllegalStateException | IllegalArgumentException e) { } catch (IllegalStateException | IllegalArgumentException e) { throw new InvalidAlgorithmParameterException(e); throw new InvalidAlgorithmParameterException(e); } } Loading keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -310,7 +310,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } else { } else { mKeymasterDigests = EmptyArray.INT; mKeymasterDigests = EmptyArray.INT; } } } catch (IllegalArgumentException e) { // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen // not set up). KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec.isUserAuthenticationRequired(), mSpec.getUserAuthenticationValidityDurationSeconds()); } catch (IllegalArgumentException | IllegalStateException e) { throw new InvalidAlgorithmParameterException(e); throw new InvalidAlgorithmParameterException(e); } } Loading keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +86 −88 Original line number Original line Diff line number Diff line Loading @@ -484,8 +484,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { spec.getKeyValidityForOriginationEnd()); spec.getKeyValidityForOriginationEnd()); importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, spec.getKeyValidityForConsumptionEnd()); spec.getKeyValidityForConsumptionEnd()); } catch (IllegalArgumentException e) { } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException("Invalid parameter", e); throw new KeyStoreException(e); } } } } Loading Loading @@ -598,21 +598,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { + " RAW format export"); + " RAW format export"); } } String keyAlgorithmString = key.getAlgorithm(); int keymasterAlgorithm; int keymasterDigest; try { keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(keyAlgorithmString); keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString); } catch (IllegalArgumentException e) { throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString); } KeymasterArguments args = new KeymasterArguments(); KeymasterArguments args = new KeymasterArguments(); try { int keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(key.getAlgorithm()); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); int[] keymasterDigests; int[] keymasterDigests; int keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (params.isDigestsSpecified()) { if (params.isDigestsSpecified()) { // Digest(s) specified in parameters // Digest(s) specified in parameters keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); Loading @@ -620,9 +613,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { // Digest also specified in the JCA key algorithm name. // Digest also specified in the JCA key algorithm name. if (!com.android.internal.util.ArrayUtils.contains( if (!com.android.internal.util.ArrayUtils.contains( keymasterDigests, keymasterDigest)) { keymasterDigests, keymasterDigest)) { throw new KeyStoreException("Key digest mismatch" throw new KeyStoreException("Digest specified in key algorithm " + ". Key: " + keyAlgorithmString + key.getAlgorithm() + " not specified in protection parameters: " + ", parameter spec: " + Arrays.asList(params.getDigests())); + Arrays.asList(params.getDigests())); } } // When the key is read back from keystore we reconstruct the JCA key algorithm // When the key is read back from keystore we reconstruct the JCA key algorithm // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to Loading Loading @@ -653,7 +646,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterDigests.length == 0) { if (keymasterDigests.length == 0) { throw new KeyStoreException("At least one digest algorithm must be specified" throw new KeyStoreException("At least one digest algorithm must be specified" + " for key algorithm " + keyAlgorithmString); + " for key algorithm " + key.getAlgorithm()); } } } } Loading @@ -666,14 +659,15 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto( if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto( keymasterBlockMode)) { keymasterBlockMode)) { throw new KeyStoreException( throw new KeyStoreException( "Randomized encryption (IND-CPA) required but may be violated by block" "Randomized encryption (IND-CPA) required but may be violated by" + " mode: " + " block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See KeyProtection documentation."); + ". See KeyProtection documentation."); } } } } } } args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes)); args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes)); args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes); args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes); if (params.getSignaturePaddings().length > 0) { if (params.getSignaturePaddings().length > 0) { throw new KeyStoreException("Signature paddings not supported for symmetric keys"); throw new KeyStoreException("Signature paddings not supported for symmetric keys"); Loading @@ -684,7 +678,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(args, KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); params.getUserAuthenticationValidityDurationSeconds()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, params.getKeyValidityForOriginationEnd()); params.getKeyValidityForOriginationEnd()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, Loading @@ -695,6 +690,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { // Permit caller-provided IV when encrypting with this key // Permit caller-provided IV when encrypting with this key args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); } } } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException(e); } Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias); Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias); String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias; String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias; Loading keystore/java/android/security/keystore/KeymasterUtils.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ public abstract class KeymasterUtils { * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user * authentication is valid as authorization for using the key or {@code -1} if every * authentication is valid as authorization for using the key or {@code -1} if every * use of the key needs authorization. * use of the key needs authorization. * * @throws IllegalStateException if user authentication is required but the system is in a wrong * state (e.g., secure lock screen not set up) for generating or importing keys that * require user authentication. */ */ public static void addUserAuthArgs(KeymasterArguments args, public static void addUserAuthArgs(KeymasterArguments args, boolean userAuthenticationRequired, boolean userAuthenticationRequired, Loading Loading
keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +7 −0 Original line number Original line Diff line number Diff line Loading @@ -239,6 +239,13 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { "At least one digest algorithm must be specified"); "At least one digest algorithm must be specified"); } } } } // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen // not set up). KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec.isUserAuthenticationRequired(), spec.getUserAuthenticationValidityDurationSeconds()); } catch (IllegalStateException | IllegalArgumentException e) { } catch (IllegalStateException | IllegalArgumentException e) { throw new InvalidAlgorithmParameterException(e); throw new InvalidAlgorithmParameterException(e); } } Loading
keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +8 −1 Original line number Original line Diff line number Diff line Loading @@ -310,7 +310,14 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } else { } else { mKeymasterDigests = EmptyArray.INT; mKeymasterDigests = EmptyArray.INT; } } } catch (IllegalArgumentException e) { // Check that user authentication related parameters are acceptable. This method // will throw an IllegalStateException if there are issues (e.g., secure lock screen // not set up). KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec.isUserAuthenticationRequired(), mSpec.getUserAuthenticationValidityDurationSeconds()); } catch (IllegalArgumentException | IllegalStateException e) { throw new InvalidAlgorithmParameterException(e); throw new InvalidAlgorithmParameterException(e); } } Loading
keystore/java/android/security/keystore/AndroidKeyStoreSpi.java +86 −88 Original line number Original line Diff line number Diff line Loading @@ -484,8 +484,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { spec.getKeyValidityForOriginationEnd()); spec.getKeyValidityForOriginationEnd()); importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, spec.getKeyValidityForConsumptionEnd()); spec.getKeyValidityForConsumptionEnd()); } catch (IllegalArgumentException e) { } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException("Invalid parameter", e); throw new KeyStoreException(e); } } } } Loading Loading @@ -598,21 +598,14 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { + " RAW format export"); + " RAW format export"); } } String keyAlgorithmString = key.getAlgorithm(); int keymasterAlgorithm; int keymasterDigest; try { keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(keyAlgorithmString); keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString); } catch (IllegalArgumentException e) { throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString); } KeymasterArguments args = new KeymasterArguments(); KeymasterArguments args = new KeymasterArguments(); try { int keymasterAlgorithm = KeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(key.getAlgorithm()); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, keymasterAlgorithm); int[] keymasterDigests; int[] keymasterDigests; int keymasterDigest = KeyProperties.KeyAlgorithm.toKeymasterDigest(key.getAlgorithm()); if (params.isDigestsSpecified()) { if (params.isDigestsSpecified()) { // Digest(s) specified in parameters // Digest(s) specified in parameters keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); keymasterDigests = KeyProperties.Digest.allToKeymaster(params.getDigests()); Loading @@ -620,9 +613,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { // Digest also specified in the JCA key algorithm name. // Digest also specified in the JCA key algorithm name. if (!com.android.internal.util.ArrayUtils.contains( if (!com.android.internal.util.ArrayUtils.contains( keymasterDigests, keymasterDigest)) { keymasterDigests, keymasterDigest)) { throw new KeyStoreException("Key digest mismatch" throw new KeyStoreException("Digest specified in key algorithm " + ". Key: " + keyAlgorithmString + key.getAlgorithm() + " not specified in protection parameters: " + ", parameter spec: " + Arrays.asList(params.getDigests())); + Arrays.asList(params.getDigests())); } } // When the key is read back from keystore we reconstruct the JCA key algorithm // When the key is read back from keystore we reconstruct the JCA key algorithm // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to // name from the KM_TAG_ALGORITHM and the first KM_TAG_DIGEST. Thus we need to Loading Loading @@ -653,7 +646,7 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterAlgorithm == KeymasterDefs.KM_ALGORITHM_HMAC) { if (keymasterDigests.length == 0) { if (keymasterDigests.length == 0) { throw new KeyStoreException("At least one digest algorithm must be specified" throw new KeyStoreException("At least one digest algorithm must be specified" + " for key algorithm " + keyAlgorithmString); + " for key algorithm " + key.getAlgorithm()); } } } } Loading @@ -666,14 +659,15 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto( if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatibleWithSymmetricCrypto( keymasterBlockMode)) { keymasterBlockMode)) { throw new KeyStoreException( throw new KeyStoreException( "Randomized encryption (IND-CPA) required but may be violated by block" "Randomized encryption (IND-CPA) required but may be violated by" + " mode: " + " block mode: " + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + KeyProperties.BlockMode.fromKeymaster(keymasterBlockMode) + ". See KeyProtection documentation."); + ". See KeyProtection documentation."); } } } } } } args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes)); args.addEnums(KeymasterDefs.KM_TAG_PURPOSE, KeyProperties.Purpose.allToKeymaster(purposes)); args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes); args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockModes); if (params.getSignaturePaddings().length > 0) { if (params.getSignaturePaddings().length > 0) { throw new KeyStoreException("Signature paddings not supported for symmetric keys"); throw new KeyStoreException("Signature paddings not supported for symmetric keys"); Loading @@ -684,7 +678,8 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { KeymasterUtils.addUserAuthArgs(args, KeymasterUtils.addUserAuthArgs(args, params.isUserAuthenticationRequired(), params.isUserAuthenticationRequired(), params.getUserAuthenticationValidityDurationSeconds()); params.getUserAuthenticationValidityDurationSeconds()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, params.getKeyValidityStart()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, params.getKeyValidityForOriginationEnd()); params.getKeyValidityForOriginationEnd()); args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, args.addDateIfNotNull(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, Loading @@ -695,6 +690,9 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { // Permit caller-provided IV when encrypting with this key // Permit caller-provided IV when encrypting with this key args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE); } } } catch (IllegalArgumentException | IllegalStateException e) { throw new KeyStoreException(e); } Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias); Credentials.deleteAllTypesForAlias(mKeyStore, entryAlias); String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias; String keyAliasInKeystore = Credentials.USER_SECRET_KEY + entryAlias; Loading
keystore/java/android/security/keystore/KeymasterUtils.java +4 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,10 @@ public abstract class KeymasterUtils { * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user * @param userAuthenticationValidityDurationSeconds duration of time (seconds) for which user * authentication is valid as authorization for using the key or {@code -1} if every * authentication is valid as authorization for using the key or {@code -1} if every * use of the key needs authorization. * use of the key needs authorization. * * @throws IllegalStateException if user authentication is required but the system is in a wrong * state (e.g., secure lock screen not set up) for generating or importing keys that * require user authentication. */ */ public static void addUserAuthArgs(KeymasterArguments args, public static void addUserAuthArgs(KeymasterArguments args, boolean userAuthenticationRequired, boolean userAuthenticationRequired, Loading