aboutsummaryrefslogtreecommitdiff
path: root/keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java')
-rw-r--r--keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java966
1 files changed, 966 insertions, 0 deletions
diff --git a/keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java b/keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java
new file mode 100644
index 0000000..21bf0d5
--- /dev/null
+++ b/keystore-cts/java/com/google/security/wycheproof/testcases/JsonSignatureTest.java
@@ -0,0 +1,966 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.security.wycheproof;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.security.wycheproof.WycheproofRunner.ExcludedTest;
+import com.google.security.wycheproof.WycheproofRunner.NoPresubmitTest;
+import com.google.security.wycheproof.WycheproofRunner.ProviderType;
+import java.security.GeneralSecurityException;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.HashSet;
+import java.util.Set;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * This test uses test vectors in JSON format to check digital signature schemes. There are still a
+ * lot of open questions, e.g. the format for the test vectors is not yet finalized. Therefore, we
+ * are not integrating the tests here into other tests
+ */
+@RunWith(JUnit4.class)
+public class JsonSignatureTest {
+
+ /**
+ * Defines the format of the signatures. RAW is used when the signature scheme already
+ * defines an encoding (e.g. this is used for RSA signatures).
+ */
+ public enum Format { RAW, ASN, P1363 };
+
+ /** Convenience method to get a String from a JsonObject */
+ protected static String getString(JsonObject object, String name) {
+ return object.get(name).getAsString();
+ }
+
+ /** Convenience method to get a byte array from a JsonObject */
+ protected static byte[] getBytes(JsonObject object, String name) throws Exception {
+ return JsonUtil.asByteArray(object.get(name));
+ }
+
+ /**
+ * Convert hash names, so that they can be used in an algorithm name for a signature. The
+ * algorithm names used in JCA are a bit inconsequential. E.g. a dash is necessary for message
+ * digests (e.g. "SHA-256") but are not used in the corresponding names for digital signatures
+ * (e.g. "SHA256WITHECDSA"). Providers sometimes use distinct algorithm names for the same
+ * cryptographic primitive. On the other hand, the dash remains for SHA-3. Hence, the correct
+ * name for ECDSA with SHA3-256 is "SHA3-256WithECDSA".
+ *
+ * <p>See https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html
+ *
+ * @param md the name of a message digest
+ * @return the name of the message digest when used in a signature algorithm.
+ */
+ protected static String convertMdName(String md) {
+ if (md.equalsIgnoreCase("SHA-1")) {
+ return "SHA1";
+ } else if (md.equalsIgnoreCase("SHA-224")) {
+ return "SHA224";
+ } else if (md.equalsIgnoreCase("SHA-256")) {
+ return "SHA256";
+ } else if (md.equalsIgnoreCase("SHA-384")) {
+ return "SHA384";
+ } else if (md.equalsIgnoreCase("SHA-512")) {
+ return "SHA512";
+ } else if (md.equalsIgnoreCase("SHA-512/224")) {
+ return "SHA512/224";
+ } else if (md.equalsIgnoreCase("SHA-512/256")) {
+ return "SHA512/256";
+ }
+ return md;
+ }
+
+ /**
+ * Returns an instance of java.security.Signature for an algorithm name, a digest name and a
+ * signature format.
+ *
+ * @param md the name of the message digest (e.g. "SHA-256")
+ * @param signatureAlgorithm the name of the signature algorithm (e.g. "ECDSA")
+ * @param signatureFormat the format of the signatures.
+ * @return an instance of java.security.Signature if the algorithm is known
+ * @throws NoSuchAlgorithmException if the algorithm is not known
+ */
+ protected static Signature getSignatureInstance(
+ JsonObject group, String signatureAlgorithm, Format signatureFormat)
+ throws NoSuchAlgorithmException {
+ String md = "";
+ if (group.has("sha")) {
+ md = convertMdName(getString(group, "sha"));
+ }
+ if (signatureAlgorithm.equals("ECDSA") || signatureAlgorithm.equals("DSA")) {
+ if (signatureFormat == Format.ASN) {
+ return Signature.getInstance(md + "WITH" + signatureAlgorithm);
+ } else if (signatureFormat == Format.P1363) {
+ // The algorithm names for signature schemes with P1363 format have distinct names
+ // in distinct providers. This is mainly the case since the P1363 format has only
+ // been added in jdk11, while providers such as BouncyCastle added the format earlier
+ // than that. Hence the code below just tries known algorithm names.
+ try {
+ String jdkName = md + "WITH" + signatureAlgorithm + "inP1363Format";
+ return Signature.getInstance(jdkName);
+ } catch (NoSuchAlgorithmException ex) {
+ // jdkName is not known.
+ }
+ try {
+ String bcName = md + "WITHPLAIN-" + signatureAlgorithm;
+ return Signature.getInstance(bcName);
+ } catch (NoSuchAlgorithmException ex) {
+ // bcName is not known.
+ }
+ }
+ } else if (signatureAlgorithm.equals("RSA")) {
+ if (signatureFormat == Format.RAW) {
+ return Signature.getInstance(md + "WITH" + signatureAlgorithm);
+ }
+ } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
+ if (signatureFormat == Format.RAW) {
+ // http://openjdk.java.net/jeps/339
+ try {
+ return Signature.getInstance(signatureAlgorithm);
+ } catch (NoSuchAlgorithmException ex) {
+ // signatureAlgorithm is not known.
+ }
+ // An alternative name (e.g. used by BouncyCastle) is "EDDSA".
+ try {
+ return Signature.getInstance("EDDSA");
+ } catch (NoSuchAlgorithmException ex) {
+ // "EDDSA" is not known either.
+ }
+ }
+ }
+ throw new NoSuchAlgorithmException(
+ "Algorithm "
+ + signatureAlgorithm
+ + " with format "
+ + signatureFormat
+ + " is not supported");
+ }
+
+ /**
+ * Returns the expected JSON schema for a given test or "" if the schema is undefined.
+ * The purpose of this function is to perform a sanity test with the goal to recognize
+ * incorrect test setups.
+ * @param signatureAlgorithm the signataure algorithm (e.g. "ECDSA")
+ * @param signatureFormat the format of the signatures
+ * @param verify true if verification is tested, false if signature generations is tested.
+ */
+ protected static String expectedSchema(String signatureAlgorithm, Format signatureFormat,
+ boolean verify) {
+ if (verify) {
+ if (signatureAlgorithm.equals("ECDSA")) {
+ switch (signatureFormat) {
+ case ASN: return "ecdsa_verify_schema.json";
+ case P1363: return "ecdsa_p1363_verify_schema.json";
+ default: break;
+ }
+ } else if (signatureAlgorithm.equals("DSA")) {
+ switch (signatureFormat) {
+ case ASN: return "dsa_verify_schema.json";
+ case P1363: return "dsa_p1363_verify_schema.json";
+ default: break;
+ }
+ } else if (signatureAlgorithm.equals("RSA")) {
+ // Only RSA-PKCS1 is implemented in this unit test.
+ // RSA-PSS signatures have their own unit test, because the algorithm parameters
+ // require a setup that is a little different.
+ switch (signatureFormat) {
+ case RAW: return "rsassa_pkcs1_verify_schema.json";
+ default: break;
+ }
+ } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
+ switch (signatureFormat) {
+ case RAW:
+ return "eddsa_verify_schema.json";
+ default:
+ break;
+ }
+ }
+ } else {
+ // signature generation
+ if (signatureAlgorithm.equals("RSA")) {
+ return "rsassa_pkcs1_generate_schema.json";
+ } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
+ // TODO(bleichen):
+ switch (signatureFormat) {
+ case RAW:
+ return "eddsa_verify_schema.json";
+ default:
+ break;
+ }
+ }
+ }
+ // If the schema is not defined then the tests below still run. The only drawback is that
+ // incorrect test setups are not recognized and will probably lead to failures later.
+ return "";
+ }
+ /**
+ * Get a PublicKey from a JsonObject.
+ *
+ * <p>object contains the key in multiple formats: "key" : elements of the public key "keyDer":
+ * the key in ASN encoding encoded hexadecimal "keyPem": the key in Pem format encoded hexadecimal
+ * The test can use the format that is most convenient.
+ */
+ // This is a false positive, since errorprone cannot track values passed into a method.
+ @SuppressWarnings("InsecureCryptoUsage")
+ protected static PublicKey getPublicKey(JsonObject group, String algorithm) throws Exception {
+ KeyFactory kf;
+ if (algorithm.equals("ECDSA")) {
+ kf = KeyFactory.getInstance("EC");
+ } else if (algorithm.equals("ED25519") || algorithm.equals("ED448")) {
+ // http://openjdk.java.net/jeps/339
+ kf = KeyFactory.getInstance("EdDSA");
+ } else {
+ kf = KeyFactory.getInstance(algorithm);
+ }
+ byte[] encoded = TestUtil.hexToBytes(getString(group, "keyDer"));
+ X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(encoded);
+ return kf.generatePublic(x509keySpec);
+ }
+
+ /**
+ * Get a PrivateKey from a JsonObject.
+ */
+ // This is a false positive, since errorprone cannot track values passed into a method.
+ @SuppressWarnings("InsecureCryptoUsage")
+ protected static PrivateKey getPrivateKey(JsonObject object, String algorithm) throws Exception {
+ if (algorithm.equals("RSA")) {
+ KeyFactory kf = KeyFactory.getInstance(algorithm);
+ byte[] encoded = TestUtil.hexToBytes(getString(object, "privateKeyPkcs8"));
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
+ return kf.generatePrivate(keySpec);
+ } else {
+ throw new NoSuchAlgorithmException("Algorithm " + algorithm + " is not supported");
+ }
+ }
+
+ /**
+ * Tests the signature verification with test vectors in a given JSON file.
+ *
+ * <p> Example format for test vectors
+ * {
+ * "algorithm": "ECDSA",
+ * "generatorVersion": "0.0a13",
+ * "numberOfTests": 217,
+ * "testGroups": [
+ * {
+ * "key": {
+ * "curve": "secp256r1",
+ * "type": "ECPublicKey",
+ * "wx": "0c9c4bc2617c81eb2dcbfda2db2a370a955be86a0d2e95fcb86a99f90cf046573",
+ * "wy": "0c400363b1b6bcc3595a7d6d3575ccebcbb03f90ba8e58da2bc4824272f4fecff"
+ * },
+ * "keyDer": <X509encoded key>
+ * "keyPem": "-----BEGIN PUBLIC KEY-----\ ... \n-----END PUBLIC KEY-----",
+ * "sha": "SHA-256",
+ * "tests": [
+ * {
+ * "comment": "random signature",
+ * "msg": "48656c6c6f",
+ * "result": "valid",
+ * "sig": "...",
+ * "tcId": 1
+ * },
+ * ...
+ * }
+ *
+ * @param filename the filename of the test vectors
+ * @param signatureAlgorithm the algorithm name of the test vectors
+ * @param signatureFormat the format of the signatures. This should be Format.P1363 for
+ * P1363 encoded signatures Format.ASN for ASN.1 encoded signature and Format.RAW
+ otherwise.
+ * @param allowSkippingKeys if true then keys that cannot be constructed will not fail the test.
+ * This is for example used for files with test vectors that use elliptic curves that are not
+ * commonly supported.
+ **/
+ public void testVerification(
+ String filename, String signatureAlgorithm, Format signatureFormat, boolean allowSkippingKeys)
+ throws Exception {
+ JsonObject test = JsonUtil.getTestVectors(filename);
+ // Checks whether the test vectors in the file use the expected algorithm and the expected
+ // format for the signatures.
+ String schema = expectedSchema(signatureAlgorithm, signatureFormat, true);
+ String actualSchema = getString(test, "schema");
+ if (!schema.isEmpty() && !schema.equals(actualSchema)) {
+ System.out.println(
+ signatureAlgorithm
+ + ": expecting test vectors with schema "
+ + schema
+ + " found vectors with schema "
+ + actualSchema);
+ }
+ int numTests = test.get("numberOfTests").getAsInt();
+ int cntTests = 0;
+ int verifiedSignatures = 0;
+ int errors = 0;
+ int skippedKeys = 0;
+ int skippedAlgorithms = 0;
+ int supportedKeys = 0;
+ Set<String> skippedGroups = new HashSet<String>();
+ for (JsonElement g : test.getAsJsonArray("testGroups")) {
+ JsonObject group = g.getAsJsonObject();
+ PublicKey key;
+ try {
+ key = getPublicKey(group, signatureAlgorithm);
+ } catch (GeneralSecurityException ex) {
+ if (!allowSkippingKeys) {
+ throw ex;
+ }
+ if (group.has("key")) {
+ JsonObject keyStruct = group.getAsJsonObject("key");
+ if (keyStruct.has("curve")) {
+ skippedGroups.add("curve = " + getString(keyStruct, "curve"));
+ }
+ }
+ skippedKeys++;
+ continue;
+ }
+ Signature verifier;
+ try {
+ verifier = getSignatureInstance(group, signatureAlgorithm, signatureFormat);
+ } catch (NoSuchAlgorithmException ex) {
+ if (!allowSkippingKeys) {
+ throw ex;
+ }
+ skippedAlgorithms++;
+ continue;
+ }
+ supportedKeys++;
+ for (JsonElement t : group.getAsJsonArray("tests")) {
+ cntTests++;
+ JsonObject testcase = t.getAsJsonObject();
+ byte[] message = getBytes(testcase, "msg");
+ byte[] signature = getBytes(testcase, "sig");
+ int tcid = testcase.get("tcId").getAsInt();
+ String sig = TestUtil.bytesToHex(signature);
+ String result = getString(testcase, "result");
+ verifier.initVerify(key);
+ verifier.update(message);
+ boolean verified = false;
+ Exception failure = null;
+ try {
+ verified = verifier.verify(signature);
+ } catch (SignatureException ex) {
+ // verify can throw SignatureExceptions if the signature is malformed.
+ // We don't flag these cases and simply consider the signature as invalid.
+ verified = false;
+ failure = ex;
+ } catch (java.lang.ArithmeticException ex) {
+ // b/33446454 The Sun provider may throw an ArithmeticException instead of
+ // the expected SignatureException for DSA signatures.
+ // We should eventually remove this.
+ verified = false;
+ failure = ex;
+ } 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(
+ signatureAlgorithm
+ + " signature throws "
+ + ex.toString()
+ + " "
+ + filename
+ + " tcId:"
+ + tcid
+ + " sig:"
+ + sig);
+ verified = false;
+ failure = ex;
+ errors++;
+ }
+ if (!verified && result.equals("valid")) {
+ String reason = "";
+ if (failure != null) {
+ reason = " reason:" + failure;
+ }
+ System.out.println(
+ "Valid "
+ + signatureAlgorithm
+ + " signature not verified."
+ + " "
+ + filename
+ + " tcId:"
+ + tcid
+ + " sig:"
+ + sig
+ + reason);
+ errors++;
+ } else if (verified) {
+ if (result.equals("invalid")) {
+ System.out.println(
+ "Invalid"
+ + signatureAlgorithm
+ + " signature verified."
+ + " "
+ + filename
+ + " tcId:"
+ + tcid
+ + " sig:"
+ + sig);
+ errors++;
+ } else {
+ verifiedSignatures++;
+ }
+ }
+ }
+ }
+ // Prints some information if tests were skipped. This avoids giving
+ // the impression that algorithms are supported.
+ if (skippedKeys > 0 || skippedAlgorithms > 0 || verifiedSignatures == 0) {
+ System.out.println(
+ "File:"
+ + filename
+ + " number of skipped keys:"
+ + skippedKeys
+ + " number of skipped algorithms:"
+ + skippedAlgorithms
+ + " number of supported keys:"
+ + supportedKeys
+ + " verified signatures:"
+ + verifiedSignatures);
+ for (String s : skippedGroups) {
+ System.out.println("Skipped groups where " + s);
+ }
+ }
+ assertEquals(0, errors);
+ if (skippedKeys == 0 && skippedAlgorithms == 0) {
+ assertEquals(numTests, cntTests);
+ }
+ }
+
+ /**
+ * Tests signature generation of deterministic signature schemes such as RSA-PKCS#1 v1.5.
+ *
+ * <p>The test expects that signatures are fully complying with the standards.
+ * E.g. it is acceptable when RSA-PKCS#1 verification considers ASN encodings of the
+ * digest name with a missing NULL value for legacy reasons. However, it is considered not
+ * acceptable when the signature generation does not include the NULL value.
+ *
+ * @param filename the filename of the test vectors
+ * @param signatureAlgorithm the algorithm name of the test vectors (e.g. "RSA")
+ * @param signatureFormat the format of the signatures.
+ * @param allowSkippingKeys if true then keys that cannot be constructed will not fail the test.
+ */
+ public void testSigning(
+ String filename, String signatureAlgorithm, Format signatureFormat,
+ boolean allowSkippingKeys) throws Exception {
+ JsonObject test = JsonUtil.getTestVectors(filename);
+ // Checks whether the test vectors in the file use the expected algorithm and the expected
+ // format for the signatures.
+ String schema = expectedSchema(signatureAlgorithm, signatureFormat, false);
+ String actualSchema = getString(test, "schema");
+ if (!schema.isEmpty() && !schema.equals(actualSchema)) {
+ System.out.println(
+ signatureAlgorithm
+ + ": expecting test vectors with schema "
+ + schema
+ + " found vectors with schema "
+ + actualSchema);
+ }
+ int cntTests = 0;
+ int errors = 0;
+ int skippedKeys = 0;
+ for (JsonElement g : test.getAsJsonArray("testGroups")) {
+ JsonObject group = g.getAsJsonObject();
+ PrivateKey key;
+ try {
+ key = getPrivateKey(group, signatureAlgorithm);
+ } catch (GeneralSecurityException ex) {
+ skippedKeys++;
+ continue;
+ }
+ Signature signer;
+ try {
+ signer = getSignatureInstance(group, signatureAlgorithm, signatureFormat);
+ } catch (NoSuchAlgorithmException ex) {
+ skippedKeys++;
+ continue;
+ }
+ for (JsonElement t : group.getAsJsonArray("tests")) {
+ JsonObject testcase = t.getAsJsonObject();
+ String result = getString(testcase, "result");
+ byte[] message = getBytes(testcase, "msg");
+ byte[] signature = getBytes(testcase, "sig");
+ int tcid = testcase.get("tcId").getAsInt();
+ String expectedSig = TestUtil.bytesToHex(signature);
+ try {
+ signer.initSign(key);
+ signer.update(message);
+ String sig = TestUtil.bytesToHex(signer.sign());
+ if (!sig.equals(expectedSig)) {
+ System.out.println(
+ "Incorrect signature generated "
+ + filename
+ + " tcId:"
+ + tcid
+ + " expected:"
+ + expectedSig
+ + " sig:"
+ + sig);
+ errors++;
+ } else {
+ cntTests++;
+ }
+ } catch (InvalidKeyException | SignatureException ex) {
+ if (result.equals("valid")) {
+ System.out.println(
+ "Failed to sign "
+ + filename
+ + " tcId:"
+ + tcid
+ + " with exception:"
+ + ex);
+
+ errors++;
+ }
+ }
+ }
+ }
+ assertEquals(0, errors);
+ if (skippedKeys > 0) {
+ System.out.println("File:" + filename);
+ System.out.println("Number of signatures verified:" + cntTests);
+ System.out.println("Number of skipped keys:" + skippedKeys);
+ assertTrue(allowSkippingKeys);
+ }
+ }
+
+ @Test
+ public void testEcdsa() throws Exception {
+ testVerification("ecdsa_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp224r1Sha224() throws Exception {
+ testVerification("ecdsa_secp224r1_sha224_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp224r1Sha256() throws Exception {
+ testVerification("ecdsa_secp224r1_sha256_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp224r1Sha512() throws Exception {
+ testVerification("ecdsa_secp224r1_sha512_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp256r1Sha256() throws Exception {
+ testVerification("ecdsa_secp256r1_sha256_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp256r1Sha512() throws Exception {
+ testVerification("ecdsa_secp256r1_sha512_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp384r1Sha384() throws Exception {
+ testVerification("ecdsa_secp384r1_sha384_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp384r1Sha512() throws Exception {
+ testVerification("ecdsa_secp384r1_sha512_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ @Test
+ public void testSecp521r1Sha512() throws Exception {
+ testVerification("ecdsa_secp521r1_sha512_test.json", "ECDSA", Format.ASN, false);
+ }
+
+ // Testing curves that may not be supported by a provider.
+ @Test
+ public void testSecp256k1Sha256() throws Exception {
+ testVerification("ecdsa_secp256k1_sha256_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp256k1Sha512() throws Exception {
+ testVerification("ecdsa_secp256k1_sha512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @NoPresubmitTest(
+ providers = {ProviderType.OPENJDK},
+ bugs = {"b/117643131"}
+ )
+ @Test
+ public void testBrainpoolP224r1Sha224() throws Exception {
+ testVerification("ecdsa_brainpoolP224r1_sha224_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testBrainpoolP256r1Sha256() throws Exception {
+ testVerification("ecdsa_brainpoolP256r1_sha256_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testBrainpoolP320r1Sha384() throws Exception {
+ testVerification("ecdsa_brainpoolP320r1_sha384_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testBrainpoolP384r1Sha384() throws Exception {
+ testVerification("ecdsa_brainpoolP384r1_sha384_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testBrainpoolP512r1Sha512() throws Exception {
+ testVerification("ecdsa_brainpoolP512r1_sha512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ // SHA-3 signatures
+ @Test
+ public void testSecp224r1Sha3_224 () throws Exception {
+ testVerification("ecdsa_secp224r1_sha3_224_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp224r1Sha3_256 () throws Exception {
+ testVerification("ecdsa_secp224r1_sha3_256_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp224r1Sha3_512 () throws Exception {
+ testVerification("ecdsa_secp224r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp256r1Sha3_256 () throws Exception {
+ testVerification("ecdsa_secp256r1_sha3_256_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp256r1Sha3_512 () throws Exception {
+ testVerification("ecdsa_secp256r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp256k1Sha3_256 () throws Exception {
+ testVerification("ecdsa_secp256k1_sha3_256_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp256k1Sha3_512 () throws Exception {
+ testVerification("ecdsa_secp256k1_sha3_512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp384r1Sha3_384 () throws Exception {
+ testVerification("ecdsa_secp384r1_sha3_384_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp384r1Sha3_512 () throws Exception {
+ testVerification("ecdsa_secp384r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ @Test
+ public void testSecp521r1Sha3_512 () throws Exception {
+ testVerification("ecdsa_secp521r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
+ }
+
+ // jdk11 adds P1363 encoded signatures.
+ @Test
+ public void testSecp224r1Sha224inP1363Format() throws Exception {
+ testVerification("ecdsa_secp224r1_sha224_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp224r1Sha256inP1363Format() throws Exception {
+ testVerification("ecdsa_secp224r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp224r1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_secp224r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp256r1Sha256inP1363Format() throws Exception {
+ testVerification("ecdsa_secp256r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp256r1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_secp256r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp384r1Sha384inP1363Format() throws Exception {
+ testVerification("ecdsa_secp384r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp384r1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_secp384r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp521r1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_secp521r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp256k1Sha256inP1363Format() throws Exception {
+ testVerification("ecdsa_secp256k1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testSecp256k1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_secp256k1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @NoPresubmitTest(
+ providers = {ProviderType.OPENJDK},
+ bugs = {"b/117643131"}
+ )
+ @Test
+ public void testBrainpoolP224r1Sha224inP1363Format() throws Exception {
+ testVerification("ecdsa_brainpoolP224r1_sha224_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testBrainpoolP256r1Sha256inP1363Format() throws Exception {
+ testVerification("ecdsa_brainpoolP256r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testBrainpoolP320r1Sha384inP1363Format() throws Exception {
+ testVerification("ecdsa_brainpoolP320r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testBrainpoolP384r1Sha384inP1363Format() throws Exception {
+ testVerification("ecdsa_brainpoolP384r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ @Test
+ public void testBrainpoolP512r1Sha512inP1363Format() throws Exception {
+ testVerification("ecdsa_brainpoolP512r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
+ }
+
+ // Testing RSA PKCS#1 v1.5 signatures.
+ @Test
+ public void testRsaSigning() throws Exception {
+ testSigning("rsa_sig_gen_misc_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures() throws Exception {
+ testVerification("rsa_signature_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignature2048sha224() throws Exception {
+ testVerification("rsa_signature_2048_sha224_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha256() throws Exception {
+ testVerification("rsa_signature_2048_sha256_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha384() throws Exception {
+ testVerification("rsa_signature_2048_sha384_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha512() throws Exception {
+ testVerification("rsa_signature_2048_sha512_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha256() throws Exception {
+ testVerification("rsa_signature_3072_sha256_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha384() throws Exception {
+ testVerification("rsa_signature_3072_sha384_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha512() throws Exception {
+ testVerification("rsa_signature_3072_sha512_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures4096sha384() throws Exception {
+ testVerification("rsa_signature_4096_sha384_test.json", "RSA", Format.RAW, false);
+ }
+
+ @Test
+ public void testRsaSignatures4096sha512() throws Exception {
+ testVerification("rsa_signature_4096_sha512_test.json", "RSA", Format.RAW, false);
+ }
+
+ // RSA signatures with truncated hashes. Tests may be skipped if the provider
+ // does not support the hash.
+ @Test
+ public void testRsaSignatures2048sha512_224() throws Exception {
+ testVerification("rsa_signature_2048_sha512_224_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha512_256() throws Exception {
+ testVerification("rsa_signature_2048_sha512_256_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha512_256() throws Exception {
+ testVerification("rsa_signature_3072_sha512_256_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures4096sha512_256() throws Exception {
+ testVerification("rsa_signature_4096_sha512_256_test.json", "RSA", Format.RAW, true);
+ }
+
+ // RSA signatures with SHA-3. Not every provider supports SHA-3. Hence the tests
+ // may be skipped.
+ @Test
+ public void testRsaSignature2048sha3_224() throws Exception {
+ testVerification("rsa_signature_2048_sha3_224_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha3_256() throws Exception {
+ testVerification("rsa_signature_2048_sha3_256_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures2048sha3_512() throws Exception {
+ testVerification("rsa_signature_2048_sha3_512_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha3_256() throws Exception {
+ testVerification("rsa_signature_3072_sha3_256_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha3_384() throws Exception {
+ testVerification("rsa_signature_3072_sha3_384_test.json", "RSA", Format.RAW, true);
+ }
+
+ @Test
+ public void testRsaSignatures3072sha3_512() throws Exception {
+ testVerification("rsa_signature_3072_sha3_512_test.json", "RSA", Format.RAW, true);
+ }
+
+ // EdDSA
+ @NoPresubmitTest(
+ providers = {ProviderType.BOUNCY_CASTLE},
+ bugs = {"https://github.com/bcgit/bc-java/issues/508"})
+ @Test
+ public void testEd25519Verify() throws Exception {
+ testVerification("eddsa_test.json", "ED25519", Format.RAW, true);
+ }
+
+ @NoPresubmitTest(
+ providers = {ProviderType.BOUNCY_CASTLE},
+ bugs = {"https://github.com/bcgit/bc-java/issues/508"})
+ @Test
+ public void testEd448Verify() throws Exception {
+ testVerification("ed448_test.json", "ED448", Format.RAW, true);
+ }
+
+ // DSA
+ // Two signature encodings for DSA are tested below: ASN encoded signatures
+ // and P1363 encoded signatures.
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048Sha224() throws Exception {
+ testVerification("dsa_2048_224_sha224_test.json", "DSA", Format.ASN, true);
+ }
+
+ // NIST allows 2048-bit DSA keys with either a 224-bit q or a 256-bit q.
+ // In both cases the security level is 112-bit.
+ // Jdk generates DSA keys with a 224-bit q (unless specified).
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048JdkSha256() throws Exception {
+ testVerification("dsa_2048_224_sha256_test.json", "DSA", Format.ASN, true);
+ }
+
+ // OpenSSL generates DSA keys with a 256-bit q (unless specified).
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048Sha256() throws Exception {
+ testVerification("dsa_2048_256_sha256_test.json", "DSA", Format.ASN, true);
+ }
+
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa3072Sha256() throws Exception {
+ testVerification("dsa_3072_256_sha256_test.json", "DSA", Format.ASN, true);
+ }
+
+ // DSA tests using P1363 formated signatures.
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048Sha224inP1363Format() throws Exception {
+ testVerification("dsa_2048_224_sha224_p1363_test.json", "DSA", Format.P1363, true);
+ }
+
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048JdkSha256inP1363Format() throws Exception {
+ testVerification("dsa_2048_224_sha256_p1363_test.json", "DSA", Format.P1363, true);
+ }
+
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa2048Sha256inP1363Format() throws Exception {
+ testVerification("dsa_2048_256_sha256_p1363_test.json", "DSA", Format.P1363, true);
+ }
+
+ @ExcludedTest(
+ providers = {ProviderType.CONSCRYPT},
+ comment = "Conscrypt does not support DSA.")
+ @Test
+ public void testDsa3072Sha256inP1363Format() throws Exception {
+ testVerification("dsa_3072_256_sha256_p1363_test.json", "DSA", Format.P1363, true);
+ }
+
+}
+