Loading keystore/java/android/security/AndroidKeyPairGeneratorSpec.java +140 −4 Original line number Original line Diff line number Diff line Loading @@ -28,10 +28,28 @@ import java.util.Date; import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal; /** /** * This provides the required parameters needed for initializing the KeyPair * This provides the required parameters needed for initializing the * generator that works with * {@code KeyPairGenerator} that works with <a href="{@docRoot} * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore * guide/topics/security/keystore.html">Android KeyStore facility</a>. The * facility</a>. * 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 * @hide */ */ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { Loading Loading @@ -74,6 +92,7 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { * period * period * @throws IllegalArgumentException when any argument is {@code null} or * @throws IllegalArgumentException when any argument is {@code null} or * {@code endDate} is before {@code startDate}. * {@code endDate} is before {@code startDate}. * @hide should be built with AndroidKeyPairGeneratorSpecBuilder */ */ public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias, public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias, X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) { X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) { Loading Loading @@ -142,4 +161,121 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { Date getEndDate() { Date getEndDate() { return mEndDate; 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); } } } } keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java +20 −0 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,26 @@ public class AndroidKeyPairGeneratorSpecTest extends AndroidTestCase { assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); } } public void testBuilder_Success() throws Exception { AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(getContext()) .setAlias(TEST_ALIAS_1) .setSubject(TEST_DN_1) .setSerialNumber(SERIAL_1) .setStartDate(NOW) .setEndDate(NOW_PLUS_10_YEARS) .build(); assertEquals("Context should be the one specified", getContext(), spec.getContext()); assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias()); assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN()); assertEquals("startDate should be the one specified", NOW, spec.getStartDate()); assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); } public void testConstructor_NullContext_Failure() throws Exception { public void testConstructor_NullContext_Failure() throws Exception { try { try { new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW, new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW, Loading Loading
keystore/java/android/security/AndroidKeyPairGeneratorSpec.java +140 −4 Original line number Original line Diff line number Diff line Loading @@ -28,10 +28,28 @@ import java.util.Date; import javax.security.auth.x500.X500Principal; import javax.security.auth.x500.X500Principal; /** /** * This provides the required parameters needed for initializing the KeyPair * This provides the required parameters needed for initializing the * generator that works with * {@code KeyPairGenerator} that works with <a href="{@docRoot} * <a href="{@docRoot}guide/topics/security/keystore.html">Android KeyStore * guide/topics/security/keystore.html">Android KeyStore facility</a>. The * facility</a>. * 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 * @hide */ */ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { Loading Loading @@ -74,6 +92,7 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { * period * period * @throws IllegalArgumentException when any argument is {@code null} or * @throws IllegalArgumentException when any argument is {@code null} or * {@code endDate} is before {@code startDate}. * {@code endDate} is before {@code startDate}. * @hide should be built with AndroidKeyPairGeneratorSpecBuilder */ */ public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias, public AndroidKeyPairGeneratorSpec(Context context, String keyStoreAlias, X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) { X500Principal subjectDN, BigInteger serialNumber, Date startDate, Date endDate) { Loading Loading @@ -142,4 +161,121 @@ public class AndroidKeyPairGeneratorSpec implements AlgorithmParameterSpec { Date getEndDate() { Date getEndDate() { return mEndDate; 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); } } } }
keystore/tests/src/android/security/AndroidKeyPairGeneratorSpecTest.java +20 −0 Original line number Original line Diff line number Diff line Loading @@ -53,6 +53,26 @@ public class AndroidKeyPairGeneratorSpecTest extends AndroidTestCase { assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); } } public void testBuilder_Success() throws Exception { AndroidKeyPairGeneratorSpec spec = new AndroidKeyPairGeneratorSpec.Builder(getContext()) .setAlias(TEST_ALIAS_1) .setSubject(TEST_DN_1) .setSerialNumber(SERIAL_1) .setStartDate(NOW) .setEndDate(NOW_PLUS_10_YEARS) .build(); assertEquals("Context should be the one specified", getContext(), spec.getContext()); assertEquals("Alias should be the one specified", TEST_ALIAS_1, spec.getKeystoreAlias()); assertEquals("subjectDN should be the one specified", TEST_DN_1, spec.getSubjectDN()); assertEquals("startDate should be the one specified", NOW, spec.getStartDate()); assertEquals("endDate should be the one specified", NOW_PLUS_10_YEARS, spec.getEndDate()); } public void testConstructor_NullContext_Failure() throws Exception { public void testConstructor_NullContext_Failure() throws Exception { try { try { new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW, new AndroidKeyPairGeneratorSpec(null, TEST_ALIAS_1, TEST_DN_1, SERIAL_1, NOW, Loading