diff options
author | Prashant Patil <patilprashant@google.com> | 2022-05-11 16:19:41 +0000 |
---|---|---|
committer | Prashant Patil <patilprashant@google.com> | 2022-05-20 14:38:33 +0000 |
commit | 895800cbee0c00dd89fa7391d233ee8db3ab08f3 (patch) | |
tree | f8e96d8b289bf1bc179c396387354846fe6de9a6 | |
parent | 31cc0fa7a53b932d3481560a3692cbc24cf8824a (diff) | |
download | wycheproof-895800cbee0c00dd89fa7391d233ee8db3ab08f3.tar.gz |
KeyStore: Remaining wycheproof tests
Included remaining Wycheproof test classes.
Below tests are getting failed for some/all test vectors.
Failed Tests
JsonEcdhTest:
testSecp224r1, testSecp256r1, testSecp384r1, testSecp521r1
Reason (b/215175472): For invalid input to KeyAgreement, generic
ProviderException is thrown, expected is InvalidKeySpecException
or InvalidKeyException.
RsaOaepTest:
testRsaOaep2048Sha1Mgf1Sha1, testRsaOaep2048Sha224Mgf1Sha1,
testRsaOaep2048Sha224Mgf1Sha224, testRsaOaep2048Sha256Mgf1Sha1,
testRsaOaep2048Sha256Mgf1Sha256, testRsaOaep2048Sha384Mgf1Sha1,
testRsaOaep2048Sha384Mgf1Sha384, testRsaOaep2048Sha512Mgf1Sha1,
testRsaOaep2048Sha512Mgf1Sha512, testRsaOaep3072Sha256Mgf1Sha1,
testRsaOaep3072Sha256Mgf1Sha256, testRsaOaep3072Sha512Mgf1Sha1,
testRsaOaep3072Sha512Mgf1Sha512, testRsaOaep4096Sha256Mgf1Sha1,
testRsaOaep4096Sha256Mgf1Sha1, testRsaOaep4096Sha512Mgf1Sha1,
testRsaOaep4096Sha512Mgf1Sha512, testRsaOaepMisc
Reason 1 (b/229182999): MGF1 digest SHA-224, SHA-256, SHA-384 and SHA512 are not
supported in AndroidKeyStore yet.
Reason 2 (b/229183581): Constructing OAEPParameterSpec failed if PSource is
constructed with some value (ie. non default value)
RsaPssTest:
testEncodeDecodePublic, testDefaults, testRsaPss2048Sha256,
testRsaPss3072Sha256, testRsaPss4096Sha256, testRsaPss4096Sha512,
testRsaPss2048Sha256NoSalt, testRsaPss2048Sha512_224,
testRsaPss2048Sha512_256
Reason (b/215319125): All above tests uses RSASSA-PSS algorithm, which is not
supported by AndroidKeyStore yet.
Bug: 205680093
Related Bugs: 215175472, 229182999, 229183581, 215319125
Test: run cts -m CtsKeystoreWycheproofTestCases
Change-Id: Id5b4e3cde977b2b7f6d8d61292984bbb20c27a78
5 files changed, 192 insertions, 149 deletions
@@ -60,11 +60,6 @@ java_library_static { "keystore-cts/java/**/*.java", "keystore-cts/android/**/*.java", ], - exclude_srcs: [ - "keystore-cts/java/**/JsonEcdhTest.java", - "keystore-cts/java/**/RsaOaepTest.java", - "keystore-cts/java/**/RsaPssTest.java", - ], java_resource_dirs: ["keystore-cts/testvectors"], sdk_version: "current", libs: [ @@ -77,6 +72,8 @@ java_library_static { java_import { name: "wycheproof-gson", - visibility: ["//cts/tests/tests/keystore"], + visibility: [ + "//cts/tests/tests/keystore", + ], jars: ["keystore-cts/libs/gson-2.9.0.jar"], } diff --git a/keystore-cts/java/android/keystore/cts/util/KeyStoreUtil.java b/keystore-cts/java/android/keystore/cts/util/KeyStoreUtil.java index 798192d..ce535e7 100644 --- a/keystore-cts/java/android/keystore/cts/util/KeyStoreUtil.java +++ b/keystore-cts/java/android/keystore/cts/util/KeyStoreUtil.java @@ -42,8 +42,7 @@ import javax.security.auth.x500.X500Principal; public class KeyStoreUtil { public static KeyStore saveKeysToKeystore(String alias, PublicKey pubKey, PrivateKey privKey, - KeyProtection keyProtection) - throws Exception { + KeyProtection keyProtection) throws Exception { KeyPair keyPair = new KeyPair(pubKey, privKey); X509Certificate certificate = createCertificate(keyPair, new X500Principal("CN=Test1"), @@ -58,8 +57,7 @@ public class KeyStoreUtil { } public static KeyStore saveSecretKeyToKeystore(String alias, SecretKeySpec keySpec, - KeyProtection keyProtection) - throws Exception { + KeyProtection keyProtection) throws Exception { KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore"); keyStore.load(null); keyStore.setEntry(alias, diff --git a/keystore-cts/java/com/google/security/wycheproof/testcases/JsonEcdhTest.java b/keystore-cts/java/com/google/security/wycheproof/testcases/JsonEcdhTest.java index 5a8b877..f5b97f8 100644 --- a/keystore-cts/java/com/google/security/wycheproof/testcases/JsonEcdhTest.java +++ b/keystore-cts/java/com/google/security/wycheproof/testcases/JsonEcdhTest.java @@ -20,6 +20,7 @@ import com.google.gson.JsonObject; import java.math.BigInteger; import java.security.InvalidKeyException; import java.security.KeyFactory; +import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; @@ -27,13 +28,24 @@ import java.security.spec.ECPrivateKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.X509EncodedKeySpec; import javax.crypto.KeyAgreement; +import org.junit.After; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.Ignore; +import android.security.keystore.KeyProtection; +import android.security.keystore.KeyProperties; +import android.keystore.cts.util.KeyStoreUtil; +import android.util.Log; /** This test uses test vectors in JSON format to check implementations of ECDH. */ -@RunWith(JUnit4.class) public class JsonEcdhTest { + private static final String TAG = "JsonEcdhTest"; + private static final String EXPECTED_PROVIDER_NAME = TestUtil.EXPECTED_PROVIDER_NAME; + private static final String KEY_ALIAS_1 = "Key1"; + + @After + public void tearDown() throws Exception { + KeyStoreUtil.cleanUpKeyStore(); + } /** Convenience mehtod to get a String from a JsonObject */ protected static String getString(JsonObject object, String name) throws Exception { @@ -76,7 +88,7 @@ public class JsonEcdhTest { * ... **/ public void testEcdhComp(String filename) throws Exception { - JsonObject test = JsonUtil.getTestVectors(filename); + JsonObject test = JsonUtil.getTestVectors(this.getClass(), filename); // This test expects test vectors as defined in wycheproof/schemas/ecdh_test_schema.json. // In particular, this means that the public keys use X509 encoding. @@ -107,12 +119,19 @@ public class JsonEcdhTest { PrivateKey privKey = kf.generatePrivate(spec); X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(publicEncoded); PublicKey pubKey = kf.generatePublic(x509keySpec); - KeyAgreement ka = KeyAgreement.getInstance("ECDH"); - ka.init(privKey); - ka.doPhase(pubKey, true); + + KeyStore keyStore = KeyStoreUtil.saveKeysToKeystore(KEY_ALIAS_1, pubKey, privKey, + new KeyProtection.Builder(KeyProperties.PURPOSE_AGREE_KEY) + .build()); + KeyAgreement ka = KeyAgreement.getInstance("ECDH", EXPECTED_PROVIDER_NAME); + PrivateKey keyStorePrivateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS_1, null); + PublicKey publicKey = keyStore.getCertificate(KEY_ALIAS_1).getPublicKey(); + + ka.init(keyStorePrivateKey); + ka.doPhase(publicKey, true); String sharedHex = TestUtil.bytesToHex(ka.generateSecret()); if (result.equals("invalid")) { - System.out.println( + Log.e(TAG, "Computed ECDH with invalid parameters" + " tcId:" + tcid @@ -122,7 +141,7 @@ public class JsonEcdhTest { + sharedHex); errors++; } else if (!expectedHex.equals(sharedHex)) { - System.out.println( + Log.e(TAG, "Incorrect ECDH computation" + " tcId:" + tcid @@ -146,62 +165,72 @@ public class JsonEcdhTest { } } catch (Exception ex) { // Other exceptions typically indicate that something is wrong with the implementation. - System.out.println( + Log.e(TAG, "Test vector with tcId:" + tcid + " comment:" + comment + " throws:" + ex.toString()); errors++; } } } assertEquals(0, errors); - assertEquals(numTests, passedTests + rejectedTests + skippedTests); + assertEquals(numTests, passedTests); } @Test + @Ignore //TODO Reverify after bug b/215175472 is fixed. public void testSecp224r1() throws Exception { testEcdhComp("ecdh_secp224r1_test.json"); } @Test + @Ignore //TODO Reverify after bug b/215175472 is fixed. public void testSecp256r1() throws Exception { testEcdhComp("ecdh_secp256r1_test.json"); } @Test + @Ignore //TODO Reverify after bug b/215175472 is fixed. public void testSecp384r1() throws Exception { testEcdhComp("ecdh_secp384r1_test.json"); } @Test + @Ignore //TODO Reverify after bug b/215175472 is fixed. public void testSecp521r1() throws Exception { testEcdhComp("ecdh_secp521r1_test.json"); } @Test + @Ignore // Secp256k1 curve not supported in AndroidKeystore public void testSecp256k1() throws Exception { testEcdhComp("ecdh_secp256k1_test.json"); } @Test + @Ignore // Brainpool curves are not supported in AndroidKeystore public void testBrainpoolP224r1() throws Exception { testEcdhComp("ecdh_brainpoolP224r1_test.json"); } @Test + @Ignore // Brainpool curves are not supported in AndroidKeystore public void testBrainpoolP256r1() throws Exception { testEcdhComp("ecdh_brainpoolP256r1_test.json"); } @Test + @Ignore // Brainpool curves are not supported in AndroidKeystore public void testBrainpoolP320r1() throws Exception { testEcdhComp("ecdh_brainpoolP320r1_test.json"); } @Test + @Ignore // Brainpool curves are not supported in AndroidKeystore public void testBrainpoolP384r1() throws Exception { testEcdhComp("ecdh_brainpoolP384r1_test.json"); } @Test + @Ignore // Brainpool curves are not supported in AndroidKeystore public void testBrainpoolP512r1() throws Exception { testEcdhComp("ecdh_brainpoolP512r1_test.json"); } diff --git a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaOaepTest.java b/keystore-cts/java/com/google/security/wycheproof/testcases/RsaOaepTest.java index 201dfbc..4fd12cb 100644 --- a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaOaepTest.java +++ b/keystore-cts/java/com/google/security/wycheproof/testcases/RsaOaepTest.java @@ -18,28 +18,59 @@ import static org.junit.Assert.assertTrue; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import java.math.BigInteger; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.KeyFactory; +import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.MGF1ParameterSpec; import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import javax.crypto.spec.OAEPParameterSpec; import javax.crypto.spec.PSource; +import org.junit.After; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.Ignore; +import android.security.keystore.KeyProtection; +import android.security.keystore.KeyProperties; +import android.keystore.cts.util.KeyStoreUtil; +import android.text.TextUtils; +import android.util.Log; /** * Checks implementations of RSA-OAEP. */ -@RunWith(JUnit4.class) public class RsaOaepTest { + private static final String TAG = "RsaOaepTest"; + private static final String EXPECTED_PROVIDER_NAME = TestUtil.EXPECTED_CRYPTO_OP_PROVIDER_NAME; + private static final String KEY_ALIAS_1 = "TestKey"; + + @After + public void tearDown() throws Exception { + KeyStoreUtil.cleanUpKeyStore(); + } + + private static PrivateKey saveKeyPairToKeystoreAndReturnPrivateKey(PublicKey pubKey, + PrivateKey privKey) throws Exception { + return (PrivateKey) KeyStoreUtil.saveKeysToKeystore(KEY_ALIAS_1, pubKey, privKey, + new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN | + KeyProperties.PURPOSE_VERIFY | + KeyProperties.PURPOSE_ENCRYPT | + KeyProperties.PURPOSE_DECRYPT) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, + KeyProperties.ENCRYPTION_PADDING_RSA_OAEP) + .setDigests(KeyProperties.DIGEST_SHA1, KeyProperties.DIGEST_SHA224, + KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384, + KeyProperties.DIGEST_SHA512) + .build()) + .getKey(KEY_ALIAS_1, null); + } /** * A list of algorithm names for RSA-OAEP. @@ -59,19 +90,19 @@ public class RsaOaepTest { protected static void printParameters(AlgorithmParameterSpec params) { if (params instanceof OAEPParameterSpec) { OAEPParameterSpec oaepParams = (OAEPParameterSpec) params; - System.out.println("OAEPParameterSpec"); - System.out.println("digestAlgorithm:" + oaepParams.getDigestAlgorithm()); - System.out.println("mgfAlgorithm:" + oaepParams.getMGFAlgorithm()); + Log.d(TAG, "OAEPParameterSpec"); + Log.d(TAG, "digestAlgorithm:" + oaepParams.getDigestAlgorithm()); + Log.d(TAG, "mgfAlgorithm:" + oaepParams.getMGFAlgorithm()); printParameters(oaepParams.getMGFParameters()); } else if (params instanceof MGF1ParameterSpec) { MGF1ParameterSpec mgf1Params = (MGF1ParameterSpec) params; - System.out.println("MGF1ParameterSpec"); - System.out.println("digestAlgorithm:" + mgf1Params.getDigestAlgorithm()); + Log.d(TAG, "MGF1ParameterSpec"); + Log.d(TAG, "digestAlgorithm:" + mgf1Params.getDigestAlgorithm()); } else { - System.out.println(params.toString()); - } + Log.d(TAG, params.toString()); + } } - + /** * This is not a real test. The JCE algorithm names only specify one hash algorithm. But OAEP * uses two hases. One hash algorithm is used to hash the labels. The other hash algorithm is @@ -79,7 +110,7 @@ public class RsaOaepTest { * * <p>Different provider use different default values for the hash function that is not specified * in the algorithm name. Jdk uses mgfsha1 as default. BouncyCastle and Conscrypt use the same - * hash for labels and mgf. Every provider allows to specify all the parameters using + * hash for labels and mgf. Every provider allows to specify all the parameters using * an OAEPParameterSpec instance. * * <p>This test simply tries a number of algorithm names for RSA-OAEP and prints the OAEP @@ -104,15 +135,11 @@ public class RsaOaepTest { X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(TestUtil.hexToBytes(pubKey)); PublicKey key = kf.generatePublic(x509keySpec); for (String oaepName : OaepAlgorithmNames) { - try { - Cipher c = Cipher.getInstance(oaepName); + Cipher c = Cipher.getInstance(oaepName, EXPECTED_PROVIDER_NAME); c.init(Cipher.ENCRYPT_MODE, key); - System.out.println("Algorithm " + oaepName + " uses the following defaults"); + Log.d(TAG, "Algorithm " + oaepName + " uses the following defaults"); AlgorithmParameters params = c.getParameters(); printParameters(params.getParameterSpec(OAEPParameterSpec.class)); - } catch (NoSuchAlgorithmException ex) { - continue; - } } } @@ -140,7 +167,11 @@ public class RsaOaepTest { kf = KeyFactory.getInstance("RSA"); byte[] encoded = TestUtil.hexToBytes(getString(object, "privateKeyPkcs8")); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded); - return kf.generatePrivate(keySpec); + PrivateKey intermediateKey = kf.generatePrivate(keySpec); + BigInteger modulus = new BigInteger(TestUtil.hexToBytes(object.get("n").getAsString())); + BigInteger exponent = new BigInteger(TestUtil.hexToBytes(object.get("e").getAsString())); + PublicKey pubKey = kf.generatePublic(new RSAPublicKeySpec(modulus, exponent)); + return saveKeyPairToKeystoreAndReturnPrivateKey(pubKey, intermediateKey); } protected static String getOaepAlgorithmName(JsonObject group) throws Exception { @@ -150,18 +181,18 @@ public class RsaOaepTest { } protected static OAEPParameterSpec getOaepParameters(JsonObject group, - JsonObject test) throws Exception { + JsonObject test) throws Exception { String sha = getString(group, "sha"); String mgf = getString(group, "mgf"); String mgfSha = getString(group, "mgfSha"); PSource p = PSource.PSpecified.DEFAULT; - if (test.has("label")) { + if (test.has("label") && !TextUtils.isEmpty(getString(test, "label"))) { p = new PSource.PSpecified(getBytes(test, "label")); } - return new OAEPParameterSpec(sha, mgf, new MGF1ParameterSpec(mgfSha), p); + return new OAEPParameterSpec(sha, mgf, new MGF1ParameterSpec(mgfSha), p); } - /** + /** * Tests the signature verification with test vectors in a given JSON file. * * <p> Example format for test vectors @@ -171,7 +202,7 @@ public class RsaOaepTest { * ... * "testGroups" : [ * { - * "d" : "...", + * "d" : "...", * "e" : "10001", * "n" : "...", * "keysize" : 2048, @@ -205,22 +236,21 @@ public class RsaOaepTest { **/ public void testOaep(String filename, boolean allowSkippingKeys) throws Exception { - JsonObject test = JsonUtil.getTestVectors(filename); + JsonObject test = JsonUtil.getTestVectors(this.getClass(), filename); // Compares the expected and actual JSON schema of the test vector file. // Mismatched JSON schemas will likely lead to a test failure. String generatorVersion = getString(test, "generatorVersion"); String expectedSchema = "rsaes_oaep_decrypt_schema.json"; String actualSchema = getString(test, "schema"); - if (!expectedSchema.equals(actualSchema)) { - System.out.println( + assertTrue( "Expecting test vectors with schema " + expectedSchema + " found vectors with schema " + actualSchema + " generatorVersion:" - + generatorVersion); - } + + generatorVersion, + expectedSchema.equals(actualSchema)); int numTests = test.get("numberOfTests").getAsInt(); int cntTests = 0; @@ -228,18 +258,9 @@ public class RsaOaepTest { int skippedKeys = 0; for (JsonElement g : test.getAsJsonArray("testGroups")) { JsonObject group = g.getAsJsonObject(); - PrivateKey key; - try { - key = getPrivateKey(group); - } catch (GeneralSecurityException ex) { - skippedKeys++; - if (!allowSkippingKeys) { - System.out.printf("Key generation throws:%s\n", ex.toString()); - } - continue; - } + PrivateKey key = getPrivateKey(group); String algorithm = getOaepAlgorithmName(group); - Cipher decrypter = Cipher.getInstance(algorithm); + Cipher decrypter = Cipher.getInstance(algorithm, EXPECTED_PROVIDER_NAME); for (JsonElement t : group.getAsJsonArray("tests")) { cntTests++; JsonObject testcase = t.getAsJsonObject(); @@ -249,17 +270,17 @@ public class RsaOaepTest { byte[] ciphertext = getBytes(testcase, "ct"); String ciphertextHex = TestUtil.bytesToHex(ciphertext); String result = getString(testcase, "result"); - decrypter.init(Cipher.DECRYPT_MODE, key, params); byte[] decrypted = null; try { + decrypter.init(Cipher.DECRYPT_MODE, key, params); decrypted = decrypter.doFinal(ciphertext); } catch (GeneralSecurityException ex) { decrypted = null; } catch (Exception ex) { // Other exceptions (i.e. unchecked exceptions) are considered as error // since a third party should never be able to cause such exceptions. - System.out.printf("Decryption throws %s. filename:%s tcId:%d ct:%s\n", - ex.toString(), filename, tcid, ciphertextHex); + Log.e(TAG, String.format("Decryption throws %s. filename:%s tcId:%d ct:%s\n", + ex.toString(), filename, tcid, ciphertextHex)); decrypted = null; // TODO(bleichen): BouncyCastle throws some non-conforming exceptions. // For the moment we do not count this as a problem to avoid that @@ -267,21 +288,21 @@ public class RsaOaepTest { // errors++; } if (decrypted == null && result.equals("valid")) { - System.out.printf( - "Valid ciphertext not decrypted. filename:%s tcId:%d ct:%s\n", - filename, tcid, ciphertextHex); + Log.e(TAG, + String.format("Valid ciphertext not decrypted. filename:%s tcId:%d ct:%s\n", + filename, tcid, ciphertextHex)); errors++; } else if (decrypted != null) { String decryptedHex = TestUtil.bytesToHex(decrypted); if (result.equals("invalid")) { - System.out.printf( - "Invalid ciphertext decrypted. filename:%s tcId:%d expected:%s decrypted:%s\n", - filename, tcid, messageHex, decryptedHex); + Log.e(TAG, + String.format("Invalid ciphertext decrypted. filename:%s tcId:%d expected:%s decrypted:%s\n", + filename, tcid, messageHex, decryptedHex)); errors++; } else if (!decryptedHex.equals(messageHex)) { - System.out.printf( - "Incorrect decryption. filename:%s tcId:%d expected:%s decrypted:%s\n", - filename, tcid, messageHex, decryptedHex); + Log.e(TAG, + String.format("Incorrect decryption. filename:%s tcId:%d expected:%s decrypted:%s\n", + filename, tcid, messageHex, decryptedHex)); errors++; } } @@ -289,7 +310,7 @@ public class RsaOaepTest { } assertEquals(0, errors); if (skippedKeys > 0) { - System.out.println("RSAES-OAEP: file:" + filename + " skipped key:" + skippedKeys); + Log.d(TAG, "RSAES-OAEP: file:" + filename + " skipped key:" + skippedKeys); assertTrue(allowSkippingKeys); } else { assertEquals(numTests, cntTests); @@ -297,94 +318,111 @@ public class RsaOaepTest { } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha1Mgf1Sha1() throws Exception { testOaep("rsa_oaep_2048_sha1_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha224Mgf1Sha1() throws Exception { testOaep("rsa_oaep_2048_sha224_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha224Mgf1Sha224() throws Exception { testOaep("rsa_oaep_2048_sha224_mgf1sha224_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha256Mgf1Sha1() throws Exception { testOaep("rsa_oaep_2048_sha256_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha256Mgf1Sha256() throws Exception { testOaep("rsa_oaep_2048_sha256_mgf1sha256_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha384Mgf1Sha1() throws Exception { testOaep("rsa_oaep_2048_sha384_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha384Mgf1Sha384() throws Exception { testOaep("rsa_oaep_2048_sha384_mgf1sha384_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha512Mgf1Sha1() throws Exception { testOaep("rsa_oaep_2048_sha512_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep2048Sha512Mgf1Sha512() throws Exception { testOaep("rsa_oaep_2048_sha512_mgf1sha512_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep3072Sha256Mgf1Sha1() throws Exception { testOaep("rsa_oaep_3072_sha256_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep3072Sha256Mgf1Sha256() throws Exception { testOaep("rsa_oaep_3072_sha256_mgf1sha256_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep3072Sha512Mgf1Sha1() throws Exception { testOaep("rsa_oaep_3072_sha512_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep3072Sha512Mgf1Sha512() throws Exception { testOaep("rsa_oaep_3072_sha512_mgf1sha512_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep4096Sha256Mgf1Sha1() throws Exception { testOaep("rsa_oaep_4096_sha256_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep4096Sha256Mgf1Sha256() throws Exception { testOaep("rsa_oaep_4096_sha256_mgf1sha256_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep4096Sha512Mgf1Sha1() throws Exception { testOaep("rsa_oaep_4096_sha512_mgf1sha1_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaep4096Sha512Mgf1Sha512() throws Exception { testOaep("rsa_oaep_4096_sha512_mgf1sha512_test.json", false); } @Test + @Ignore //TODO Reverify after bugs b/229182999 and b/229183581 are fixed. public void testRsaOaepMisc() throws Exception { testOaep("rsa_oaep_misc_test.json", false); } - } diff --git a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaPssTest.java b/keystore-cts/java/com/google/security/wycheproof/testcases/RsaPssTest.java index 8868c23..b9a0a72 100644 --- a/keystore-cts/java/com/google/security/wycheproof/testcases/RsaPssTest.java +++ b/keystore-cts/java/com/google/security/wycheproof/testcases/RsaPssTest.java @@ -15,11 +15,10 @@ package com.google.security.wycheproof; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertFalse; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest; -import com.google.security.wycheproof.WycheproofRunner.ProviderType; import java.lang.reflect.Constructor; import java.math.BigInteger; import java.security.AlgorithmParameters; @@ -27,6 +26,7 @@ import java.security.GeneralSecurityException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.PublicKey; import java.security.Signature; @@ -38,21 +38,23 @@ import java.security.spec.RSAKeyGenParameterSpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashSet; import java.util.Set; +import org.junit.After; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; +import org.junit.Ignore; +import android.util.Log; /** * Tests for RSA-PSS. */ -@RunWith(JUnit4.class) public class RsaPssTest { + private static final String TAG = "RsaPssTest"; + private static final String EXPECTED_PROVIDER_NAME = TestUtil.EXPECTED_CRYPTO_OP_PROVIDER_NAME; /** * Returns an AlgorithmParameterSpec for generating a RSASSA-PSS key, * which include the PSSParameters. * Requires jdk11. - * + * * @param keySizeInBits the size of the modulus in bits. * @param sha the name of the hash function for hashing the input (e.g. "SHA-256") * @param mgf the name of the mask generating function (typically "MGF1") @@ -85,55 +87,37 @@ public class RsaPssTest { /** * Tries encoding and decoding of RSASSA-PSS keys generated with RSASSA-PSS. - * + * * RSASSA-PSS keys contain the PSSParameters, hence their encodings are * somewhat different than plain RSA keys. */ - @NoPresubmitTest( - providers = {ProviderType.OPENJDK}, - bugs = {"b/120406853"} - ) @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testEncodeDecodePublic() throws Exception { int keySizeInBits = 2048; - PublicKey pub; - try { - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSASSA-PSS"); - keyGen.initialize(keySizeInBits); - KeyPair keypair = keyGen.genKeyPair(); - pub = keypair.getPublic(); - } catch (NoSuchAlgorithmException ex) { - System.out.println("Key generation for RSASSA-PSS is not supported."); - return; - } + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSASSA-PSS", EXPECTED_PROVIDER_NAME); + keyGen.initialize(keySizeInBits); + KeyPair keypair = keyGen.genKeyPair(); + PublicKey pub = keypair.getPublic(); byte[] encoded = pub.getEncoded(); assertEquals( "The test assumes that the public key is in X.509 format", "X.509", pub.getFormat()); - System.out.println("Generated RSA-PSS key"); - System.out.println(TestUtil.bytesToHex(encoded)); KeyFactory kf = KeyFactory.getInstance("RSASSA-PSS"); X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded); kf.generatePublic(spec); - + // Tries to generate another pair or keys. This time the generator is given an // RSAKeyGenParameterSpec containing the key size an the PSS parameters. String sha = "SHA-256"; String mgf = "MGF1"; int saltLength = 20; - try { - RSAKeyGenParameterSpec params = - getPssAlgorithmParameters(keySizeInBits, sha, mgf, sha, saltLength); - KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSASSA-PSS"); - keyGen.initialize(params); - KeyPair keypair = keyGen.genKeyPair(); - pub = keypair.getPublic(); - } catch (NoSuchAlgorithmException | NoSuchMethodException ex) { - System.out.println("Key generation for RSASSA-PSS is not supported."); - return; - } + RSAKeyGenParameterSpec params = + getPssAlgorithmParameters(keySizeInBits, sha, mgf, sha, saltLength); + KeyPairGenerator keyGen1 = KeyPairGenerator.getInstance("RSASSA-PSS", EXPECTED_PROVIDER_NAME); + keyGen1.initialize(params); + KeyPair keypair1 = keyGen1.genKeyPair(); + pub = keypair1.getPublic(); byte[] encoded2 = pub.getEncoded(); - System.out.println("Generated RSA-PSS key with PSS parameters"); - System.out.println(TestUtil.bytesToHex(encoded2)); X509EncodedKeySpec spec2 = new X509EncodedKeySpec(encoded2); kf.generatePublic(spec2); } @@ -171,14 +155,8 @@ public class RsaPssTest { kf = KeyFactory.getInstance("RSA"); X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(TestUtil.hexToBytes(pubKey)); PublicKey key = kf.generatePublic(x509keySpec); - Signature verifier; - try { - verifier = Signature.getInstance(algorithm); - verifier.initVerify(key); - } catch (NoSuchAlgorithmException ex) { - System.out.println("Unsupported algorithm:" + algorithm); - return; - } + Signature verifier = Signature.getInstance(algorithm, EXPECTED_PROVIDER_NAME); + verifier.initVerify(key); AlgorithmParameters params = verifier.getParameters(); if (params == null) { // No defaults are specified. This is a good choice since this avoid @@ -234,6 +212,7 @@ public class RsaPssTest { * PSSParameters explicitly, and does not default to weak behaviour. */ @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testDefaults() throws Exception { testDefaultForAlgorithm("SHA1withRSAandMGF1", "SHA-1", "MGF1", "SHA-1", 20, 1); testDefaultForAlgorithm("SHA224withRSAandMGF1", "SHA-224", "MGF1", "SHA-224", 28, 1); @@ -249,7 +228,7 @@ public class RsaPssTest { testDefaultForAlgorithm("SHA3-384withRSAandMGF1", "SHA3-384", "MGF1", "SHA3-384", 48, 1); testDefaultForAlgorithm("SHA3-512withRSAandMGF1", "SHA3-512", "MGF1", "SHA3-512", 64, 1); } - + /** Convenience mehtod to get a String from a JsonObject */ protected static String getString(JsonObject object, String name) throws Exception { return object.get(name).getAsString(); @@ -265,7 +244,7 @@ public class RsaPssTest { * Oracle previously specified that algorithm names for RSA-PSS are strings like * "SHA256WITHRSAandMGF1". * See http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html - * These algorithm names fail to specify the hash function for the MGF. A cleaner solution + * These algorithm names fail to specify the hash function for the MGF. A cleaner solution * in jdk11 is to use the algorithm name "RSASSA-PSS" and specify the parameters separately. * This function simply attempts to return an algorithm name that works. * @@ -275,7 +254,7 @@ public class RsaPssTest { */ protected static String getAlgorithmName(JsonObject group) throws Exception { try { - Signature.getInstance("RSASSA-PSS"); + Signature.getInstance("RSASSA-PSS", EXPECTED_PROVIDER_NAME); return "RSASSA-PSS"; } catch (NoSuchAlgorithmException ex) { // RSASSA-PSS is not known. Try the other option. @@ -385,15 +364,14 @@ public class RsaPssTest { // the minor number if only the test vectors (but not the format) changes. // Versions meant for distribution have no status. final String expectedVersion = "0.6"; - JsonObject test = JsonUtil.getTestVectors(filename); + JsonObject test = JsonUtil.getTestVectors(this.getClass(), filename); String generatorVersion = getString(test, "generatorVersion"); - if (!generatorVersion.equals(expectedVersion)) { - System.out.println( + assertFalse( "Expecting test vectors with version " + expectedVersion + " found vectors with version " - + generatorVersion); - } + + generatorVersion, + generatorVersion.equals(expectedVersion)); int numTests = test.get("numberOfTests").getAsInt(); int cntTests = 0; int errors = 0; @@ -407,9 +385,9 @@ public class RsaPssTest { Signature verifier = null; try { key = getPublicKey(group, paramsIncluded); - verifier = Signature.getInstance(algorithm); + verifier = Signature.getInstance(algorithm, EXPECTED_PROVIDER_NAME); if (!paramsIncluded) { - PSSParameterSpec pssParams = getPSSParams(group); + PSSParameterSpec pssParams = getPSSParams(group); verifier.setParameter(pssParams); } } catch (GeneralSecurityException ex) { @@ -417,10 +395,10 @@ public class RsaPssTest { skippedKeys++; skippedAlgorithms.add(algorithm); } else { - System.out.println("Failed to generate verifier for " + algorithm + ex); + Log.e(TAG, "Failed to generate verifier for " + algorithm + ex); errors++; } - continue; + throw ex; } for (JsonElement t : group.getAsJsonArray("tests")) { cntTests++; @@ -444,7 +422,7 @@ public class RsaPssTest { } catch (Exception ex) { // Other exceptions (i.e. unchecked exceptions) are considered as error // since a third party should never be able to cause such exceptions. - System.out.println( + Log.e(TAG, "Signature verification throws " + ex.toString() + " " @@ -461,7 +439,7 @@ public class RsaPssTest { if (reason != null) { comment = " exception:" + reason; } - System.out.println( + Log.e(TAG, "Valid signature not verified. " + filename + " tcId:" @@ -471,7 +449,7 @@ public class RsaPssTest { + comment); errors++; } else if (verified && result.equals("invalid")) { - System.out.println( + Log.e(TAG, "Invalid signature verified. " + filename + " tcId:" @@ -488,7 +466,7 @@ public class RsaPssTest { // Prints some information if tests were skipped. This avoids giving // the impression that algorithms are supported. if (skippedKeys > 0 || verifiedTests == 0) { - System.out.println( + Log.d(TAG, "File:" + filename + " number of skipped keys:" @@ -496,7 +474,7 @@ public class RsaPssTest { + " verified signatures:" + verifiedTests); for (String s : skippedAlgorithms) { - System.out.println("Skipped algorithms " + s); + Log.d(TAG, "Skipped algorithms " + s); } } @@ -509,47 +487,50 @@ public class RsaPssTest { } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss2048Sha256() throws Exception { - testRsaPss("rsa_pss_2048_sha256_mgf1_32_test.json", true, false); + testRsaPss("rsa_pss_2048_sha256_mgf1_32_test.json", false, false); } - @NoPresubmitTest( - providers = {ProviderType.BOUNCY_CASTLE}, - bugs = {"b/111634359"} - ) @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss3072Sha256() throws Exception { - testRsaPss("rsa_pss_3072_sha256_mgf1_32_test.json", true, false); + testRsaPss("rsa_pss_3072_sha256_mgf1_32_test.json", false, false); } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss4096Sha256() throws Exception { - testRsaPss("rsa_pss_4096_sha256_mgf1_32_test.json", true, false); + testRsaPss("rsa_pss_4096_sha256_mgf1_32_test.json", false, false); } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss4096Sha512() throws Exception { - testRsaPss("rsa_pss_4096_sha512_mgf1_32_test.json", true, false); + testRsaPss("rsa_pss_4096_sha512_mgf1_32_test.json", false, false); } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss2048Sha256NoSalt() throws Exception { - testRsaPss("rsa_pss_2048_sha256_mgf1_0_test.json", true, false); + testRsaPss("rsa_pss_2048_sha256_mgf1_0_test.json", false, false); } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss2048Sha512_224() throws Exception { - testRsaPss("rsa_pss_2048_sha512_256_mgf1_28_test.json", true, false); + testRsaPss("rsa_pss_2048_sha512_256_mgf1_28_test.json", false, false); } @Test + @Ignore //TODO Reverify after b/215319125 is fixed. public void testRsaPss2048Sha512_256() throws Exception { - testRsaPss("rsa_pss_2048_sha512_256_mgf1_32_test.json", true, false); + testRsaPss("rsa_pss_2048_sha512_256_mgf1_32_test.json", false, false); } // BouncyCastle and Conscrypt do not support RSA-PSS Parameters in the // encoding of the key. jdk11 should support this, but as long as - // testEncodeDecodePublic fails it makes no sense to try this test. + // testEncodeDecodePublic fails it makes no sense to try this test. /* @ExcludedTest( providers = {ProviderType.BOUNCY_CASTLE, ProviderType.CONSCRYPT}, |