summaryrefslogtreecommitdiff
path: root/keystore/java/android/security/AndroidKeyStore.java
diff options
context:
space:
mode:
authorAlex Klyubin <klyubin@google.com>2015-04-06 15:36:25 -0700
committerAlex Klyubin <klyubin@google.com>2015-04-07 09:18:00 -0700
commitc46e9e7da4558f6bc99262361fd1ca35c3a44090 (patch)
treefe03eacff018dff328a9e954d307bf4734de0fa0 /keystore/java/android/security/AndroidKeyStore.java
parent64b0062a373102f83837faade20b469685758139 (diff)
Make the new AndroidKeyStore API conformant.
This makes the new AndroidKeyStore API conform with the latest Keymaster API changes as well as the latest Android framework API design guidelines. Keymaster changes: * Multiple paddings, block modes, and digests can be set on a key. * "max uses per boot" and "min seconds between use" restrictions will not be exposed in the framework API. * Padding scheme ZERO will not be exposed. Changes due to Android framework design guidelines: * Sets of enum values have been replaced with bitsets represented as ints. * Integer has been replaced with int, with null being represented with a special value (e.g., -1 or 0) where possible. Bug: 18088752 Change-Id: Ib21739aa9b42d48895cb7a681e836a5c6d972ac6
Diffstat (limited to 'keystore/java/android/security/AndroidKeyStore.java')
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java81
1 files changed, 36 insertions, 45 deletions
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index dcc79be5eaa9..f72c7acd182b 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -466,81 +466,72 @@ public class AndroidKeyStore extends KeyStoreSpi {
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
}
- if ((params.getAlgorithm() != null) && (params.getAlgorithm() != keyAlgorithm)) {
- throw new KeyStoreException("Key algorithm mismatch. Key: " + keyAlgorithmString
- + ", parameter spec: "
- + KeyStoreKeyConstraints.Algorithm.toString(params.getAlgorithm()));
- }
-
KeymasterArguments args = new KeymasterArguments();
args.addInt(KeymasterDefs.KM_TAG_ALGORITHM,
KeyStoreKeyConstraints.Algorithm.toKeymaster(keyAlgorithm));
- if (digest != null) {
- // Digest available from JCA key algorithm
- if (params.getDigest() != null) {
- // Digest also specified in parameters -- check that these two match
- if (digest != params.getDigest()) {
- throw new KeyStoreException("Key digest mismatch. Key: " + keyAlgorithmString
+ @KeyStoreKeyConstraints.DigestEnum int digests;
+ if (params.isDigestsSpecified()) {
+ // Digest(s) specified in parameters
+ if (digest != null) {
+ // Digest also specified in the JCA key algorithm name.
+ if ((params.getDigests() & digest) != digest) {
+ throw new KeyStoreException("Key digest mismatch"
+ + ". Key: " + keyAlgorithmString
+ ", parameter spec: "
- + KeyStoreKeyConstraints.Digest.toString(params.getDigest()));
+ + KeyStoreKeyConstraints.Digest.allToString(params.getDigests()));
}
}
+ digests = params.getDigests();
} else {
- // Digest not available from JCA key algorithm
- digest = params.getDigest();
+ // No digest specified in parameters
+ if (digest != null) {
+ // Digest specified in the JCA key algorithm name.
+ digests = digest;
+ } else {
+ digests = 0;
+ }
}
- if (digest != null) {
- args.addInt(KeymasterDefs.KM_TAG_DIGEST,
- KeyStoreKeyConstraints.Digest.toKeymaster(digest));
+ for (int keymasterDigest : KeyStoreKeyConstraints.Digest.allToKeymaster(digests)) {
+ args.addInt(KeymasterDefs.KM_TAG_DIGEST, keymasterDigest);
+ }
+ if (digests != 0) {
+ // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
+ // This code will blow up if mode than one digest is specified.
Integer digestOutputSizeBytes =
KeyStoreKeyConstraints.Digest.getOutputSizeBytes(digest);
if (digestOutputSizeBytes != null) {
- // TODO: Remove MAC length constraint once Keymaster API no longer requires it.
// TODO: Switch to bits instead of bytes, once this is fixed in Keymaster
args.addInt(KeymasterDefs.KM_TAG_MAC_LENGTH, digestOutputSizeBytes);
}
}
if (keyAlgorithm == KeyStoreKeyConstraints.Algorithm.HMAC) {
- if (digest == null) {
- throw new IllegalStateException("Digest algorithm must be specified for key"
- + " algorithm " + keyAlgorithmString);
+ if (digests == 0) {
+ throw new KeyStoreException("At least one digest algorithm must be specified"
+ + " for key algorithm " + keyAlgorithmString);
}
}
- @KeyStoreKeyConstraints.PurposeEnum int purposes = (params.getPurposes() != null)
- ? params.getPurposes()
- : (KeyStoreKeyConstraints.Purpose.ENCRYPT
- | KeyStoreKeyConstraints.Purpose.DECRYPT
- | KeyStoreKeyConstraints.Purpose.SIGN
- | KeyStoreKeyConstraints.Purpose.VERIFY);
- for (int keymasterPurpose :
- KeyStoreKeyConstraints.Purpose.allToKeymaster(purposes)) {
+ int purposes = params.getPurposes();
+ for (int keymasterPurpose : KeyStoreKeyConstraints.Purpose.allToKeymaster(purposes)) {
args.addInt(KeymasterDefs.KM_TAG_PURPOSE, keymasterPurpose);
}
- if (params.getBlockMode() != null) {
- args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE,
- KeyStoreKeyConstraints.BlockMode.toKeymaster(params.getBlockMode()));
- }
- if (params.getPadding() != null) {
- args.addInt(KeymasterDefs.KM_TAG_PADDING,
- KeyStoreKeyConstraints.Padding.toKeymaster(params.getPadding()));
- }
- if (params.getMaxUsesPerBoot() != null) {
- args.addInt(KeymasterDefs.KM_TAG_MAX_USES_PER_BOOT, params.getMaxUsesPerBoot());
+ for (int keymasterBlockMode :
+ KeyStoreKeyConstraints.BlockMode.allToKeymaster(params.getBlockModes())) {
+ args.addInt(KeymasterDefs.KM_TAG_BLOCK_MODE, keymasterBlockMode);
}
- if (params.getMinSecondsBetweenOperations() != null) {
- args.addInt(KeymasterDefs.KM_TAG_MIN_SECONDS_BETWEEN_OPS,
- params.getMinSecondsBetweenOperations());
+ for (int keymasterPadding :
+ KeyStoreKeyConstraints.Padding.allToKeymaster(params.getPaddings())) {
+ args.addInt(KeymasterDefs.KM_TAG_PADDING, keymasterPadding);
}
- if (params.getUserAuthenticators().isEmpty()) {
+ if (params.getUserAuthenticators() == 0) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
} else {
args.addInt(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeyStoreKeyConstraints.UserAuthenticator.allToKeymaster(
params.getUserAuthenticators()));
}
- if (params.getUserAuthenticationValidityDurationSeconds() != null) {
+ if (params.getUserAuthenticationValidityDurationSeconds() != -1) {
args.addInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
params.getUserAuthenticationValidityDurationSeconds());
}