OSDN Git Service

Make specifying self-signed cert parameters optional.
authorAlex Klyubin <klyubin@google.com>
Tue, 14 Apr 2015 19:48:17 +0000 (12:48 -0700)
committerAlex Klyubin <klyubin@google.com>
Tue, 14 Apr 2015 19:56:17 +0000 (12:56 -0700)
This removes the need to specify the three parameters of the
self-signed certificate (serial number, subject, validity range) when
generating key pairs in AndroidKeyStore. This is achieved by
providing sensible defaults for these parameters:
* serial number: 1
* subject: CN=fake
* validity range: Jan 1 1970 to Jan 1 2048.

Bug: 18088752
Change-Id: I5df918b1ef8b26ed3ddd43828c4c78c9fa58cd43

keystore/java/android/security/KeyPairGeneratorSpec.java
keystore/tests/src/android/security/KeyPairGeneratorSpecTest.java

index 9d6701a..fce02df 100644 (file)
@@ -52,6 +52,11 @@ import javax.security.auth.x500.X500Principal;
  */
 public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
 
+    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
     private final Context mContext;
 
     private final String mKeystoreAlias;
@@ -144,22 +149,29 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
             throw new IllegalArgumentException("context == null");
         } else if (TextUtils.isEmpty(keyStoreAlias)) {
             throw new IllegalArgumentException("keyStoreAlias must not be empty");
-        } else if (subjectDN == null) {
-            throw new IllegalArgumentException("subjectDN == null");
-        } else if (serialNumber == null) {
-            throw new IllegalArgumentException("serialNumber == null");
-        } else if (startDate == null) {
-            throw new IllegalArgumentException("startDate == null");
-        } else if (endDate == null) {
-            throw new IllegalArgumentException("endDate == null");
-        } else if (endDate.before(startDate)) {
-            throw new IllegalArgumentException("endDate < startDate");
         } else if ((userAuthenticationValidityDurationSeconds < 0)
                 && (userAuthenticationValidityDurationSeconds != -1)) {
             throw new IllegalArgumentException(
                     "userAuthenticationValidityDurationSeconds must not be negative");
         }
 
+        if (subjectDN == null) {
+            subjectDN = DEFAULT_CERT_SUBJECT;
+        }
+        if (startDate == null) {
+            startDate = DEFAULT_CERT_NOT_BEFORE;
+        }
+        if (endDate == null) {
+            endDate = DEFAULT_CERT_NOT_AFTER;
+        }
+        if (serialNumber == null) {
+            serialNumber = DEFAULT_CERT_SERIAL_NUMBER;
+        }
+
+        if (endDate.before(startDate)) {
+            throw new IllegalArgumentException("endDate < startDate");
+        }
+
         mContext = context;
         mKeystoreAlias = keyStoreAlias;
         mKeyType = keyType;
@@ -559,6 +571,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         /**
          * Sets the subject used for the self-signed certificate of the
          * generated key pair.
+         *
+         * <p>The subject must be specified on API Level
+         * {@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) {
             if (subject == null) {
@@ -571,6 +587,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         /**
          * Sets the serial number used for the self-signed certificate of the
          * generated key pair.
+         *
+         * <p>The serial number must be specified on API Level
+         * {@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) {
             if (serialNumber == null) {
@@ -583,6 +603,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         /**
          * Sets the start of the validity period for the self-signed certificate
          * of the generated key pair.
+         *
+         * <p>The date must be specified on API Level
+         * {@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) {
             if (startDate == null) {
@@ -595,6 +619,10 @@ public final class KeyPairGeneratorSpec implements AlgorithmParameterSpec {
         /**
          * Sets the end of the validity period for the self-signed certificate
          * of the generated key pair.
+         *
+         * <p>The date must be specified on API Level
+         * {@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) {
             if (endDate == null) {
index bc8dd13..681a9ff 100644 (file)
@@ -24,6 +24,11 @@ import java.util.Date;
 import javax.security.auth.x500.X500Principal;
 
 public class KeyPairGeneratorSpecTest extends AndroidTestCase {
+    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1980
+    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
     private static final String TEST_ALIAS_1 = "test1";
 
     private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
@@ -105,46 +110,37 @@ public class KeyPairGeneratorSpecTest extends AndroidTestCase {
         }
     }
 
-    public void testConstructor_NullSubjectDN_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when subjectDN is null");
-        } catch (IllegalArgumentException success) {
-        }
+    public void testConstructor_NullSubjectDN_Success() throws Exception {
+        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
+                getContext(), TEST_ALIAS_1, "RSA", 1024, null, null, SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS, 0);
+        assertEquals(DEFAULT_CERT_SUBJECT, spec.getSubjectDN());
     }
 
-    public void testConstructor_NullSerial_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
-                    NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when startDate is null");
-        } catch (IllegalArgumentException success) {
-        }
+    public void testConstructor_NullSerial_Success() throws Exception {
+        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
+                getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, null, NOW,
+                NOW_PLUS_10_YEARS, 0);
+        assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getSerialNumber());
     }
 
-    public void testConstructor_NullStartDate_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    null, NOW_PLUS_10_YEARS, 0);
-            fail("Should throw IllegalArgumentException when startDate is null");
-        } catch (IllegalArgumentException success) {
-        }
+    public void testConstructor_NullStartDate_Success() throws Exception {
+        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
+                getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, null,
+                NOW_PLUS_10_YEARS, 0);
+        assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getStartDate());
     }
 
-    public void testConstructor_NullEndDate_Failure() throws Exception {
-        try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    NOW, null, 0);
-            fail("Should throw IllegalArgumentException when keystoreAlias is null");
-        } catch (IllegalArgumentException success) {
-        }
+    public void testConstructor_NullEndDate_Success() throws Exception {
+        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec(
+                getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1, NOW, null, 0);
+        assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getEndDate());
     }
 
     public void testConstructor_EndBeforeStart_Failure() throws Exception {
         try {
-            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1, SERIAL_1,
-                    NOW_PLUS_10_YEARS, NOW, 0);
+            new KeyPairGeneratorSpec(getContext(), TEST_ALIAS_1, "RSA", 1024, null, TEST_DN_1,
+                    SERIAL_1, NOW_PLUS_10_YEARS, NOW, 0);
             fail("Should throw IllegalArgumentException when end is before start");
         } catch (IllegalArgumentException success) {
         }