summaryrefslogtreecommitdiffstats
path: root/keystore/java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore/java')
-rw-r--r--keystore/java/android/security/AndroidKeyPairGeneratorSpec.java144
-rw-r--r--keystore/java/android/security/Credentials.java8
-rw-r--r--keystore/java/android/security/KeyChain.java24
-rw-r--r--keystore/java/android/security/KeyStore.java18
4 files changed, 190 insertions, 4 deletions
diff --git a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
index 79a7630..83faf35 100644
--- a/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
+++ b/keystore/java/android/security/AndroidKeyPairGeneratorSpec.java
@@ -28,10 +28,28 @@ import java.util.Date;
import javax.security.auth.x500.X500Principal;
/**
- * This provides the required parameters needed for initializing the KeyPair
- * generator that works with
- * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore
- * facility</a>.
+ * This provides the required parameters needed for initializing the
+ * {@code KeyPairGenerator} that works with <a href="{@docRoot}
+ * guide/topics/security/keystore.html">Android KeyStore facility</a>. The
+ * Android KeyStore facility is accessed through a
+ * {@link java.security.KeyPairGenerator} API using the
+ * {@code AndroidKeyPairGenerator} provider. The {@code context} passed in may
+ * be used to pop up some UI to ask the user to unlock or initialize the Android
+ * keystore facility.
+ * <p>
+ * After generation, the {@code keyStoreAlias} is used with the
+ * {@link java.security.KeyStore#getEntry(String, java.security.KeyStore.ProtectionParameter)}
+ * interface to retrieve the {@link PrivateKey} and its associated
+ * {@link Certificate} chain.
+ * <p>
+ * The KeyPair generator will create a self-signed certificate with the subject
+ * as its X.509v3 Subject Distinguished Name and as its X.509v3 Issuer
+ * Distinguished Name along with the other parameters specified with the
+ * {@link Builder}.
+ * <p>
+ * The self-signed certificate may be replaced at a later time by a certificate
+ * signed by a real Certificate Authority.
+ *
* @hide
*/
public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
@@ -74,6 +92,7 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
* period
* @throws IllegalArgumentException when any argument is {@code null} or
* {@code endDate} is before {@code startDate}.
+ * @hide should be built with AndroidKeyPairGeneratorSpecBuilder
*/
public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias,
X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) {
@@ -142,4 +161,121 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec {
Date getEndDate() {
return mEndDate;
}
+
+ /**
+ * Builder class for {@link AndroidKeyPairGeneratorSpec} objects.
+ * <p>
+ * This will build a parameter spec for use with the <a href="{@docRoot}
+ * guide/topics/security/keystore.html">Android KeyStore facility</a>.
+ * <p>
+ * The required fields must be filled in with the builder.
+ * <p>
+ * Example:
+ *
+ * <pre class="prettyprint">
+ * Calendar start = new Calendar();
+ * Calendar end = new Calendar();
+ * end.add(1, Calendar.YEAR);
+ *
+ * AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(mContext)
+ * .setAlias("myKey")
+ * .setSubject(new X500Principal("CN=myKey"))
+ * .setSerial(BigInteger.valueOf(1337))
+ * .setStartDate(start.getTime())
+ * .setEndDate(end.getTime())
+ * .build();
+ * </pre>
+ */
+ public static class Builder {
+ private final Context mContext;
+
+ private String mKeystoreAlias;
+
+ private X500Principal mSubjectDN;
+
+ private BigInteger mSerialNumber;
+
+ private Date mStartDate;
+
+ private Date mEndDate;
+
+ public Builder(Context context) {
+ if (context == null) {
+ throw new NullPointerException("context == null");
+ }
+ mContext = context;
+ }
+
+ /**
+ * Sets the alias to be used to retrieve the key later from a
+ * {@link java.security.KeyStore} instance using the
+ * {@code AndroidKeyStore} provider.
+ */
+ public Builder setAlias(String alias) {
+ if (alias == null) {
+ throw new NullPointerException("alias == null");
+ }
+ mKeystoreAlias = alias;
+ return this;
+ }
+
+ /**
+ * Sets the subject used for the self-signed certificate of the
+ * generated key pair.
+ */
+ public Builder setSubject(X500Principal subject) {
+ if (subject == null) {
+ throw new NullPointerException("subject == null");
+ }
+ mSubjectDN = subject;
+ return this;
+ }
+
+ /**
+ * Sets the serial number used for the self-signed certificate of the
+ * generated key pair.
+ */
+ public Builder setSerialNumber(BigInteger serialNumber) {
+ if (serialNumber == null) {
+ throw new NullPointerException("serialNumber == null");
+ }
+ mSerialNumber = serialNumber;
+ return this;
+ }
+
+ /**
+ * Sets the start of the validity period for the self-signed certificate
+ * of the generated key pair.
+ */
+ public Builder setStartDate(Date startDate) {
+ if (startDate == null) {
+ throw new NullPointerException("startDate == null");
+ }
+ mStartDate = startDate;
+ return this;
+ }
+
+ /**
+ * Sets the end of the validity period for the self-signed certificate
+ * of the generated key pair.
+ */
+ public Builder setEndDate(Date endDate) {
+ if (endDate == null) {
+ throw new NullPointerException("endDate == null");
+ }
+ mEndDate = endDate;
+ return this;
+ }
+
+ /**
+ * Builds the instance of the {@code AndroidKeyPairGeneratorSpec}.
+ *
+ * @throws IllegalArgumentException if a required field is missing
+ * @return built instance of {@code AndroidKeyPairGeneratorSpec}
+ */
+ public AndroidKeyPairGeneratorSpec build() {
+ return new AndroidKeyPairGeneratorSpec(mContext, mKeystoreAlias, mSubjectDN,
+ mSerialNumber, mStartDate, mEndDate);
+ }
+ }
}
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index d8109ce..166849d 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -49,6 +49,8 @@ public class Credentials {
public static final String INSTALL_ACTION = "android.credentials.INSTALL";
+ public static final String INSTALL_AS_USER_ACTION = "android.credentials.INSTALL_AS_USER";
+
public static final String UNLOCK_ACTION = "com.android.credentials.UNLOCK";
/** Key prefix for CA certificates. */
@@ -83,6 +85,12 @@ public class Credentials {
public static final String EXTENSION_PFX = ".pfx";
/**
+ * Intent extra: install the certificate bundle as this UID instead of
+ * system.
+ */
+ public static final String EXTRA_INSTALL_AS_UID = "install_as_uid";
+
+ /**
* Intent extra: name for the user's private key.
*/
public static final String EXTRA_USER_PRIVATE_KEY_NAME = "user_private_key_name";
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index d7119fff..c99dff0 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -356,6 +356,30 @@ public final class KeyChain {
}
}
+ /**
+ * Returns {@code true} if the current device's {@code KeyChain} supports a
+ * specific {@code PrivateKey} type indicated by {@code algorithm} (e.g.,
+ * "RSA").
+ */
+ public static boolean isKeyAlgorithmSupported(String algorithm) {
+ return "RSA".equals(algorithm);
+ }
+
+ /**
+ * Returns {@code true} if the current device's {@code KeyChain} binds any
+ * {@code PrivateKey} of the given {@code algorithm} to the device once
+ * imported or generated. This can be used to tell if there is special
+ * hardware support that can be used to bind keys to the device in a way
+ * that makes it non-exportable.
+ */
+ public static boolean isBoundKeyAlgorithm(String algorithm) {
+ if (!isKeyAlgorithmSupported(algorithm)) {
+ return false;
+ }
+
+ return KeyStore.getInstance().isHardwareBacked();
+ }
+
private static X509Certificate toCertificate(byte[] bytes) {
if (bytes == null) {
throw new IllegalArgumentException("bytes == null");
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 12c0ed8..852f0bb 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -296,6 +296,24 @@ public class KeyStore {
}
}
+ public boolean isHardwareBacked() {
+ try {
+ return mBinder.is_hardware_backed() == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
+ }
+
+ public boolean clearUid(int uid) {
+ try {
+ return mBinder.clear_uid(uid) == NO_ERROR;
+ } catch (RemoteException e) {
+ Log.w(TAG, "Cannot connect to keystore", e);
+ return false;
+ }
+ }
+
public int getLastError() {
return mError;
}