Don't fail if self-signed certificate can't be signed.

This makes Android Keystore's KeyPairGenerator fall back to generating
a self-signed certificate with an invalid/fake signature when the
attempt to generate a self-signed certificate with a valid signature
fails.

There is a growing number of reasons/authorizations due to which the
generated private key cannot be used to sign the self-signed
certificate. It's safer for KeyPairGenerator to succeed than to fail.

Bug: 22033161
Change-Id: I1ecbd421346166bfd536b5cfbaea169b11f0b1c8
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index f7ff07f..02afa0a 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -515,15 +515,23 @@
             return generateSelfSignedCertificateWithFakeSignature(publicKey);
         } else {
             // Key can be used to sign a certificate
-            return generateSelfSignedCertificateWithValidSignature(
-                    privateKey, publicKey, signatureAlgorithm);
+            try {
+                return generateSelfSignedCertificateWithValidSignature(
+                        privateKey, publicKey, signatureAlgorithm);
+            } catch (Exception e) {
+                // Failed to generate the self-signed certificate with valid signature. Fall back
+                // to generating a self-signed certificate with a fake signature. This is done for
+                // all exception types because we prefer key pair generation to succeed and end up
+                // producing a self-signed certificate with an invalid signature to key pair
+                // generation failing.
+                return generateSelfSignedCertificateWithFakeSignature(publicKey);
+            }
         }
     }
 
     @SuppressWarnings("deprecation")
     private X509Certificate generateSelfSignedCertificateWithValidSignature(
-            PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm)
-                    throws Exception {
+            PrivateKey privateKey, PublicKey publicKey, String signatureAlgorithm) throws Exception {
         final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
         certGen.setPublicKey(publicKey);
         certGen.setSerialNumber(mSpec.getCertificateSerialNumber());
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index 3d23399..919dd48 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -71,6 +71,8 @@
  * <li>{@link KeyProperties#PURPOSE_SIGN},</li>
  * <li>operation without requiring the user to be authenticated (see
  * {@link Builder#setUserAuthenticationRequired(boolean)}),</li>
+ * <li>signing/origination at this moment in time (see {@link Builder#setKeyValidityStart(Date)}
+ * and {@link Builder#setKeyValidityForOriginationEnd(Date)}),</li>
  * <li>suitable digest or {@link KeyProperties#DIGEST_NONE},</li>
  * <li>(RSA keys only) padding scheme {@link KeyProperties#SIGNATURE_PADDING_RSA_PKCS1} or
  * {@link KeyProperties#ENCRYPTION_PADDING_NONE}.</li>