diff options
Diffstat (limited to 'keystore/tests/src/android')
3 files changed, 72 insertions, 56 deletions
diff --git a/keystore/tests/src/android/security/KeyStoreTest.java b/keystore/tests/src/android/security/KeyStoreTest.java index 44fb826..0b60c62 100644 --- a/keystore/tests/src/android/security/KeyStoreTest.java +++ b/keystore/tests/src/android/security/KeyStoreTest.java @@ -20,7 +20,6 @@ import android.app.Activity; import android.os.Binder; import android.os.IBinder; import android.os.Process; -import android.os.ServiceManager; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; @@ -34,13 +33,9 @@ import android.test.suitebuilder.annotation.MediumTest; import com.android.org.conscrypt.NativeConstants; import java.nio.charset.StandardCharsets; import java.util.Arrays; -import java.util.Date; import java.util.HashSet; import java.security.spec.RSAKeyGenParameterSpec; -import android.util.Log; -import android.util.Base64; - /** * Junit / Instrumentation test case for KeyStore class * diff --git a/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java index 8488acd..e5c15c5 100644 --- a/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java +++ b/keystore/tests/src/android/security/keystore/AndroidKeyPairGeneratorTest.java @@ -26,17 +26,21 @@ import android.test.AndroidTestCase; import java.io.ByteArrayInputStream; import java.math.BigInteger; import java.security.KeyPair; +import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; +import java.security.interfaces.ECKey; import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAKey; import java.security.interfaces.RSAPublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.RSAKeyGenParameterSpec; import java.text.SimpleDateFormat; +import java.util.Arrays; import java.util.Date; import javax.security.auth.x500.X500Principal; @@ -158,6 +162,26 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase { } public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception { + KeyPairGenerator generator = KeyPairGenerator.getInstance("EC", "AndroidKeyStore"); + generator.initialize(new KeyGenParameterSpec.Builder( + TEST_ALIAS_1, + KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY) + .setCertificateSubject(TEST_DN_1) + .setCertificateSerialNumber(TEST_SERIAL_1) + .setCertificateNotBefore(NOW) + .setCertificateNotAfter(NOW_PLUS_10_YEARS) + .setDigests(KeyProperties.DIGEST_SHA256) + .build()); + + final KeyPair pair = generator.generateKeyPair(); + assertNotNull("The KeyPair returned should not be null", pair); + + assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW, + NOW_PLUS_10_YEARS); + } + + public void testKeyPairGenerator_Legacy_GenerateKeyPair_EC_Unencrypted_Success() + throws Exception { mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext()) .setAlias(TEST_ALIAS_1) .setKeyType("EC") @@ -328,19 +352,40 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase { assertNotNull("The PrivateKey for the KeyPair should be not null", privKey); assertEquals(keyType, privKey.getAlgorithm()); + if ("EC".equalsIgnoreCase(keyType)) { + assertTrue("EC private key must be instanceof ECKey: " + privKey.getClass().getName(), + privKey instanceof ECKey); + assertEquals("Private and public key must have the same EC parameters", + ((ECKey) pubKey).getParams(), ((ECKey) privKey).getParams()); + } else if ("RSA".equalsIgnoreCase(keyType)) { + assertTrue("RSA private key must be instance of RSAKey: " + + privKey.getClass().getName(), + privKey instanceof RSAKey); + assertEquals("Private and public key must have the same RSA modulus", + ((RSAKey) pubKey).getModulus(), ((RSAKey) privKey).getModulus()); + } + final byte[] userCertBytes = mAndroidKeyStore.get(Credentials.USER_CERTIFICATE + alias); assertNotNull("The user certificate should exist for the generated entry", userCertBytes); final CertificateFactory cf = CertificateFactory.getInstance("X.509"); - final Certificate userCert = cf - .generateCertificate(new ByteArrayInputStream(userCertBytes)); + final Certificate userCert = + cf.generateCertificate(new ByteArrayInputStream(userCertBytes)); assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate); final X509Certificate x509userCert = (X509Certificate) userCert; + assertEquals( + "Public key used to sign certificate should have the same algorithm as in KeyPair", + pubKey.getAlgorithm(), x509userCert.getPublicKey().getAlgorithm()); + assertEquals("PublicKey used to sign certificate should match one returned in KeyPair", - pubKey, x509userCert.getPublicKey()); + pubKey, + AndroidKeyStoreProvider.getAndroidKeyStorePublicKey( + Credentials.USER_PRIVATE_KEY + alias, + x509userCert.getPublicKey().getAlgorithm(), + x509userCert.getPublicKey().getEncoded())); assertEquals("The Subject DN should be the one passed into the params", dn, x509userCert.getSubjectDN()); @@ -357,7 +402,10 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase { assertDateEquals("The notAfter date should be the one passed into the params", end, x509userCert.getNotAfter()); + // Assert that the cert's signature verifies using the public key from generated KeyPair x509userCert.verify(pubKey); + // Assert that the cert's signature verifies using the public key from the cert itself. + x509userCert.verify(x509userCert.getPublicKey()); final byte[] caCerts = mAndroidKeyStore.get(Credentials.CA_CERTIFICATE + alias); assertNull("A list of CA certificates should not exist for the generated entry", caCerts); @@ -368,6 +416,8 @@ public class AndroidKeyPairGeneratorTest extends AndroidTestCase { final byte[] pubKeyBytes = exportResult.exportData; assertNotNull("The keystore should return the public key for the generated key", pubKeyBytes); + assertTrue("Public key X.509 format should be as expected", + Arrays.equals(pubKey.getEncoded(), pubKeyBytes)); } private static void assertDateEquals(String message, Date date1, Date date2) throws Exception { diff --git a/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java index 336fa40..c3b731b 100644 --- a/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java +++ b/keystore/tests/src/android/security/keystore/AndroidKeyStoreTest.java @@ -19,38 +19,31 @@ package android.security.keystore; import com.android.org.bouncycastle.x509.X509V3CertificateGenerator; import com.android.org.conscrypt.NativeConstants; -import com.android.org.conscrypt.OpenSSLEngine; import android.security.Credentials; import android.security.KeyStore; import android.security.KeyStoreParameter; -import android.security.keymaster.ExportResult; -import android.security.keymaster.KeymasterDefs; import android.test.AndroidTestCase; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.OutputStream; import java.math.BigInteger; -import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyFactory; +import java.security.KeyPair; import java.security.KeyStore.Entry; import java.security.KeyStore.PrivateKeyEntry; import java.security.KeyStore.TrustedCertificateEntry; import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAPrivateKey; -import java.security.spec.InvalidKeySpecException; +import java.security.interfaces.ECKey; +import java.security.interfaces.RSAKey; import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; import java.util.Collection; import java.util.Date; @@ -1203,14 +1196,14 @@ public class AndroidKeyStoreTest extends AndroidTestCase { private void assertPrivateKeyEntryEquals(PrivateKeyEntry keyEntry, PrivateKey expectedKey, Certificate expectedCert, Collection<Certificate> expectedChain) throws Exception { - if (expectedKey instanceof ECPrivateKey) { + if (expectedKey instanceof ECKey) { assertEquals("Returned PrivateKey should be what we inserted", - ((ECPrivateKey) expectedKey).getParams().getCurve(), - ((ECPublicKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve()); - } else if (expectedKey instanceof RSAPrivateKey) { + ((ECKey) expectedKey).getParams().getCurve(), + ((ECKey) keyEntry.getCertificate().getPublicKey()).getParams().getCurve()); + } else if (expectedKey instanceof RSAKey) { assertEquals("Returned PrivateKey should be what we inserted", - ((RSAPrivateKey) expectedKey).getModulus(), - ((RSAPrivateKey) keyEntry.getPrivateKey()).getModulus()); + ((RSAKey) expectedKey).getModulus(), + ((RSAKey) keyEntry.getPrivateKey()).getModulus()); } assertEquals("Returned Certificate should be what we inserted", expectedCert, @@ -1263,15 +1256,14 @@ public class AndroidKeyStoreTest extends AndroidTestCase { Key key = mKeyStore.getKey(TEST_ALIAS_1, null); assertNotNull("Key should exist", key); - assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey); - - RSAPrivateKey actualKey = (RSAPrivateKey) key; + assertTrue("Should be a PrivateKey", key instanceof PrivateKey); + assertTrue("Should be a RSAKey", key instanceof RSAKey); KeyFactory keyFact = KeyFactory.getInstance("RSA"); PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1)); assertEquals("Inserted key should be same as retrieved key", - ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus()); + ((RSAKey) expectedKey).getModulus(), ((RSAKey) key).getModulus()); } public void testKeyStore_GetKey_NoPassword_Unencrypted_Success() throws Exception { @@ -1287,15 +1279,14 @@ public class AndroidKeyStoreTest extends AndroidTestCase { Key key = mKeyStore.getKey(TEST_ALIAS_1, null); assertNotNull("Key should exist", key); - assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey); - - RSAPrivateKey actualKey = (RSAPrivateKey) key; + assertTrue("Should be a PrivateKey", key instanceof PrivateKey); + assertTrue("Should be a RSAKey", key instanceof RSAKey); KeyFactory keyFact = KeyFactory.getInstance("RSA"); PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1)); assertEquals("Inserted key should be same as retrieved key", - ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus()); + ((RSAKey) expectedKey).getModulus(), ((RSAKey) key).getModulus()); } public void testKeyStore_GetKey_Certificate_Encrypted_Failure() throws Exception { @@ -1926,31 +1917,11 @@ public class AndroidKeyStoreTest extends AndroidTestCase { Date notAfter) throws Exception { final String privateKeyAlias = Credentials.USER_PRIVATE_KEY + alias; - final PrivateKey privKey; - final OpenSSLEngine engine = OpenSSLEngine.getInstance("keystore"); - try { - privKey = engine.getPrivateKeyById(privateKeyAlias); - } catch (InvalidKeyException e) { - throw new RuntimeException("Can't get key", e); - } - - ExportResult exportResult = - keyStore.exportKey(privateKeyAlias, KeymasterDefs.KM_KEY_FORMAT_X509, null, null); - assertEquals(KeyStore.NO_ERROR, exportResult.resultCode); - final byte[] pubKeyBytes = exportResult.exportData; - - final PublicKey pubKey; - try { - final KeyFactory keyFact = KeyFactory.getInstance("RSA"); - pubKey = keyFact.generatePublic(new X509EncodedKeySpec(pubKeyBytes)); - } catch (NoSuchAlgorithmException e) { - throw new IllegalStateException("Can't instantiate RSA key generator", e); - } catch (InvalidKeySpecException e) { - throw new IllegalStateException("keystore returned invalid key encoding", e); - } + KeyPair keyPair = AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore( + keyStore, privateKeyAlias); final X509V3CertificateGenerator certGen = new X509V3CertificateGenerator(); - certGen.setPublicKey(pubKey); + certGen.setPublicKey(keyPair.getPublic()); certGen.setSerialNumber(serialNumber); certGen.setSubjectDN(subjectDN); certGen.setIssuerDN(subjectDN); @@ -1958,7 +1929,7 @@ public class AndroidKeyStoreTest extends AndroidTestCase { certGen.setNotAfter(notAfter); certGen.setSignatureAlgorithm("sha1WithRSA"); - final X509Certificate cert = certGen.generate(privKey); + final X509Certificate cert = certGen.generate(keyPair.getPrivate()); return cert; } |