diff options
Diffstat (limited to 'keystore/java')
-rw-r--r-- | keystore/java/android/security/AndroidKeyPairGeneratorSpec.java | 144 | ||||
-rw-r--r-- | keystore/java/android/security/Credentials.java | 8 | ||||
-rw-r--r-- | keystore/java/android/security/KeyChain.java | 24 | ||||
-rw-r--r-- | keystore/java/android/security/KeyStore.java | 18 |
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; } |