summaryrefslogtreecommitdiffstats
path: root/keystore/java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore/java')
-rw-r--r--keystore/java/android/security/AndroidKeyPairGenerator.java21
-rw-r--r--keystore/java/android/security/AndroidKeyStore.java12
-rw-r--r--keystore/java/android/security/EcIesParameterSpec.java74
-rw-r--r--keystore/java/android/security/KeyChain.java42
-rw-r--r--keystore/java/android/security/KeyChainAliasCallback.java4
-rw-r--r--keystore/java/android/security/KeyGeneratorSpec.java72
-rw-r--r--keystore/java/android/security/KeyPairGeneratorSpec.java166
-rw-r--r--keystore/java/android/security/KeyStore.java6
-rw-r--r--keystore/java/android/security/KeyStoreCipherSpi.java2
-rw-r--r--keystore/java/android/security/KeyStoreKeyGeneratorSpi.java8
-rw-r--r--keystore/java/android/security/KeyStoreKeyProperties.java553
-rw-r--r--keystore/java/android/security/KeyStoreKeySpec.java40
-rw-r--r--keystore/java/android/security/KeyStoreParameter.java134
13 files changed, 649 insertions, 485 deletions
diff --git a/keystore/java/android/security/AndroidKeyPairGenerator.java b/keystore/java/android/security/AndroidKeyPairGenerator.java
index 3f29c6a..ea90ca3 100644
--- a/keystore/java/android/security/AndroidKeyPairGenerator.java
+++ b/keystore/java/android/security/AndroidKeyPairGenerator.java
@@ -54,13 +54,13 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
public static class RSA extends AndroidKeyPairGenerator {
public RSA() {
- super(KeyStoreKeyProperties.Algorithm.RSA);
+ super(KeyStoreKeyProperties.KEY_ALGORITHM_RSA);
}
}
public static class EC extends AndroidKeyPairGenerator {
public EC() {
- super(KeyStoreKeyProperties.Algorithm.EC);
+ super(KeyStoreKeyProperties.KEY_ALGORITHM_EC);
}
}
@@ -83,15 +83,15 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
private android.security.KeyStore mKeyStore;
private KeyPairGeneratorSpec mSpec;
- private @KeyStoreKeyProperties.AlgorithmEnum String mKeyAlgorithm;
+ private @KeyStoreKeyProperties.KeyAlgorithmEnum String mKeyAlgorithm;
private int mKeyType;
private int mKeySize;
- protected AndroidKeyPairGenerator(@KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ protected AndroidKeyPairGenerator(@KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) {
mAlgorithm = algorithm;
}
- public @KeyStoreKeyProperties.AlgorithmEnum String getAlgorithm() {
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String getAlgorithm() {
return mAlgorithm;
}
@@ -197,7 +197,8 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
return certGen.generate(privateKey);
}
- private @KeyStoreKeyProperties.AlgorithmEnum String getKeyAlgorithm(KeyPairGeneratorSpec spec) {
+ private @KeyStoreKeyProperties.KeyAlgorithmEnum String getKeyAlgorithm(
+ KeyPairGeneratorSpec spec) {
String result = spec.getKeyType();
if (result != null) {
return result;
@@ -249,10 +250,10 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
}
private static String getDefaultSignatureAlgorithmForKeyAlgorithm(
- @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
- if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(algorithm)) {
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) {
+ if (KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(algorithm)) {
return "sha256WithRSA";
- } else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(algorithm)) {
+ } else if (KeyStoreKeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(algorithm)) {
return "sha256WithECDSA";
} else {
throw new IllegalArgumentException("Unsupported key type " + algorithm);
@@ -288,7 +289,7 @@ public abstract class AndroidKeyPairGenerator extends KeyPairGeneratorSpi {
}
KeyPairGeneratorSpec spec = (KeyPairGeneratorSpec) params;
- @KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithm = getKeyAlgorithm(spec);
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithm = getKeyAlgorithm(spec);
int keyType = KeyStore.getKeyTypeForAlgorithm(keyAlgorithm);
if (keyType == -1) {
throw new InvalidAlgorithmParameterException(
diff --git a/keystore/java/android/security/AndroidKeyStore.java b/keystore/java/android/security/AndroidKeyStore.java
index 69d80e6..7ac236a 100644
--- a/keystore/java/android/security/AndroidKeyStore.java
+++ b/keystore/java/android/security/AndroidKeyStore.java
@@ -129,10 +129,10 @@ public class AndroidKeyStore extends KeyStoreSpi {
keymasterDigest = keymasterDigests.get(0);
}
- @KeyStoreKeyProperties.AlgorithmEnum String keyAlgorithmString;
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithmString;
try {
keyAlgorithmString =
- KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
+ KeyStoreKeyProperties.KeyAlgorithm.fromKeymasterSecretKeyAlgorithm(
keymasterAlgorithm, keymasterDigest);
} catch (IllegalArgumentException e) {
throw (UnrecoverableKeyException)
@@ -453,10 +453,10 @@ public class AndroidKeyStore extends KeyStoreSpi {
int keymasterAlgorithm;
int keymasterDigest;
try {
- keymasterAlgorithm = KeyStoreKeyProperties.Algorithm.toKeymasterSecretKeyAlgorithm(
+ keymasterAlgorithm = KeyStoreKeyProperties.KeyAlgorithm.toKeymasterSecretKeyAlgorithm(
keyAlgorithmString);
keymasterDigest =
- KeyStoreKeyProperties.Algorithm.toKeymasterDigest(keyAlgorithmString);
+ KeyStoreKeyProperties.KeyAlgorithm.toKeymasterDigest(keyAlgorithmString);
} catch (IllegalArgumentException e) {
throw new KeyStoreException("Unsupported secret key algorithm: " + keyAlgorithmString);
}
@@ -497,7 +497,7 @@ public class AndroidKeyStore extends KeyStoreSpi {
@KeyStoreKeyProperties.PurposeEnum int purposes = params.getPurposes();
int[] keymasterBlockModes =
KeyStoreKeyProperties.BlockMode.allToKeymaster(params.getBlockModes());
- if (((purposes & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ if (((purposes & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0)
&& (params.isRandomizedEncryptionRequired())) {
for (int keymasterBlockMode : keymasterBlockModes) {
if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(keymasterBlockMode)) {
@@ -536,7 +536,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 & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!params.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
diff --git a/keystore/java/android/security/EcIesParameterSpec.java b/keystore/java/android/security/EcIesParameterSpec.java
index a3e5aec..1cd8784 100644
--- a/keystore/java/android/security/EcIesParameterSpec.java
+++ b/keystore/java/android/security/EcIesParameterSpec.java
@@ -1,6 +1,8 @@
package android.security;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -49,45 +51,44 @@ import javax.crypto.Mac;
*/
public class EcIesParameterSpec implements AlgorithmParameterSpec {
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
- @IntDef(value = {PointFormat.UNCOMPRESSED, PointFormat.COMPRESSED})
+ @IntDef({
+ POINT_FORMAT_UNSPECIFIED,
+ POINT_FORMAT_UNCOMPRESSED,
+ POINT_FORMAT_COMPRESSED,
+ })
public @interface PointFormatEnum {}
+ /** Unspecified EC point format. */
+ public static final int POINT_FORMAT_UNSPECIFIED = -1;
+
/**
- * Wire format of the EC point.
+ * Uncompressed EC point format: both coordinates are stored separately.
+ *
+ * <p>The wire format is byte {@code 0x04} followed by binary representation of the {@code x}
+ * coordinate followed by binary representation of the {@code y} coordinate. See
+ * {@code ISO 18033-2} section {@code 5.4.3}.
*/
- public static abstract class PointFormat {
-
- private PointFormat() {}
+ public static final int POINT_FORMAT_UNCOMPRESSED = 0;
- /** Unspecified point format. */
- public static final int UNSPECIFIED = -1;
-
- /**
- * Uncompressed point format: both coordinates are stored separately.
- *
- * <p>The wire format is byte {@code 0x04} followed by binary representation of the
- * {@code x} coordinate followed by binary representation of the {@code y} coordinate. See
- * {@code ISO 18033-2} section {@code 5.4.3}.
- */
- public static final int UNCOMPRESSED = 0;
-
- /**
- * Compressed point format: only one coordinate is stored.
- *
- * <p>The wire format is byte {@code 0x02} or {@code 0x03} (depending on the value of the
- * stored coordinate) followed by the binary representation of the {@code x} coordinate.
- * See {@code ISO 18033-2} section {@code 5.4.3}.
- */
- public static final int COMPRESSED = 1;
- }
+ /**
+ * Compressed EC point format: only one coordinate is stored.
+ *
+ * <p>The wire format is byte {@code 0x02} or {@code 0x03} (depending on the value of the stored
+ * coordinate) followed by the binary representation of the {@code x} coordinate. See
+ * {@code ISO 18033-2} section {@code 5.4.3}.
+ */
+ public static final int POINT_FORMAT_COMPRESSED = 1;
/**
* Default parameter spec: compressed point format, {@code HKDFwithSHA256}, DEM uses 128-bit AES
* GCM.
*/
public static final EcIesParameterSpec DEFAULT = new EcIesParameterSpec(
- PointFormat.COMPRESSED,
+ POINT_FORMAT_COMPRESSED,
"HKDFwithSHA256",
"AES/GCM/NoPadding",
128,
@@ -117,7 +118,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
}
/**
- * Returns KEM EC point wire format or {@link PointFormat#UNSPECIFIED} if not specified.
+ * Returns KEM EC point wire format or {@link #POINT_FORMAT_UNSPECIFIED} if not specified.
*/
public @PointFormatEnum int getKemPointFormat() {
return mKemPointFormat;
@@ -127,6 +128,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* Returns KEM KDF algorithm (e.g., {@code HKDFwithSHA256} or {@code KDF1withSHA1}) or
* {@code null} if not specified.
*/
+ @Nullable
public String getKemKdfAlgorithm() {
return mKemKdfAlgorithm;
}
@@ -138,6 +140,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* @see Cipher#getInstance(String)
* @see #getDemCipherKeySize()
*/
+ @Nullable
public String getDemCipherTransformation() {
return mDemCipherTransformation;
}
@@ -158,6 +161,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* @see Mac#getInstance(String)
* @see #getDemMacKeySize()
*/
+ @Nullable
public String getDemMacAlgorithm() {
return mDemMacAlgorithm;
}
@@ -175,7 +179,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* Builder of {@link EcIesParameterSpec}.
*/
public static class Builder {
- private @PointFormatEnum int mKemPointFormat = PointFormat.UNSPECIFIED;
+ private @PointFormatEnum int mKemPointFormat = POINT_FORMAT_UNSPECIFIED;
private String mKemKdfAlgorithm;
private String mDemCipherTransformation;
private int mDemCipherKeySize = 128;
@@ -194,7 +198,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
* Sets KEM KDF algorithm. For example, {@code HKDFwithSHA256}, {@code KDF2withSHA256}, or
* {@code KDF1withSHA1}.
*/
- public Builder setKemKdfAlgorithm(String algorithm) {
+ @NonNull
+ public Builder setKemKdfAlgorithm(@Nullable String algorithm) {
mKemKdfAlgorithm = algorithm;
return this;
}
@@ -205,7 +210,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
*
* @see Cipher#getInstance(String)
*/
- public Builder setDemCipherTransformation(String transformation) {
+ @NonNull
+ public Builder setDemCipherTransformation(@Nullable String transformation) {
mDemCipherTransformation = transformation;
return this;
}
@@ -217,6 +223,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
*
* @see #setDemCipherTransformation(String)
*/
+ @NonNull
public Builder setDemCipherKeySize(int sizeBits) {
mDemCipherKeySize = sizeBits;
return this;
@@ -227,7 +234,8 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
*
* @see Mac#getInstance(String)
*/
- public Builder setDemMacAlgorithm(String algorithm) {
+ @NonNull
+ public Builder setDemMacAlgorithm(@Nullable String algorithm) {
mDemMacAlgorithm = algorithm;
return this;
}
@@ -239,6 +247,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
*
* @see #setDemCipherKeySize(int)
*/
+ @NonNull
public Builder setDemMacKeySize(int sizeBits) {
mDemMacKeySize = sizeBits;
return this;
@@ -247,6 +256,7 @@ public class EcIesParameterSpec implements AlgorithmParameterSpec {
/**
* Returns a new {@link EcIesParameterSpec} based on the current state of this builder.
*/
+ @NonNull
public EcIesParameterSpec build() {
int demMacKeySize = (mDemMacKeySize != -1) ? mDemMacKeySize : mDemCipherKeySize;
return new EcIesParameterSpec(
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index 8e27dc3..3853eca 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -15,6 +15,8 @@
*/
package android.security;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
@@ -217,6 +219,7 @@ public final class KeyChain {
* successfully installed, otherwise {@link
* Activity#RESULT_CANCELED} will be returned.
*/
+ @NonNull
public static Intent createInstallIntent() {
Intent intent = new Intent(ACTION_INSTALL);
intent.setClassName(CERT_INSTALLER_PACKAGE,
@@ -261,9 +264,10 @@ public final class KeyChain {
* @param alias The alias to preselect if available, or null if
* unavailable.
*/
- public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
- @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
- String host, int port, String alias) {
+ public static void choosePrivateKeyAlias(@NonNull Activity activity,
+ @NonNull KeyChainAliasCallback response,
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String[] keyTypes, Principal[] issuers,
+ @Nullable String host, int port, @Nullable String alias) {
choosePrivateKeyAlias(activity, response, keyTypes, issuers, host, port, null, alias);
}
@@ -306,9 +310,10 @@ public final class KeyChain {
* @param alias The alias to preselect if available, or null if
* unavailable.
*/
- public static void choosePrivateKeyAlias(Activity activity, KeyChainAliasCallback response,
- @KeyStoreKeyProperties.AlgorithmEnum String[] keyTypes, Principal[] issuers,
- String host, int port, String url, String alias) {
+ public static void choosePrivateKeyAlias(@NonNull Activity activity,
+ @NonNull KeyChainAliasCallback response,
+ @KeyStoreKeyProperties.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
* to follow the semantics and purpose of X509KeyManager
@@ -361,7 +366,8 @@ public final class KeyChain {
* returned via {@link KeyChainAliasCallback#alias}.
* @throws KeyChainException if the alias was valid but there was some problem accessing it.
*/
- public static PrivateKey getPrivateKey(Context context, String alias)
+ @Nullable
+ public static PrivateKey getPrivateKey(@NonNull Context context, @NonNull String alias)
throws KeyChainException, InterruptedException {
if (alias == null) {
throw new NullPointerException("alias == null");
@@ -396,8 +402,9 @@ public final class KeyChain {
* returned via {@link KeyChainAliasCallback#alias}.
* @throws KeyChainException if the alias was valid but there was some problem accessing it.
*/
- public static X509Certificate[] getCertificateChain(Context context, String alias)
- throws KeyChainException, InterruptedException {
+ @Nullable
+ public static X509Certificate[] getCertificateChain(@NonNull Context context,
+ @NonNull String alias) throws KeyChainException, InterruptedException {
if (alias == null) {
throw new NullPointerException("alias == null");
}
@@ -432,10 +439,10 @@ public final class KeyChain {
* "RSA").
*/
public static boolean isKeyAlgorithmSupported(
- @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ @NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) {
final String algUpper = algorithm.toUpperCase(Locale.US);
- return KeyStoreKeyProperties.Algorithm.EC.equals(algUpper)
- || KeyStoreKeyProperties.Algorithm.RSA.equals(algUpper);
+ return KeyStoreKeyProperties.KEY_ALGORITHM_EC.equals(algUpper)
+ || KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equals(algUpper);
}
/**
@@ -446,7 +453,7 @@ public final class KeyChain {
* that makes it non-exportable.
*/
public static boolean isBoundKeyAlgorithm(
- @KeyStoreKeyProperties.AlgorithmEnum String algorithm) {
+ @NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String algorithm) {
if (!isKeyAlgorithmSupported(algorithm)) {
return false;
}
@@ -455,7 +462,8 @@ public final class KeyChain {
}
/** @hide */
- public static X509Certificate toCertificate(byte[] bytes) {
+ @NonNull
+ public static X509Certificate toCertificate(@NonNull byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("bytes == null");
}
@@ -496,14 +504,14 @@ public final class KeyChain {
*
* Caller should call unbindService on the result when finished.
*/
- public static KeyChainConnection bind(Context context) throws InterruptedException {
+ public static KeyChainConnection bind(@NonNull Context context) throws InterruptedException {
return bindAsUser(context, Process.myUserHandle());
}
/**
* @hide
*/
- public static KeyChainConnection bindAsUser(Context context, UserHandle user)
+ public static KeyChainConnection bindAsUser(@NonNull Context context, UserHandle user)
throws InterruptedException {
if (context == null) {
throw new NullPointerException("context == null");
@@ -537,7 +545,7 @@ public final class KeyChain {
return new KeyChainConnection(context, keyChainServiceConnection, q.take());
}
- private static void ensureNotOnMainThread(Context context) {
+ private static void ensureNotOnMainThread(@NonNull Context context) {
Looper looper = Looper.myLooper();
if (looper != null && looper == context.getMainLooper()) {
throw new IllegalStateException(
diff --git a/keystore/java/android/security/KeyChainAliasCallback.java b/keystore/java/android/security/KeyChainAliasCallback.java
index 2500863..8e41377 100644
--- a/keystore/java/android/security/KeyChainAliasCallback.java
+++ b/keystore/java/android/security/KeyChainAliasCallback.java
@@ -15,6 +15,8 @@
*/
package android.security;
+import android.annotation.Nullable;
+
/**
* The KeyChainAliasCallback is the callback for {@link
* KeyChain#choosePrivateKeyAlias}.
@@ -25,5 +27,5 @@ public interface KeyChainAliasCallback {
* Called with the alias of the certificate chosen by the user, or
* null if no value was chosen.
*/
- public void alias(String alias);
+ public void alias(@Nullable String alias);
}
diff --git a/keystore/java/android/security/KeyGeneratorSpec.java b/keystore/java/android/security/KeyGeneratorSpec.java
index 97e3a67..e63566b 100644
--- a/keystore/java/android/security/KeyGeneratorSpec.java
+++ b/keystore/java/android/security/KeyGeneratorSpec.java
@@ -16,6 +16,9 @@
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.text.TextUtils;
@@ -53,13 +56,13 @@ import javax.crypto.KeyGenerator;
* been authenticated within the last five minutes.
* <pre> {@code
* KeyGenerator keyGenerator = KeyGenerator.getInstance(
- * KeyStoreKeyProperties.Algorithm.HMAC_SHA256,
+ * KeyStoreKeyProperties.KEY_ALGORITHM_HMAC_SHA256,
* "AndroidKeyStore");
* keyGenerator.initialize(
* new KeyGeneratorSpec.Builder(context)
* .setAlias("key1")
- * .setPurposes(KeyStoreKeyProperties.Purpose.SIGN
- * | KeyStoreKeyProperties.Purpose.VERIFY)
+ * .setPurposes(KeyStoreKeyProperties.PURPOSE_SIGN
+ * | KeyStoreKeyProperties.PURPOSE_VERIFY)
* // Only permit this key to be used if the user authenticated
* // within the last five minutes.
* .setUserAuthenticationRequired(true)
@@ -163,6 +166,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityStart() {
return mKeyValidityStart;
}
@@ -172,6 +176,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
}
@@ -181,27 +186,41 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
}
/**
- * Gets the set of purposes for which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
+ * Gets the set of padding schemes (e.g., {@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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of block modes with which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
@@ -269,7 +288,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* {@code context} passed in may be used to pop up some UI to ask the user to unlock or
* initialize the Android KeyStore facility.
*/
- public Builder(Context context) {
+ public Builder(@NonNull Context context) {
if (context == null) {
throw new NullPointerException("context == null");
}
@@ -282,7 +301,8 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* <p>The alias must be provided. There is no default.
*/
- public Builder setAlias(String alias) {
+ @NonNull
+ public Builder setAlias(@NonNull String alias) {
if (alias == null) {
throw new NullPointerException("alias == null");
}
@@ -296,6 +316,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* <p>By default, the key size will be determines based on the key algorithm. For example,
* for {@code HmacSHA256}, the key size will default to {@code 256}.
*/
+ @NonNull
public Builder setKeySize(int keySize) {
mKeySize = keySize;
return this;
@@ -313,6 +334,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see KeyguardManager#isDeviceSecure()
*/
+ @NonNull
public Builder setEncryptionRequired() {
mFlags |= KeyStore.FLAG_ENCRYPTED;
return this;
@@ -325,6 +347,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see #setKeyValidityEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
return this;
@@ -339,6 +362,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
setKeyValidityForConsumptionEnd(endDate);
@@ -352,6 +376,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see #setKeyValidityForConsumptionEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
return this;
@@ -365,28 +390,36 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
return this;
}
/**
- * Sets the set of purposes for which the key can be used.
+ * 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.
*
* <p>This must be specified for all keys. There is no default.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
+ @NonNull
public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
+ * Sets the set of padding schemes (e.g., {@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.
*
* <p>This must be specified for keys which are used for encryption/decryption.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public Builder setEncryptionPaddings(
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -394,11 +427,15 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
+ * Sets 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.
*
* <p>This must be specified for encryption/decryption keys.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
@@ -436,6 +473,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
* ciphertext.</li>
* </ul>
*/
+ @NonNull
public Builder setRandomizedEncryptionRequired(boolean required) {
mRandomizedEncryptionRequired = required;
return this;
@@ -456,6 +494,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
*/
+ @NonNull
public Builder setUserAuthenticationRequired(boolean required) {
mUserAuthenticationRequired = required;
return this;
@@ -472,7 +511,9 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @see #setUserAuthenticationRequired(boolean)
*/
- public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
+ @NonNull
+ public Builder setUserAuthenticationValidityDurationSeconds(
+ @IntRange(from = -1) int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
@@ -482,6 +523,7 @@ public class KeyGeneratorSpec implements AlgorithmParameterSpec {
*
* @throws IllegalArgumentException if a required field is missing or violates a constraint.
*/
+ @NonNull
public KeyGeneratorSpec build() {
return new KeyGeneratorSpec(mContext,
mKeystoreAlias,
diff --git a/keystore/java/android/security/KeyPairGeneratorSpec.java b/keystore/java/android/security/KeyPairGeneratorSpec.java
index 7fd5cb5..b07c052 100644
--- a/keystore/java/android/security/KeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/KeyPairGeneratorSpec.java
@@ -17,6 +17,9 @@
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.text.TextUtils;
@@ -66,16 +69,16 @@ import javax.security.auth.x500.X500Principal;
* digest and only if the user has been authenticated within the last five minutes.
* <pre> {@code
* KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(
- * KeyStoreKeyProperties.Algorithm.EC,
+ * 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)
+ * .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)
@@ -284,9 +287,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Returns the key type (e.g., "EC", "RSA") specified by this parameter.
+ * Returns the type of key pair (e.g., {@code EC}, {@code RSA}) to be generated. See
+ * {@link KeyStoreKeyProperties}.{@code KEY_ALGORITHM} constants.
*/
- public @KeyStoreKeyProperties.AlgorithmEnum String getKeyType() {
+ @Nullable
+ public @KeyStoreKeyProperties.KeyAlgorithmEnum String getKeyType() {
return mKeyType;
}
@@ -303,6 +308,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Returns the {@link AlgorithmParameterSpec} that will be used for creation
* of the key pair.
*/
+ @NonNull
public AlgorithmParameterSpec getAlgorithmParameterSpec() {
return mSpec;
}
@@ -311,6 +317,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the subject distinguished name to be used on the X.509 certificate
* that will be put in the {@link java.security.KeyStore}.
*/
+ @NonNull
public X500Principal getSubjectDN() {
return mSubjectDN;
}
@@ -319,6 +326,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the serial number to be used on the X.509 certificate that will be
* put in the {@link java.security.KeyStore}.
*/
+ @NonNull
public BigInteger getSerialNumber() {
return mSerialNumber;
}
@@ -327,6 +335,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the start date to be used on the X.509 certificate that will be put
* in the {@link java.security.KeyStore}.
*/
+ @NonNull
public Date getStartDate() {
return mStartDate;
}
@@ -335,6 +344,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Gets the end date to be used on the X.509 certificate that will be put in
* the {@link java.security.KeyStore}.
*/
+ @NonNull
public Date getEndDate() {
return mEndDate;
}
@@ -359,6 +369,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityStart() {
return mKeyValidityStart;
}
@@ -369,6 +380,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
}
@@ -378,41 +390,64 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
}
/**
- * Gets the set of purposes for which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of digest algorithms with which the key can be used.
+ * 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 with which the key can be used when encrypting/decrypting.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of padding schemes with which the key can be used when signing/verifying.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
- * Gets the set of block modes with which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
@@ -528,7 +563,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* some UI to ask the user to unlock or initialize the Android KeyStore
* facility.
*/
- public Builder(Context context) {
+ public Builder(@NonNull Context context) {
if (context == null) {
throw new NullPointerException("context == null");
}
@@ -540,7 +575,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* {@link java.security.KeyStore} instance using the
* {@code AndroidKeyStore} provider.
*/
- public Builder setAlias(String alias) {
+ @NonNull
+ public Builder setAlias(@NonNull String alias) {
if (alias == null) {
throw new NullPointerException("alias == null");
}
@@ -549,9 +585,12 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the key type (e.g., EC, RSA) of the keypair to be created.
+ * 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.
+ *
*/
- public Builder setKeyType(@KeyStoreKeyProperties.AlgorithmEnum String keyType)
+ @NonNull
+ public Builder setKeyType(@NonNull @KeyStoreKeyProperties.KeyAlgorithmEnum String keyType)
throws NoSuchAlgorithmException {
if (keyType == null) {
throw new NullPointerException("keyType == null");
@@ -569,6 +608,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* key type of RSA this will set the modulus size and for a key type of
* EC it will select a curve with a matching field size.
*/
+ @NonNull
public Builder setKeySize(int keySize) {
if (keySize < 0) {
throw new IllegalArgumentException("keySize < 0");
@@ -581,7 +621,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* Sets the algorithm-specific key generation parameters. For example, for RSA keys
* this may be an instance of {@link java.security.spec.RSAKeyGenParameterSpec}.
*/
- public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec spec) {
+ public Builder setAlgorithmParameterSpec(@NonNull AlgorithmParameterSpec spec) {
if (spec == null) {
throw new NullPointerException("spec == null");
}
@@ -597,7 +637,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* {@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.
*/
- public Builder setSubject(X500Principal subject) {
+ @NonNull
+ public Builder setSubject(@NonNull X500Principal subject) {
if (subject == null) {
throw new NullPointerException("subject == null");
}
@@ -613,7 +654,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* {@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.
*/
- public Builder setSerialNumber(BigInteger serialNumber) {
+ @NonNull
+ public Builder setSerialNumber(@NonNull BigInteger serialNumber) {
if (serialNumber == null) {
throw new NullPointerException("serialNumber == null");
}
@@ -629,7 +671,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* {@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.
*/
- public Builder setStartDate(Date startDate) {
+ @NonNull
+ public Builder setStartDate(@NonNull Date startDate) {
if (startDate == null) {
throw new NullPointerException("startDate == null");
}
@@ -645,7 +688,8 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* {@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.
*/
- public Builder setEndDate(Date endDate) {
+ @NonNull
+ public Builder setEndDate(@NonNull Date endDate) {
if (endDate == null) {
throw new NullPointerException("endDate == null");
}
@@ -665,6 +709,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* @see KeyguardManager#isDeviceSecure()
*/
+ @NonNull
public Builder setEncryptionRequired() {
mFlags |= KeyStore.FLAG_ENCRYPTED;
return this;
@@ -675,10 +720,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @see #setKeyValidityEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
return this;
@@ -689,12 +735,13 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @see #setKeyValidityStart(Date)
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
setKeyValidityForConsumptionEnd(endDate);
@@ -706,10 +753,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @see #setKeyValidityForConsumptionEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
return this;
@@ -721,55 +769,67 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
return this;
}
/**
- * Sets the set of purposes for which the key can be used.
+ * 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.
*
* <p>This must be specified for all keys. There is no default.
*
* <p>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 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.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
+ @NonNull
public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Sets the set of digests with which the key can be used when signing/verifying. Attempts
- * to use the key with any other digest will be rejected.
+ * 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.
*
* <p>This must be specified for keys which are used for signing/verification.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * @see KeyStoreKeyProperties.Digest
*/
+ @NonNull
public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
return this;
}
/**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
+ * 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.
*
* <p>This must be specified for keys which are used for encryption/decryption.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public Builder setEncryptionPaddings(
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -777,14 +837,17 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the set of padding schemes with which the key can be used when
- * signing/verifying. Attempts to use the key with any other padding scheme will be
- * rejected.
+ * 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.
*
* <p>This must be specified for RSA keys which are used for signing/verification.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
+ @NonNull
public Builder setSignaturePaddings(
@KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -792,13 +855,17 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
}
/**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
+ * 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.
*
* <p>This must be specified for encryption/decryption keys.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
@@ -824,8 +891,9 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
* </ul>
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*/
+ @NonNull
public Builder setRandomizedEncryptionRequired(boolean required) {
mRandomizedEncryptionRequired = required;
return this;
@@ -847,10 +915,11 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>This restriction applies only to private key operations. Public key operations are not
* restricted.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
*/
+ @NonNull
public Builder setUserAuthenticationRequired(boolean required) {
mUserAuthenticationRequired = required;
return this;
@@ -865,14 +934,16 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* <p>This restriction applies only to private key operations. Public key operations are not
* restricted.
*
- * <p><b>NOTE: This has currently no effect.
+ * <p><b>NOTE: This has currently no effect.</b>
*
* @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
* every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
*/
- public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
+ @NonNull
+ public Builder setUserAuthenticationValidityDurationSeconds(
+ @IntRange(from = -1) int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
@@ -883,6 +954,7 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
* @throws IllegalArgumentException if a required field is missing
* @return built instance of {@code KeyPairGeneratorSpec}
*/
+ @NonNull
public KeyPairGeneratorSpec build() {
return new KeyPairGeneratorSpec(mContext,
mKeystoreAlias,
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 3ed8899..7e3193d 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -131,10 +131,10 @@ public class KeyStore {
return mToken;
}
- static int getKeyTypeForAlgorithm(@KeyStoreKeyProperties.AlgorithmEnum String keyType) {
- if (KeyStoreKeyProperties.Algorithm.RSA.equalsIgnoreCase(keyType)) {
+ static int getKeyTypeForAlgorithm(@KeyStoreKeyProperties.KeyAlgorithmEnum String keyType) {
+ if (KeyStoreKeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyType)) {
return NativeConstants.EVP_PKEY_RSA;
- } else if (KeyStoreKeyProperties.Algorithm.EC.equalsIgnoreCase(keyType)) {
+ } else if (KeyStoreKeyProperties.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 bd601bc..4eeca47 100644
--- a/keystore/java/android/security/KeyStoreCipherSpi.java
+++ b/keystore/java/android/security/KeyStoreCipherSpi.java
@@ -496,7 +496,7 @@ public abstract class KeyStoreCipherSpi extends CipherSpi implements KeyStoreCry
if ((mIv != null) && (mIv.length > 0)) {
try {
AlgorithmParameters params =
- AlgorithmParameters.getInstance(KeyStoreKeyProperties.Algorithm.AES);
+ AlgorithmParameters.getInstance(KeyStoreKeyProperties.KEY_ALGORITHM_AES);
params.init(new IvParameterSpec(mIv));
return params;
} catch (NoSuchAlgorithmException e) {
diff --git a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
index 4b914c2..d734d66 100644
--- a/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/KeyStoreKeyGeneratorSpi.java
@@ -174,7 +174,7 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
spec.getEncryptionPaddings());
mKeymasterBlockModes =
KeyStoreKeyProperties.BlockMode.allToKeymaster(spec.getBlockModes());
- if (((spec.getPurposes() & KeyStoreKeyProperties.Purpose.ENCRYPT) != 0)
+ if (((spec.getPurposes() & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0)
&& (spec.isRandomizedEncryptionRequired())) {
for (int keymasterBlockMode : mKeymasterBlockModes) {
if (!KeymasterUtils.isKeymasterBlockModeIndCpaCompatible(
@@ -247,7 +247,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() & KeyStoreKeyProperties.PURPOSE_ENCRYPT) != 0)
&& (!spec.isRandomizedEncryptionRequired())) {
// Permit caller-provided IV when encrypting with this key
args.addBoolean(KeymasterDefs.KM_TAG_CALLER_NONCE);
@@ -265,9 +265,9 @@ public abstract class KeyStoreKeyGeneratorSpi extends KeyGeneratorSpi {
throw new ProviderException(
"Keystore operation failed", KeyStore.getKeyStoreException(errorCode));
}
- String keyAlgorithmJCA;
+ @KeyStoreKeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA;
try {
- keyAlgorithmJCA = KeyStoreKeyProperties.Algorithm.fromKeymasterSecretKeyAlgorithm(
+ keyAlgorithmJCA = KeyStoreKeyProperties.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/KeyStoreKeyProperties.java b/keystore/java/android/security/KeyStoreKeyProperties.java
index 1cf6a7a..b58a7dd 100644
--- a/keystore/java/android/security/KeyStoreKeyProperties.java
+++ b/keystore/java/android/security/KeyStoreKeyProperties.java
@@ -17,6 +17,8 @@
package android.security;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.StringDef;
import android.security.keymaster.KeymasterDefs;
@@ -24,94 +26,83 @@ import libcore.util.EmptyArray;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.security.Key;
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
import java.util.Collection;
import java.util.Locale;
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKeyFactory;
-
/**
* Properties of {@code AndroidKeyStore} keys.
*/
public abstract class KeyStoreKeyProperties {
private KeyStoreKeyProperties() {}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef(flag = true,
- value = {Purpose.ENCRYPT, Purpose.DECRYPT, Purpose.SIGN, Purpose.VERIFY})
+ value = {
+ PURPOSE_ENCRYPT,
+ PURPOSE_DECRYPT,
+ PURPOSE_SIGN,
+ PURPOSE_VERIFY,
+ })
public @interface PurposeEnum {}
/**
- * Purposes of key.
+ * Purpose of key: encryption.
*/
- public static abstract class Purpose {
- private Purpose() {}
+ public static final int PURPOSE_ENCRYPT = 1 << 0;
- /**
- * Purpose: encryption.
- */
- public static final int ENCRYPT = 1 << 0;
+ /**
+ * Purpose of key: decryption.
+ */
+ public static final int PURPOSE_DECRYPT = 1 << 1;
- /**
- * Purpose: decryption.
- */
- public static final int DECRYPT = 1 << 1;
+ /**
+ * Purpose of key: signing or generating a Message Authentication Code (MAC).
+ */
+ public static final int PURPOSE_SIGN = 1 << 2;
- /**
- * Purpose: signing.
- */
- public static final int SIGN = 1 << 2;
+ /**
+ * Purpose of key: signature or Message Authentication Code (MAC) verification.
+ */
+ public static final int PURPOSE_VERIFY = 1 << 3;
- /**
- * Purpose: signature verification.
- */
- public static final int VERIFY = 1 << 3;
+ static abstract class Purpose {
+ private Purpose() {}
- /**
- * @hide
- */
- public static int toKeymaster(@PurposeEnum int purpose) {
+ static int toKeymaster(@PurposeEnum int purpose) {
switch (purpose) {
- case ENCRYPT:
+ case PURPOSE_ENCRYPT:
return KeymasterDefs.KM_PURPOSE_ENCRYPT;
- case DECRYPT:
+ case PURPOSE_DECRYPT:
return KeymasterDefs.KM_PURPOSE_DECRYPT;
- case SIGN:
+ case PURPOSE_SIGN:
return KeymasterDefs.KM_PURPOSE_SIGN;
- case VERIFY:
+ case PURPOSE_VERIFY:
return KeymasterDefs.KM_PURPOSE_VERIFY;
default:
throw new IllegalArgumentException("Unknown purpose: " + purpose);
}
}
- /**
- * @hide
- */
- public static @PurposeEnum int fromKeymaster(int purpose) {
+ static @PurposeEnum int fromKeymaster(int purpose) {
switch (purpose) {
case KeymasterDefs.KM_PURPOSE_ENCRYPT:
- return ENCRYPT;
+ return PURPOSE_ENCRYPT;
case KeymasterDefs.KM_PURPOSE_DECRYPT:
- return DECRYPT;
+ return PURPOSE_DECRYPT;
case KeymasterDefs.KM_PURPOSE_SIGN:
- return SIGN;
+ return PURPOSE_SIGN;
case KeymasterDefs.KM_PURPOSE_VERIFY:
- return VERIFY;
+ return PURPOSE_VERIFY;
default:
throw new IllegalArgumentException("Unknown purpose: " + purpose);
}
}
- /**
- * @hide
- */
- public static int[] allToKeymaster(@PurposeEnum int purposes) {
+ @NonNull
+ static int[] allToKeymaster(@PurposeEnum int purposes) {
int[] result = getSetFlags(purposes);
for (int i = 0; i < result.length; i++) {
result[i] = toKeymaster(result[i]);
@@ -119,10 +110,7 @@ public abstract class KeyStoreKeyProperties {
return result;
}
- /**
- * @hide
- */
- public static @PurposeEnum int allFromKeymaster(Collection<Integer> purposes) {
+ static @PurposeEnum int allFromKeymaster(@NonNull Collection<Integer> purposes) {
@PurposeEnum int result = 0;
for (int keymasterPurpose : purposes) {
result |= fromKeymaster(keymasterPurpose);
@@ -131,59 +119,51 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- Algorithm.RSA,
- Algorithm.EC,
- Algorithm.AES,
- Algorithm.HMAC_SHA1,
- Algorithm.HMAC_SHA224,
- Algorithm.HMAC_SHA256,
- Algorithm.HMAC_SHA384,
- Algorithm.HMAC_SHA512,
+ KEY_ALGORITHM_RSA,
+ KEY_ALGORITHM_EC,
+ KEY_ALGORITHM_AES,
+ KEY_ALGORITHM_HMAC_SHA1,
+ KEY_ALGORITHM_HMAC_SHA224,
+ KEY_ALGORITHM_HMAC_SHA256,
+ KEY_ALGORITHM_HMAC_SHA384,
+ KEY_ALGORITHM_HMAC_SHA512,
})
- public @interface AlgorithmEnum {}
+ public @interface KeyAlgorithmEnum {}
- /**
- * Key algorithms.
- *
- * <p>These are standard names which can be used to obtain instances of {@link KeyGenerator},
- * {@link KeyPairGenerator}, {@link Cipher} (as part of the transformation string), {@link Mac},
- * {@link KeyFactory}, {@link SecretKeyFactory}. These are also the names used by
- * {@link Key#getAlgorithm()}.
- */
- public static abstract class Algorithm {
- private Algorithm() {}
+ /** Rivest Shamir Adleman (RSA) key. */
+ public static final String KEY_ALGORITHM_RSA = "RSA";
- /** Rivest Shamir Adleman (RSA) key. */
- public static final String RSA = "RSA";
+ /** Elliptic Curve (EC) Cryptography key. */
+ public static final String KEY_ALGORITHM_EC = "EC";
- /** Elliptic Curve (EC) key. */
- public static final String EC = "EC";
+ /** Advanced Encryption Standard (AES) key. */
+ public static final String KEY_ALGORITHM_AES = "AES";
- /** Advanced Encryption Standard (AES) key. */
- public static final String AES = "AES";
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA1 = "HmacSHA1";
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-1 as the hash. */
- public static final String HMAC_SHA1 = "HmacSHA1";
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA224 = "HmacSHA224";
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-224 as the hash. */
- public static final String HMAC_SHA224 = "HmacSHA224";
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA256 = "HmacSHA256";
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-256 as the hash. */
- public static final String HMAC_SHA256 = "HmacSHA256";
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA384 = "HmacSHA384";
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-384 as the hash. */
- public static final String HMAC_SHA384 = "HmacSHA384";
+ /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */
+ public static final String KEY_ALGORITHM_HMAC_SHA512 = "HmacSHA512";
- /** Keyed-Hash Message Authentication Code (HMAC) key using SHA-512 as the hash. */
- public static final String HMAC_SHA512 = "HmacSHA512";
+ static abstract class KeyAlgorithm {
+ private KeyAlgorithm() {}
- /**
- * @hide
- */
- static int toKeymasterSecretKeyAlgorithm(@AlgorithmEnum String algorithm) {
- if (AES.equalsIgnoreCase(algorithm)) {
+ static int toKeymasterSecretKeyAlgorithm(@NonNull @KeyAlgorithmEnum String algorithm) {
+ if (KEY_ALGORITHM_AES.equalsIgnoreCase(algorithm)) {
return KeymasterDefs.KM_ALGORITHM_AES;
} else if (algorithm.toUpperCase(Locale.US).startsWith("HMAC")) {
return KeymasterDefs.KM_ALGORITHM_HMAC;
@@ -193,10 +173,8 @@ public abstract class KeyStoreKeyProperties {
}
}
- /**
- * @hide
- */
- static @AlgorithmEnum String fromKeymasterSecretKeyAlgorithm(
+ @NonNull
+ static @KeyAlgorithmEnum String fromKeymasterSecretKeyAlgorithm(
int keymasterAlgorithm, int keymasterDigest) {
switch (keymasterAlgorithm) {
case KeymasterDefs.KM_ALGORITHM_AES:
@@ -204,26 +182,26 @@ public abstract class KeyStoreKeyProperties {
throw new IllegalArgumentException("Digest not supported for AES key: "
+ Digest.fromKeymaster(keymasterDigest));
}
- return AES;
+ return KEY_ALGORITHM_AES;
case KeymasterDefs.KM_ALGORITHM_HMAC:
switch (keymasterDigest) {
case KeymasterDefs.KM_DIGEST_SHA1:
- return HMAC_SHA1;
+ return KEY_ALGORITHM_HMAC_SHA1;
case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return HMAC_SHA224;
+ return KEY_ALGORITHM_HMAC_SHA224;
case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return HMAC_SHA256;
+ return KEY_ALGORITHM_HMAC_SHA256;
case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return HMAC_SHA384;
+ return KEY_ALGORITHM_HMAC_SHA384;
case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return HMAC_SHA512;
+ return KEY_ALGORITHM_HMAC_SHA512;
default:
throw new IllegalArgumentException("Unsupported HMAC digest: "
+ Digest.fromKeymaster(keymasterDigest));
}
default:
throw new IllegalArgumentException(
- "Unsupported algorithm: " + keymasterAlgorithm);
+ "Unsupported key algorithm: " + keymasterAlgorithm);
}
}
@@ -232,7 +210,7 @@ public abstract class KeyStoreKeyProperties {
*
* @return keymaster digest or {@code -1} if the algorithm does not involve a digest.
*/
- static int toKeymasterDigest(@AlgorithmEnum String algorithm) {
+ static int toKeymasterDigest(@NonNull @KeyAlgorithmEnum String algorithm) {
String algorithmUpper = algorithm.toUpperCase(Locale.US);
if (algorithmUpper.startsWith("HMAC")) {
String digestUpper = algorithmUpper.substring("HMAC".length());
@@ -257,72 +235,65 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- BlockMode.ECB,
- BlockMode.CBC,
- BlockMode.CTR,
- BlockMode.GCM,
+ BLOCK_MODE_ECB,
+ BLOCK_MODE_CBC,
+ BLOCK_MODE_CTR,
+ BLOCK_MODE_GCM,
})
public @interface BlockModeEnum {}
- /**
- * Block modes that can be used when encrypting/decrypting using a key.
- */
- public static abstract class BlockMode {
- private BlockMode() {}
+ /** Electronic Codebook (ECB) block mode. */
+ public static final String BLOCK_MODE_ECB = "ECB";
- /** Electronic Codebook (ECB) block mode. */
- public static final String ECB = "ECB";
+ /** Cipher Block Chaining (CBC) block mode. */
+ public static final String BLOCK_MODE_CBC = "CBC";
- /** Cipher Block Chaining (CBC) block mode. */
- public static final String CBC = "CBC";
+ /** Counter (CTR) block mode. */
+ public static final String BLOCK_MODE_CTR = "CTR";
- /** Counter (CTR) block mode. */
- public static final String CTR = "CTR";
+ /** Galois/Counter Mode (GCM) block mode. */
+ public static final String BLOCK_MODE_GCM = "GCM";
- /** Galois/Counter Mode (GCM) block mode. */
- public static final String GCM = "GCM";
+ static abstract class BlockMode {
+ private BlockMode() {}
- /**
- * @hide
- */
- static int toKeymaster(@BlockModeEnum String blockMode) {
- if (ECB.equalsIgnoreCase(blockMode)) {
+ static int toKeymaster(@NonNull @BlockModeEnum String blockMode) {
+ if (BLOCK_MODE_ECB.equalsIgnoreCase(blockMode)) {
return KeymasterDefs.KM_MODE_ECB;
- } else if (CBC.equalsIgnoreCase(blockMode)) {
+ } else if (BLOCK_MODE_CBC.equalsIgnoreCase(blockMode)) {
return KeymasterDefs.KM_MODE_CBC;
- } else if (CTR.equalsIgnoreCase(blockMode)) {
+ } else if (BLOCK_MODE_CTR.equalsIgnoreCase(blockMode)) {
return KeymasterDefs.KM_MODE_CTR;
- } else if (GCM.equalsIgnoreCase(blockMode)) {
+ } else if (BLOCK_MODE_GCM.equalsIgnoreCase(blockMode)) {
return KeymasterDefs.KM_MODE_GCM;
} else {
throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
}
}
- /**
- * @hide
- */
+ @NonNull
static @BlockModeEnum String fromKeymaster(int blockMode) {
switch (blockMode) {
case KeymasterDefs.KM_MODE_ECB:
- return ECB;
+ return BLOCK_MODE_ECB;
case KeymasterDefs.KM_MODE_CBC:
- return CBC;
+ return BLOCK_MODE_CBC;
case KeymasterDefs.KM_MODE_CTR:
- return CTR;
+ return BLOCK_MODE_CTR;
case KeymasterDefs.KM_MODE_GCM:
- return GCM;
+ return BLOCK_MODE_GCM;
default:
throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
}
}
- /**
- * @hide
- */
- static @BlockModeEnum String[] allFromKeymaster(Collection<Integer> blockModes) {
+ @NonNull
+ static @BlockModeEnum String[] allFromKeymaster(@NonNull Collection<Integer> blockModes) {
if ((blockModes == null) || (blockModes.isEmpty())) {
return EmptyArray.STRING;
}
@@ -335,10 +306,7 @@ public abstract class KeyStoreKeyProperties {
return result;
}
- /**
- * @hide
- */
- static int[] allToKeymaster(@BlockModeEnum String[] blockModes) {
+ static int[] allToKeymaster(@Nullable @BlockModeEnum String[] blockModes) {
if ((blockModes == null) || (blockModes.length == 0)) {
return EmptyArray.INT;
}
@@ -350,52 +318,49 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- EncryptionPadding.NONE,
- EncryptionPadding.PKCS7,
- EncryptionPadding.RSA_PKCS1,
- EncryptionPadding.RSA_OAEP,
+ ENCRYPTION_PADDING_NONE,
+ ENCRYPTION_PADDING_PKCS7,
+ ENCRYPTION_PADDING_RSA_PKCS1,
+ ENCRYPTION_PADDING_RSA_OAEP,
})
public @interface EncryptionPaddingEnum {}
/**
- * Padding schemes for encryption/decryption.
+ * No encryption padding.
*/
- public static abstract class EncryptionPadding {
- private EncryptionPadding() {}
+ public static final String ENCRYPTION_PADDING_NONE = "NoPadding";
- /**
- * No padding.
- */
- public static final String NONE = "NoPadding";
+ /**
+ * PKCS#7 encryption padding scheme.
+ */
+ public static final String ENCRYPTION_PADDING_PKCS7 = "PKCS7Padding";
- /**
- * PKCS#7 padding.
- */
- public static final String PKCS7 = "PKCS7Padding";
+ /**
+ * RSA PKCS#1 v1.5 padding scheme for encryption.
+ */
+ public static final String ENCRYPTION_PADDING_RSA_PKCS1 = "PKCS1Padding";
- /**
- * RSA PKCS#1 v1.5 padding for encryption/decryption.
- */
- public static final String RSA_PKCS1 = "PKCS1Padding";
+ /**
+ * RSA Optimal Asymmetric Encryption Padding (OAEP) scheme.
+ */
+ public static final String ENCRYPTION_PADDING_RSA_OAEP = "OAEPPadding";
- /**
- * RSA Optimal Asymmetric Encryption Padding (OAEP).
- */
- public static final String RSA_OAEP = "OAEPPadding";
+ static abstract class EncryptionPadding {
+ private EncryptionPadding() {}
- /**
- * @hide
- */
- static int toKeymaster(@EncryptionPaddingEnum String padding) {
- if (NONE.equalsIgnoreCase(padding)) {
+ static int toKeymaster(@NonNull @EncryptionPaddingEnum String padding) {
+ if (ENCRYPTION_PADDING_NONE.equalsIgnoreCase(padding)) {
return KeymasterDefs.KM_PAD_NONE;
- } else if (PKCS7.equalsIgnoreCase(padding)) {
+ } else if (ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(padding)) {
return KeymasterDefs.KM_PAD_PKCS7;
- } else if (RSA_PKCS1.equalsIgnoreCase(padding)) {
+ } else if (ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(padding)) {
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT;
- } else if (RSA_OAEP.equalsIgnoreCase(padding)) {
+ } else if (ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(padding)) {
return KeymasterDefs.KM_PAD_RSA_OAEP;
} else {
throw new IllegalArgumentException(
@@ -403,29 +368,25 @@ public abstract class KeyStoreKeyProperties {
}
}
- /**
- * @hide
- */
+ @NonNull
static @EncryptionPaddingEnum String fromKeymaster(int padding) {
switch (padding) {
case KeymasterDefs.KM_PAD_NONE:
- return NONE;
+ return ENCRYPTION_PADDING_NONE;
case KeymasterDefs.KM_PAD_PKCS7:
- return PKCS7;
+ return ENCRYPTION_PADDING_PKCS7;
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT:
- return RSA_PKCS1;
+ return ENCRYPTION_PADDING_RSA_PKCS1;
case KeymasterDefs.KM_PAD_RSA_OAEP:
- return RSA_OAEP;
+ return ENCRYPTION_PADDING_RSA_OAEP;
default:
throw new IllegalArgumentException(
"Unsupported encryption padding: " + padding);
}
}
- /**
- * @hide
- */
- static int[] allToKeymaster(@EncryptionPaddingEnum String[] paddings) {
+ @NonNull
+ static int[] allToKeymaster(@Nullable @EncryptionPaddingEnum String[] paddings) {
if ((paddings == null) || (paddings.length == 0)) {
return EmptyArray.INT;
}
@@ -437,37 +398,34 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- SignaturePadding.RSA_PKCS1,
- SignaturePadding.RSA_PSS,
+ SIGNATURE_PADDING_RSA_PKCS1,
+ SIGNATURE_PADDING_RSA_PSS,
})
public @interface SignaturePaddingEnum {}
/**
- * Padding schemes for signing/verification.
+ * RSA PKCS#1 v1.5 padding for signatures.
*/
- public static abstract class SignaturePadding {
- private SignaturePadding() {}
+ public static final String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
- /**
- * RSA PKCS#1 v1.5 padding for signatures.
- */
- public static final String RSA_PKCS1 = "PKCS1";
+ /**
+ * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
+ */
+ public static final String SIGNATURE_PADDING_RSA_PSS = "PSS";
- /**
- * RSA PKCS#1 v2.1 Probabilistic Signature Scheme (PSS) padding.
- */
- public static final String RSA_PSS = "PSS";
+ static abstract class SignaturePadding {
+ private SignaturePadding() {}
- /**
- * @hide
- */
- static int toKeymaster(@SignaturePaddingEnum String padding) {
+ static int toKeymaster(@NonNull @SignaturePaddingEnum String padding) {
switch (padding.toUpperCase(Locale.US)) {
- case RSA_PKCS1:
+ case SIGNATURE_PADDING_RSA_PKCS1:
return KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN;
- case RSA_PSS:
+ case SIGNATURE_PADDING_RSA_PSS:
return KeymasterDefs.KM_PAD_RSA_PSS;
default:
throw new IllegalArgumentException(
@@ -475,24 +433,20 @@ public abstract class KeyStoreKeyProperties {
}
}
- /**
- * @hide
- */
+ @NonNull
static @SignaturePaddingEnum String fromKeymaster(int padding) {
switch (padding) {
case KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN:
- return RSA_PKCS1;
+ return SIGNATURE_PADDING_RSA_PKCS1;
case KeymasterDefs.KM_PAD_RSA_PSS:
- return RSA_PSS;
+ return SIGNATURE_PADDING_RSA_PSS;
default:
throw new IllegalArgumentException("Unsupported signature padding: " + padding);
}
}
- /**
- * @hide
- */
- static int[] allToKeymaster(@SignaturePaddingEnum String[] paddings) {
+ @NonNull
+ static int[] allToKeymaster(@Nullable @SignaturePaddingEnum String[] paddings) {
if ((paddings == null) || (paddings.length == 0)) {
return EmptyArray.INT;
}
@@ -504,112 +458,104 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- Digest.NONE,
- Digest.MD5,
- Digest.SHA1,
- Digest.SHA224,
- Digest.SHA256,
- Digest.SHA384,
- Digest.SHA512,
+ DIGEST_NONE,
+ DIGEST_MD5,
+ DIGEST_SHA1,
+ DIGEST_SHA224,
+ DIGEST_SHA256,
+ DIGEST_SHA384,
+ DIGEST_SHA512,
})
public @interface DigestEnum {}
/**
- * Digests that can be used with a key when signing or generating Message Authentication
- * Codes (MACs).
+ * No digest: sign/authenticate the raw message.
*/
- public static abstract class Digest {
- private Digest() {}
+ public static final String DIGEST_NONE = "NONE";
- /**
- * No digest: sign/authenticate the raw message.
- */
- public static final String NONE = "NONE";
+ /**
+ * MD5 digest.
+ */
+ public static final String DIGEST_MD5 = "MD5";
- /**
- * MD5 digest.
- */
- public static final String MD5 = "MD5";
+ /**
+ * SHA-1 digest.
+ */
+ public static final String DIGEST_SHA1 = "SHA-1";
- /**
- * SHA-1 digest.
- */
- public static final String SHA1 = "SHA-1";
+ /**
+ * SHA-2 224 (aka SHA-224) digest.
+ */
+ public static final String DIGEST_SHA224 = "SHA-224";
- /**
- * SHA-2 224 (aka SHA-224) digest.
- */
- public static final String SHA224 = "SHA-224";
+ /**
+ * SHA-2 256 (aka SHA-256) digest.
+ */
+ public static final String DIGEST_SHA256 = "SHA-256";
- /**
- * SHA-2 256 (aka SHA-256) digest.
- */
- public static final String SHA256 = "SHA-256";
+ /**
+ * SHA-2 384 (aka SHA-384) digest.
+ */
+ public static final String DIGEST_SHA384 = "SHA-384";
- /**
- * SHA-2 384 (aka SHA-384) digest.
- */
- public static final String SHA384 = "SHA-384";
+ /**
+ * SHA-2 512 (aka SHA-512) digest.
+ */
+ public static final String DIGEST_SHA512 = "SHA-512";
- /**
- * SHA-2 512 (aka SHA-512) digest.
- */
- public static final String SHA512 = "SHA-512";
+ static abstract class Digest {
+ private Digest() {}
- /**
- * @hide
- */
- static int toKeymaster(@DigestEnum String digest) {
+ static int toKeymaster(@NonNull @DigestEnum String digest) {
switch (digest.toUpperCase(Locale.US)) {
- case SHA1:
+ case DIGEST_SHA1:
return KeymasterDefs.KM_DIGEST_SHA1;
- case SHA224:
+ case DIGEST_SHA224:
return KeymasterDefs.KM_DIGEST_SHA_2_224;
- case SHA256:
+ case DIGEST_SHA256:
return KeymasterDefs.KM_DIGEST_SHA_2_256;
- case SHA384:
+ case DIGEST_SHA384:
return KeymasterDefs.KM_DIGEST_SHA_2_384;
- case SHA512:
+ case DIGEST_SHA512:
return KeymasterDefs.KM_DIGEST_SHA_2_512;
- case NONE:
+ case DIGEST_NONE:
return KeymasterDefs.KM_DIGEST_NONE;
- case MD5:
+ case DIGEST_MD5:
return KeymasterDefs.KM_DIGEST_MD5;
default:
throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
}
}
- /**
- * @hide
- */
+ @NonNull
static @DigestEnum String fromKeymaster(int digest) {
switch (digest) {
case KeymasterDefs.KM_DIGEST_NONE:
- return NONE;
+ return DIGEST_NONE;
case KeymasterDefs.KM_DIGEST_MD5:
- return MD5;
+ return DIGEST_MD5;
case KeymasterDefs.KM_DIGEST_SHA1:
- return SHA1;
+ return DIGEST_SHA1;
case KeymasterDefs.KM_DIGEST_SHA_2_224:
- return SHA224;
+ return DIGEST_SHA224;
case KeymasterDefs.KM_DIGEST_SHA_2_256:
- return SHA256;
+ return DIGEST_SHA256;
case KeymasterDefs.KM_DIGEST_SHA_2_384:
- return SHA384;
+ return DIGEST_SHA384;
case KeymasterDefs.KM_DIGEST_SHA_2_512:
- return SHA512;
+ return DIGEST_SHA512;
default:
throw new IllegalArgumentException("Unsupported digest algorithm: " + digest);
}
}
- /**
- * @hide
- */
- static @DigestEnum String[] allFromKeymaster(Collection<Integer> digests) {
+ @NonNull
+ static @DigestEnum String[] allFromKeymaster(@NonNull Collection<Integer> digests) {
if (digests.isEmpty()) {
return EmptyArray.STRING;
}
@@ -622,10 +568,8 @@ public abstract class KeyStoreKeyProperties {
return result;
}
- /**
- * @hide
- */
- static int[] allToKeymaster(@DigestEnum String[] digests) {
+ @NonNull
+ static int[] allToKeymaster(@Nullable @DigestEnum String[] digests) {
if ((digests == null) || (digests.length == 0)) {
return EmptyArray.INT;
}
@@ -639,39 +583,40 @@ public abstract class KeyStoreKeyProperties {
}
}
+ /**
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({Origin.GENERATED, Origin.IMPORTED, Origin.UNKNOWN})
+ @IntDef({
+ ORIGIN_GENERATED,
+ ORIGIN_IMPORTED,
+ ORIGIN_UNKNOWN,
+ })
public @interface OriginEnum {}
- /**
- * Origin of the key.
- */
- public static abstract class Origin {
- private Origin() {}
+ /** Key was generated inside AndroidKeyStore. */
+ public static final int ORIGIN_GENERATED = 1 << 0;
- /** Key was generated inside AndroidKeyStore. */
- public static final int GENERATED = 1 << 0;
+ /** Key was imported into AndroidKeyStore. */
+ public static final int ORIGIN_IMPORTED = 1 << 1;
- /** Key was imported into AndroidKeyStore. */
- public static final int IMPORTED = 1 << 1;
+ /**
+ * Origin of the key is unknown. This can occur only for keys backed by an old TEE-backed
+ * implementation which does not record origin information.
+ */
+ public static final int ORIGIN_UNKNOWN = 1 << 2;
- /**
- * Origin of the key is unknown. This can occur only for keys backed by an old TEE-backed
- * implementation which does not record origin information.
- */
- public static final int UNKNOWN = 1 << 2;
+ static abstract class Origin {
+ private Origin() {}
- /**
- * @hide
- */
- public static @OriginEnum int fromKeymaster(int origin) {
+ static @OriginEnum int fromKeymaster(int origin) {
switch (origin) {
case KeymasterDefs.KM_ORIGIN_GENERATED:
- return GENERATED;
+ return ORIGIN_GENERATED;
case KeymasterDefs.KM_ORIGIN_IMPORTED:
- return IMPORTED;
+ return ORIGIN_IMPORTED;
case KeymasterDefs.KM_ORIGIN_UNKNOWN:
- return UNKNOWN;
+ return ORIGIN_UNKNOWN;
default:
throw new IllegalArgumentException("Unknown origin: " + origin);
}
diff --git a/keystore/java/android/security/KeyStoreKeySpec.java b/keystore/java/android/security/KeyStoreKeySpec.java
index 0a9acbb..4c43f89 100644
--- a/keystore/java/android/security/KeyStoreKeySpec.java
+++ b/keystore/java/android/security/KeyStoreKeySpec.java
@@ -16,6 +16,9 @@
package android.security;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
import java.security.PrivateKey;
import java.security.spec.KeySpec;
import java.util.Date;
@@ -132,7 +135,7 @@ public class KeyStoreKeySpec implements KeySpec {
}
/**
- * Gets the origin of the key.
+ * Gets the origin of the key. See {@link KeyStoreKeyProperties}.{@code ORIGIN} constants.
*/
public @KeyStoreKeyProperties.OriginEnum int getOrigin() {
return mOrigin;
@@ -150,6 +153,7 @@ public class KeyStoreKeySpec implements KeySpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityStart() {
return mKeyValidityStart;
}
@@ -159,6 +163,7 @@ public class KeyStoreKeySpec implements KeySpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
}
@@ -168,41 +173,64 @@ public class KeyStoreKeySpec implements KeySpec {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
}
/**
- * Gets the set of purposes for which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of block modes with which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
/**
- * Gets the set of padding modes with which the key can be used when encrypting/decrypting.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of padding modes with which the key can be used when signing/verifying.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
- * Gets the set of digest algorithms with which the key can be used.
+ * 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);
}
diff --git a/keystore/java/android/security/KeyStoreParameter.java b/keystore/java/android/security/KeyStoreParameter.java
index 7332332..a7fab80 100644
--- a/keystore/java/android/security/KeyStoreParameter.java
+++ b/keystore/java/android/security/KeyStoreParameter.java
@@ -16,6 +16,9 @@
package android.security;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.content.Context;
@@ -59,11 +62,11 @@ import javax.crypto.Cipher;
* "key1",
* new KeyStore.SecretKeyEntry(key),
* new KeyStoreParameter.Builder(context)
- * .setPurposes(KeyStoreKeyProperties.Purpose.ENCRYPT
- * | KeyStoreKeyProperties.Purpose.DECRYPT)
- * .setBlockMode(KeyStoreKeyProperties.BlockMode.CBC)
+ * .setPurposes(KeyStoreKeyProperties.PURPOSE_ENCRYPT
+ * | KeyStoreKeyProperties.PURPOSE_DECRYPT)
+ * .setBlockMode(KeyStoreKeyProperties.BLOCK_MODE_CBC)
* .setEncryptionPaddings(
- * KeyStoreKeyProperties.EncryptionPaddings.PKCS7)
+ * KeyStoreKeyProperties.ENCRYPTION_PADDING_PKCS7)
* .build());
* // Key imported, obtain a reference to it.
* SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
@@ -87,8 +90,8 @@ import javax.crypto.Cipher;
* "key2",
* new KeyStore.PrivateKeyEntry(privateKey, certChain),
* new KeyStoreParameter.Builder(context)
- * .setPurposes(KeyStoreKeyProperties.Purpose.SIGN)
- * .setDigests(KeyStoreKeyProperties.Digest.SHA256)
+ * .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)
@@ -182,6 +185,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityStart() {
return mKeyValidityStart;
}
@@ -191,6 +195,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForConsumptionEnd() {
return mKeyValidityForConsumptionEnd;
}
@@ -200,39 +205,55 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @return instant or {@code null} if not restricted.
*/
+ @Nullable
public Date getKeyValidityForOriginationEnd() {
return mKeyValidityForOriginationEnd;
}
/**
- * Gets the set of purposes for which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
public @KeyStoreKeyProperties.PurposeEnum int getPurposes() {
return mPurposes;
}
/**
- * Gets the set of padding schemes with which the key can be used when encrypting/decrypting.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.EncryptionPaddingEnum String[] getEncryptionPaddings() {
return ArrayUtils.cloneIfNotEmpty(mEncryptionPaddings);
}
/**
- * Gets the set of padding schemes with which the key can be used when signing or verifying
- * signatures.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.SignaturePaddingEnum String[] getSignaturePaddings() {
return ArrayUtils.cloneIfNotEmpty(mSignaturePaddings);
}
/**
- * Gets the set of digest algorithms with which the key can be used.
+ * 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");
@@ -246,13 +267,19 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @see #getDigests()
*/
+ @NonNull
public boolean isDigestsSpecified() {
return mDigests != null;
}
/**
- * Gets the set of block modes with which the key can be used.
+ * 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.
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public @KeyStoreKeyProperties.BlockModeEnum String[] getBlockModes() {
return ArrayUtils.cloneIfNotEmpty(mBlockModes);
}
@@ -330,7 +357,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
* some UI to ask the user to unlock or initialize the Android KeyStore
* facility.
*/
- public Builder(Context context) {
+ public Builder(@NonNull Context context) {
if (context == null) {
throw new NullPointerException("context == null");
}
@@ -350,6 +377,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* @see KeyguardManager#isDeviceSecure()
*/
+ @NonNull
public Builder setEncryptionRequired(boolean required) {
if (required) {
mFlags |= KeyStore.FLAG_ENCRYPTED;
@@ -364,10 +392,11 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @see #setKeyValidityEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityStart(Date startDate) {
mKeyValidityStart = startDate;
return this;
@@ -378,12 +407,13 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @see #setKeyValidityStart(Date)
* @see #setKeyValidityForConsumptionEnd(Date)
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityEnd(Date endDate) {
setKeyValidityForOriginationEnd(endDate);
setKeyValidityForConsumptionEnd(endDate);
@@ -395,10 +425,11 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @see #setKeyValidityForConsumptionEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForOriginationEnd(Date endDate) {
mKeyValidityForOriginationEnd = endDate;
return this;
@@ -410,36 +441,44 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* <p>By default, the key is valid at any instant.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @see #setKeyValidityForOriginationEnd(Date)
*/
+ @NonNull
public Builder setKeyValidityForConsumptionEnd(Date endDate) {
mKeyValidityForConsumptionEnd = endDate;
return this;
}
/**
- * Sets the set of purposes for which the key can be used.
+ * 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.
*
* <p>This must be specified for all keys. There is no default.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code PURPOSE} flags.
*/
+ @NonNull
public Builder setPurposes(@KeyStoreKeyProperties.PurposeEnum int purposes) {
mPurposes = purposes;
return this;
}
/**
- * Sets the set of padding schemes with which the key can be used when
- * encrypting/decrypting. Attempts to use the key with any other padding scheme will be
- * rejected.
+ * 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.
*
* <p>This must be specified for keys which are used for encryption/decryption.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code ENCRYPTION_PADDING} constants.
*/
+ @NonNull
public Builder setEncryptionPaddings(
@KeyStoreKeyProperties.EncryptionPaddingEnum String... paddings) {
mEncryptionPaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -447,14 +486,17 @@ public final class KeyStoreParameter implements ProtectionParameter {
}
/**
- * Sets the set of padding schemes with which the key can be used when
- * signing/verifying. Attempts to use the key with any other padding scheme will be
- * rejected.
+ * 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.
*
* <p>This must be specified for RSA keys which are used for signing/verification.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code SIGNATURE_PADDING} constants.
*/
+ @NonNull
public Builder setSignaturePaddings(
@KeyStoreKeyProperties.SignaturePaddingEnum String... paddings) {
mSignaturePaddings = ArrayUtils.cloneIfNotEmpty(paddings);
@@ -463,27 +505,36 @@ public final class KeyStoreParameter implements ProtectionParameter {
/**
- * Sets the set of digests with which the key can be used when signing/verifying or
- * generating MACs. Attempts to use the key with any other digest will be rejected.
+ * 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.
*
- * <p>For HMAC keys, the default is the digest specified in {@link Key#getAlgorithm()}. For
- * asymmetric signing keys this constraint must be specified.
+ * <p>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.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * @see KeyStoreKeyProperties.Digest
*/
+ @NonNull
public Builder setDigests(@KeyStoreKeyProperties.DigestEnum String... digests) {
mDigests = ArrayUtils.cloneIfNotEmpty(digests);
return this;
}
/**
- * Sets the set of block modes with which the key can be used when encrypting/decrypting.
- * Attempts to use the key with any other block modes will be rejected.
+ * 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.
*
* <p>This must be specified for encryption/decryption keys.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
+ *
+ * <p>See {@link KeyStoreKeyProperties}.{@code BLOCK_MODE} constants.
*/
+ @NonNull
public Builder setBlockModes(@KeyStoreKeyProperties.BlockModeEnum String... blockModes) {
mBlockModes = ArrayUtils.cloneIfNotEmpty(blockModes);
return this;
@@ -523,8 +574,9 @@ public final class KeyStoreParameter implements ProtectionParameter {
* schemes which offer {@code IND-CPA}, such as PKCS#1 or OAEP.</li>
* </ul>
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*/
+ @NonNull
public Builder setRandomizedEncryptionRequired(boolean required) {
mRandomizedEncryptionRequired = required;
return this;
@@ -543,10 +595,11 @@ public final class KeyStoreParameter implements ProtectionParameter {
* <a href="{@docRoot}training/articles/keystore.html#UserAuthentication">More
* information</a>.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @see #setUserAuthenticationValidityDurationSeconds(int)
*/
+ @NonNull
public Builder setUserAuthenticationRequired(boolean required) {
mUserAuthenticationRequired = required;
return this;
@@ -558,14 +611,16 @@ public final class KeyStoreParameter implements ProtectionParameter {
*
* <p>By default, the user needs to authenticate for every use of the key.
*
- * <p><b>NOTE: This has currently no effect on asymmetric key pairs.
+ * <p><b>NOTE: This has currently no effect on asymmetric key pairs.</b>
*
* @param seconds duration in seconds or {@code -1} if the user needs to authenticate for
* every use of the key.
*
* @see #setUserAuthenticationRequired(boolean)
*/
- public Builder setUserAuthenticationValidityDurationSeconds(int seconds) {
+ @NonNull
+ public Builder setUserAuthenticationValidityDurationSeconds(
+ @IntRange(from = -1) int seconds) {
mUserAuthenticationValidityDurationSeconds = seconds;
return this;
}
@@ -576,6 +631,7 @@ public final class KeyStoreParameter implements ProtectionParameter {
* @throws IllegalArgumentException if a required field is missing
* @return built instance of {@code KeyStoreParameter}
*/
+ @NonNull
public KeyStoreParameter build() {
return new KeyStoreParameter(
mContext,