1 /**
2  * Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  *   http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 package com.google.security.wycheproof;
15 
16 import static org.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertTrue;
18 import static org.junit.Assert.assertFalse;
19 
20 import com.google.gson.JsonElement;
21 import com.google.gson.JsonObject;
22 import java.security.GeneralSecurityException;
23 import java.security.InvalidKeyException;
24 import java.security.KeyFactory;
25 import java.security.KeyStore;
26 import java.security.NoSuchAlgorithmException;
27 import java.security.NoSuchProviderException;
28 import java.security.PrivateKey;
29 import java.security.PublicKey;
30 import java.security.Signature;
31 import java.security.SignatureException;
32 import java.security.spec.PKCS8EncodedKeySpec;
33 import java.security.spec.X509EncodedKeySpec;
34 import java.util.HashSet;
35 import java.util.Set;
36 import org.junit.After;
37 import org.junit.Test;
38 import org.junit.Ignore;
39 import android.security.keystore.KeyProtection;
40 import android.security.keystore.KeyProperties;
41 import android.keystore.cts.util.KeyStoreUtil;
42 
43 /**
44  * This test uses test vectors in JSON format to check digital signature schemes. There are still a
45  * lot of open questions, e.g. the format for the test vectors is not yet finalized. Therefore, we
46  * are not integrating the tests here into other tests
47  */
48 public class JsonSignatureTest {
49   private static final String EXPECTED_PROVIDER_NAME = TestUtil.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
50   private static final String KEY_ALIAS_1 = "TestKey";
51 
52   @After
tearDown()53   public void tearDown() throws Exception {
54     KeyStoreUtil.cleanUpKeyStore();
55   }
56 
getKeystorePrivateKey(PublicKey pubKey, PrivateKey privKey, String digest, boolean isStrongBox)57   private static PrivateKey getKeystorePrivateKey(PublicKey pubKey, PrivateKey privKey, String digest,
58                                                   boolean isStrongBox) throws Exception {
59     KeyProtection keyProtection = new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
60 	      .setDigests(digest)
61 	      .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
62               .setIsStrongBoxBacked(isStrongBox)
63 	      .build();
64     KeyStore keyStore =
65                        KeyStoreUtil.saveKeysToKeystore(KEY_ALIAS_1, pubKey, privKey, keyProtection);
66     return (PrivateKey) keyStore.getKey(KEY_ALIAS_1, null);
67   }
68 
69   /**
70    * Defines the format of the signatures. RAW is used when the signature scheme already
71    * defines an encoding (e.g. this is used for RSA signatures).
72    */
73   public enum Format { RAW, ASN, P1363 };
74 
75   /** Convenience method to get a String from a JsonObject */
getString(JsonObject object, String name)76   protected static String getString(JsonObject object, String name) {
77     return object.get(name).getAsString();
78   }
79 
80   /** Convenience method to get a byte array from a JsonObject */
getBytes(JsonObject object, String name)81   protected static byte[] getBytes(JsonObject object, String name) throws Exception {
82     return JsonUtil.asByteArray(object.get(name));
83   }
84 
85   /**
86    * Convert hash names, so that they can be used in an algorithm name for a signature. The
87    * algorithm names used in JCA are a bit inconsequential. E.g. a dash is necessary for message
88    * digests (e.g. "SHA-256") but are not used in the corresponding names for digital signatures
89    * (e.g. "SHA256WITHECDSA"). Providers sometimes use distinct algorithm names for the same
90    * cryptographic primitive. On the other hand, the dash remains for SHA-3. Hence, the correct
91    * name for ECDSA with SHA3-256 is "SHA3-256WithECDSA".
92    *
93    * <p>See https://docs.oracle.com/en/java/javase/11/docs/specs/security/standard-names.html
94    *
95    * @param md the name of a message digest
96    * @return the name of the message digest when used in a signature algorithm.
97    */
convertMdName(String md)98   protected static String convertMdName(String md) {
99     if (md.equalsIgnoreCase("SHA-1")) {
100       return "SHA1";
101     } else if (md.equalsIgnoreCase("SHA-224")) {
102       return "SHA224";
103     } else if (md.equalsIgnoreCase("SHA-256")) {
104       return "SHA256";
105     } else if (md.equalsIgnoreCase("SHA-384")) {
106       return "SHA384";
107     } else if (md.equalsIgnoreCase("SHA-512")) {
108       return "SHA512";
109     } else if (md.equalsIgnoreCase("SHA-512/224")) {
110       return "SHA512/224";
111     } else if (md.equalsIgnoreCase("SHA-512/256")) {
112       return "SHA512/256";
113     }
114     return md;
115   }
116 
117   /**
118    * Returns an instance of java.security.Signature for an algorithm name, a digest name and a
119    * signature format.
120    *
121    * @param md the name of the message digest (e.g. "SHA-256")
122    * @param signatureAlgorithm the name of the signature algorithm (e.g. "ECDSA")
123    * @param signatureFormat the format of the signatures.
124    * @return an instance of java.security.Signature if the algorithm is known
125    * @throws NoSuchAlgorithmException if the algorithm is not known
126    */
getSignatureInstance( JsonObject group, String signatureAlgorithm, Format signatureFormat)127   protected static Signature getSignatureInstance(
128       JsonObject group, String signatureAlgorithm, Format signatureFormat)
129       throws NoSuchAlgorithmException, NoSuchProviderException {
130     String md = "";
131     if (group.has("sha")) {
132       md = convertMdName(getString(group, "sha"));
133     }
134     if (signatureAlgorithm.equals("ECDSA") || signatureAlgorithm.equals("DSA")) {
135       if (signatureFormat == Format.ASN) {
136         return Signature.getInstance(md + "WITH" + signatureAlgorithm, EXPECTED_PROVIDER_NAME);
137       } else if (signatureFormat == Format.P1363) {
138         // The algorithm names for signature schemes with P1363 format have distinct names
139         // in distinct providers. This is mainly the case since the P1363 format has only
140         // been added in jdk11, while providers such as BouncyCastle added the format earlier
141         // than that. Hence the code below just tries known algorithm names.
142         try {
143           String jdkName = md + "WITH" + signatureAlgorithm + "inP1363Format";
144           return Signature.getInstance(jdkName, EXPECTED_PROVIDER_NAME);
145         } catch (NoSuchAlgorithmException ex) {
146           // jdkName is not known.
147         }
148         String bcName = md + "WITHPLAIN-" + signatureAlgorithm;
149         return Signature.getInstance(bcName, EXPECTED_PROVIDER_NAME);
150       }
151     } else if (signatureAlgorithm.equals("RSA")) {
152       if (signatureFormat == Format.RAW) {
153         return Signature.getInstance(md + "WITH" + signatureAlgorithm, EXPECTED_PROVIDER_NAME);
154       }
155     } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
156       if (signatureFormat == Format.RAW) {
157         // http://openjdk.java.net/jeps/339
158         try {
159           return Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME);
160         } catch (NoSuchAlgorithmException ex) {
161           // signatureAlgorithm is not known.
162         }
163         // An alternative name (e.g. used by BouncyCastle) is "EDDSA".
164         try {
165           return Signature.getInstance("EDDSA", EXPECTED_PROVIDER_NAME);
166         } catch (NoSuchAlgorithmException ex) {
167           // "EDDSA" is not known either.
168         }
169       }
170     }
171     throw new NoSuchAlgorithmException(
172         "Algorithm "
173             + signatureAlgorithm
174             + " with format "
175             + signatureFormat
176             + " is not supported");
177   }
178 
179   /**
180    * Returns the expected JSON schema for a given test or "" if the schema is undefined.
181    * The purpose of this function is to perform a sanity test with the goal to recognize
182    * incorrect test setups.
183    * @param signatureAlgorithm the signataure algorithm (e.g. "ECDSA")
184    * @param signatureFormat the format of the signatures
185    * @param verify true if verification is tested, false if signature generations is tested.
186    */
expectedSchema(String signatureAlgorithm, Format signatureFormat, boolean verify)187   protected static String expectedSchema(String signatureAlgorithm, Format signatureFormat,
188                                          boolean verify) {
189     if (verify) {
190       if (signatureAlgorithm.equals("ECDSA")) {
191         switch (signatureFormat) {
192           case ASN: return "ecdsa_verify_schema.json";
193           case P1363: return "ecdsa_p1363_verify_schema.json";
194           default: break;
195         }
196       } else if (signatureAlgorithm.equals("DSA")) {
197         switch (signatureFormat) {
198           case ASN: return "dsa_verify_schema.json";
199           case P1363: return "dsa_p1363_verify_schema.json";
200           default: break;
201         }
202       } else if (signatureAlgorithm.equals("RSA")) {
203         // Only RSA-PKCS1 is implemented in this unit test.
204         // RSA-PSS signatures have their own unit test, because the algorithm parameters
205         // require a setup that is a little different.
206         switch (signatureFormat) {
207           case RAW: return "rsassa_pkcs1_verify_schema.json";
208           default: break;
209         }
210       } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
211         switch (signatureFormat) {
212           case RAW:
213             return "eddsa_verify_schema.json";
214           default:
215             break;
216         }
217       }
218     } else {
219       // signature generation
220       if (signatureAlgorithm.equals("RSA")) {
221         return "rsassa_pkcs1_generate_schema.json";
222       } else if (signatureAlgorithm.equals("ED25519") || signatureAlgorithm.equals("ED448")) {
223         // TODO(bleichen):
224         switch (signatureFormat) {
225           case RAW:
226             return "eddsa_verify_schema.json";
227           default:
228             break;
229         }
230       }
231     }
232     // If the schema is not defined then the tests below still run. The only drawback is that
233     // incorrect test setups are not recognized and will probably lead to failures later.
234     return "";
235   }
236   /**
237    * Get a PublicKey from a JsonObject.
238    *
239    * <p>object contains the key in multiple formats: "key" : elements of the public key "keyDer":
240    * the key in ASN encoding encoded hexadecimal "keyPem": the key in Pem format encoded hexadecimal
241    * The test can use the format that is most convenient.
242    */
243   // This is a false positive, since errorprone cannot track values passed into a method.
244   @SuppressWarnings("InsecureCryptoUsage")
getPublicKey(JsonObject group, String algorithm)245   protected static PublicKey getPublicKey(JsonObject group, String algorithm) throws Exception {
246     KeyFactory kf;
247     if (algorithm.equals("ECDSA")) {
248       kf = KeyFactory.getInstance("EC");
249     } else if (algorithm.equals("ED25519") || algorithm.equals("ED448")) {
250       // http://openjdk.java.net/jeps/339
251       kf = KeyFactory.getInstance("EdDSA");
252     } else {
253       kf = KeyFactory.getInstance(algorithm);
254     }
255     byte[] encoded = TestUtil.hexToBytes(getString(group, "keyDer"));
256     X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(encoded);
257     return kf.generatePublic(x509keySpec);
258   }
259 
260   /**
261    * Get a PrivateKey from a JsonObject.
262    */
263   // This is a false positive, since errorprone cannot track values passed into a method.
264   @SuppressWarnings("InsecureCryptoUsage")
getPrivateKey(JsonObject object, String algorithm, boolean isStrongBox)265   protected static PrivateKey getPrivateKey(JsonObject object, String algorithm,
266                                             boolean isStrongBox) throws Exception {
267     if (algorithm.equals("RSA")) {
268       KeyFactory kf = KeyFactory.getInstance(algorithm);
269       byte[] encoded = TestUtil.hexToBytes(getString(object, "privateKeyPkcs8"));
270       byte[] pubEncoded = TestUtil.hexToBytes(getString(object, "keyDer"));
271       String digest = getString(object, "sha");
272       PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
273       PrivateKey intermediateKey = kf.generatePrivate(keySpec);
274       X509EncodedKeySpec x509keySpec = new X509EncodedKeySpec(pubEncoded);
275       PublicKey pubKey = kf.generatePublic(x509keySpec);
276       return getKeystorePrivateKey(pubKey, intermediateKey, digest, isStrongBox);
277     } else {
278       throw new NoSuchAlgorithmException("Algorithm " + algorithm + " is not supported");
279     }
280   }
281 
282   /**
283    * Tests the signature verification with test vectors in a given JSON file.
284    *
285    * <p> Example format for test vectors
286    * {
287    *   "algorithm": "ECDSA",
288    *   "generatorVersion": "0.0a13",
289    *   "numberOfTests": 217,
290    *   "testGroups": [
291    *     {
292    *       "key": {
293    *         "curve": "secp256r1",
294    *         "type": "ECPublicKey",
295    *         "wx": "0c9c4bc2617c81eb2dcbfda2db2a370a955be86a0d2e95fcb86a99f90cf046573",
296    *         "wy": "0c400363b1b6bcc3595a7d6d3575ccebcbb03f90ba8e58da2bc4824272f4fecff"
297    *       },
298    *       "keyDer": <X509encoded key>
299    *       "keyPem": "-----BEGIN PUBLIC KEY-----\ ... \n-----END PUBLIC KEY-----",
300    *       "sha": "SHA-256",
301    *       "tests": [
302    *         {
303    *           "comment": "random signature",
304    *           "msg": "48656c6c6f",
305    *           "result": "valid",
306    *           "sig": "...",
307    *           "tcId": 1
308    *         },
309    *        ...
310    * }
311    *
312    * @param filename the filename of the test vectors
313    * @param signatureAlgorithm the algorithm name of the test vectors
314    * @param signatureFormat the format of the signatures. This should be Format.P1363 for
315    *        P1363 encoded signatures Format.ASN for ASN.1 encoded signature  and Format.RAW
316             otherwise.
317    * @param allowSkippingKeys if true then keys that cannot be constructed will not fail the test.
318    *     This is for example used for files with test vectors that use elliptic curves that are not
319    *     commonly supported.
320    **/
testVerification( String filename, String signatureAlgorithm, Format signatureFormat, boolean allowSkippingKeys)321   public void testVerification(
322       String filename, String signatureAlgorithm, Format signatureFormat, boolean allowSkippingKeys)
323       throws Exception {
324     JsonObject test = JsonUtil.getTestVectors(this.getClass(), filename);
325     // Checks whether the test vectors in the file use the expected algorithm and the expected
326     // format for the signatures.
327     String schema = expectedSchema(signatureAlgorithm, signatureFormat, true);
328     String actualSchema = getString(test, "schema");
329     assertFalse(
330           signatureAlgorithm
331               + ": expecting test vectors with schema "
332               + schema
333               + " found vectors with schema "
334               + actualSchema,
335           !schema.isEmpty() && !schema.equals(actualSchema));
336     int numTests = test.get("numberOfTests").getAsInt();
337     int cntTests = 0;
338     int verifiedSignatures = 0;
339     int errors = 0;
340     int skippedKeys = 0;
341     int skippedAlgorithms = 0;
342     int supportedKeys = 0;
343     Set<String> skippedGroups = new HashSet<String>();
344     for (JsonElement g : test.getAsJsonArray("testGroups")) {
345       JsonObject group = g.getAsJsonObject();
346       PublicKey key;
347       try {
348         key = getPublicKey(group, signatureAlgorithm);
349       } catch (GeneralSecurityException ex) {
350         if (!allowSkippingKeys) {
351           throw ex;
352         }
353         if (group.has("key")) {
354           JsonObject keyStruct = group.getAsJsonObject("key");
355           if (keyStruct.has("curve")) {
356             skippedGroups.add("curve = " + getString(keyStruct, "curve"));
357           }
358         }
359         skippedKeys++;
360         continue;
361       }
362       Signature verifier;
363       try {
364         verifier = getSignatureInstance(group, signatureAlgorithm, signatureFormat);
365       } catch (NoSuchAlgorithmException ex) {
366         if (!allowSkippingKeys) {
367           throw ex;
368         }
369         skippedAlgorithms++;
370         continue;
371       }
372       supportedKeys++;
373       for (JsonElement t : group.getAsJsonArray("tests")) {
374         cntTests++;
375         JsonObject testcase = t.getAsJsonObject();
376         byte[] message = getBytes(testcase, "msg");
377         byte[] signature = getBytes(testcase, "sig");
378         int tcid = testcase.get("tcId").getAsInt();
379         String sig = TestUtil.bytesToHex(signature);
380         String result = getString(testcase, "result");
381         verifier.initVerify(key);
382         verifier.update(message);
383         boolean verified = false;
384         Exception failure = null;
385         try {
386           verified = verifier.verify(signature);
387         } catch (SignatureException ex) {
388           // verify can throw SignatureExceptions if the signature is malformed.
389           // We don't flag these cases and simply consider the signature as invalid.
390           verified = false;
391           failure = ex;
392         } catch (java.lang.ArithmeticException ex) {
393           // b/33446454 The Sun provider may throw an ArithmeticException instead of
394           // the expected SignatureException for DSA signatures.
395           // We should eventually remove this.
396           verified = false;
397           failure = ex;
398         } catch (Exception ex) {
399           // Other exceptions (i.e. unchecked exceptions) are considered as error
400           // since a third party should never be able to cause such exceptions.
401           verified = false;
402           failure = ex;
403           errors++;
404         }
405         if (!verified && result.equals("valid")) {
406           errors++;
407         } else if (verified) {
408           if (result.equals("invalid")) {
409             errors++;
410           } else {
411             verifiedSignatures++;
412           }
413         }
414       }
415     }
416     assertEquals(0, errors);
417     if (skippedKeys == 0 && skippedAlgorithms == 0) {
418       assertEquals(numTests, cntTests);
419     }
420   }
421 
422   /**
423    * Tests signature generation of deterministic signature schemes such as RSA-PKCS#1 v1.5.
424    *
425    * <p>The test expects that signatures are fully complying with the standards.
426    * E.g. it is acceptable when RSA-PKCS#1 verification considers ASN encodings of the
427    * digest name with a missing NULL value for legacy reasons. However, it is considered not
428    * acceptable when the signature generation does not include the NULL value.
429    *
430    * @param filename the filename of the test vectors
431    * @param signatureAlgorithm the algorithm name of the test vectors (e.g. "RSA")
432    * @param signatureFormat the format of the signatures.
433    * @param allowSkippingKeys if true then keys that cannot be constructed will not fail the test.
434    */
testSigning( String filename, String signatureAlgorithm, Format signatureFormat, boolean allowSkippingKeys)435   public void testSigning(
436           String filename, String signatureAlgorithm, Format signatureFormat,
437           boolean allowSkippingKeys) throws Exception {
438     testSigning(filename, signatureAlgorithm, signatureFormat, allowSkippingKeys, false);
439   }
testSigning( String filename, String signatureAlgorithm, Format signatureFormat, boolean allowSkippingKeys, boolean isStrongBox)440   public void testSigning(
441       String filename, String signatureAlgorithm, Format signatureFormat,
442       boolean allowSkippingKeys, boolean isStrongBox) throws Exception {
443     JsonObject test = JsonUtil.getTestVectors(this.getClass(), filename);
444     int cntTests = 0;
445     int errors = 0;
446     int skippedKeys = 0;
447     for (JsonElement g : test.getAsJsonArray("testGroups")) {
448       JsonObject group = g.getAsJsonObject();
449       PrivateKey key;
450       try {
451         key = getPrivateKey(group, signatureAlgorithm, isStrongBox);
452       } catch (GeneralSecurityException ex) {
453         skippedKeys++;
454         continue;
455       }
456       Signature signer;
457       try {
458         signer = getSignatureInstance(group, signatureAlgorithm, signatureFormat);
459       } catch (NoSuchAlgorithmException ex) {
460         skippedKeys++;
461         continue;
462       }
463       for (JsonElement t : group.getAsJsonArray("tests")) {
464         JsonObject testcase = t.getAsJsonObject();
465         String result = getString(testcase, "result");
466         byte[] message = getBytes(testcase, "msg");
467         byte[] signature = getBytes(testcase, "sig");
468         int tcid = testcase.get("tcId").getAsInt();
469         String expectedSig = TestUtil.bytesToHex(signature);
470         try {
471           signer.initSign(key);
472           signer.update(message);
473           String sig = TestUtil.bytesToHex(signer.sign());
474           if (!sig.equals(expectedSig)) {
475             android.util.Log.e("JsonSignatureTest", "Signature mismatch error for test id " + tcid);
476             errors++;
477           } else {
478             cntTests++;
479           }
480         } catch (InvalidKeyException | SignatureException ex) {
481           if (result.equals("valid")) {
482             android.util.Log.e("JsonSignatureTest", "Unexpected exception for test id " + tcid, ex);
483             if (!isStrongBox) {
484               errors++;
485             }
486           }
487         }
488       }
489     }
490     assertEquals(0, errors);
491     if (skippedKeys > 0) {
492       assertTrue(allowSkippingKeys);
493     }
494   }
495 
496   @Test
testEcdsa()497   public void testEcdsa() throws Exception {
498     testVerification("ecdsa_test.json", "ECDSA", Format.ASN, true);
499   }
500 
501   @Test
testSecp224r1Sha224()502   public void testSecp224r1Sha224() throws Exception {
503     testVerification("ecdsa_secp224r1_sha224_test.json", "ECDSA", Format.ASN, false);
504   }
505 
506   @Test
testSecp224r1Sha256()507   public void testSecp224r1Sha256() throws Exception {
508     testVerification("ecdsa_secp224r1_sha256_test.json", "ECDSA", Format.ASN, false);
509   }
510 
511   @Test
testSecp224r1Sha512()512   public void testSecp224r1Sha512() throws Exception {
513     testVerification("ecdsa_secp224r1_sha512_test.json", "ECDSA", Format.ASN, false);
514   }
515 
516   @Test
testSecp256r1Sha256()517   public void testSecp256r1Sha256() throws Exception {
518     testVerification("ecdsa_secp256r1_sha256_test.json", "ECDSA", Format.ASN, false);
519   }
520 
521   @Test
testSecp256r1Sha512()522   public void testSecp256r1Sha512() throws Exception {
523     testVerification("ecdsa_secp256r1_sha512_test.json", "ECDSA", Format.ASN, false);
524   }
525 
526   @Test
testSecp384r1Sha384()527   public void testSecp384r1Sha384() throws Exception {
528     testVerification("ecdsa_secp384r1_sha384_test.json", "ECDSA", Format.ASN, false);
529   }
530 
531   @Test
testSecp384r1Sha512()532   public void testSecp384r1Sha512() throws Exception {
533     testVerification("ecdsa_secp384r1_sha512_test.json", "ECDSA", Format.ASN, false);
534   }
535 
536   @Test
testSecp521r1Sha512()537   public void testSecp521r1Sha512() throws Exception {
538     testVerification("ecdsa_secp521r1_sha512_test.json", "ECDSA", Format.ASN, false);
539   }
540 
541   // Testing curves that may not be supported by a provider.
542   @Test
543   @Ignore // Secp256k1 curve not supported in AndroidKeystore
testSecp256k1Sha256()544   public void testSecp256k1Sha256() throws Exception {
545     testVerification("ecdsa_secp256k1_sha256_test.json", "ECDSA", Format.ASN, true);
546   }
547 
548   @Test
549   @Ignore // Secp256k1 curve not supported in AndroidKeystore
testSecp256k1Sha512()550   public void testSecp256k1Sha512() throws Exception {
551     testVerification("ecdsa_secp256k1_sha512_test.json", "ECDSA", Format.ASN, true);
552   }
553 
554   @Test
555   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP224r1Sha224()556   public void testBrainpoolP224r1Sha224() throws Exception {
557     testVerification("ecdsa_brainpoolP224r1_sha224_test.json", "ECDSA", Format.ASN, true);
558   }
559 
560   @Test
561   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP256r1Sha256()562   public void testBrainpoolP256r1Sha256() throws Exception {
563     testVerification("ecdsa_brainpoolP256r1_sha256_test.json", "ECDSA", Format.ASN, true);
564   }
565 
566   @Test
567   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP320r1Sha384()568   public void testBrainpoolP320r1Sha384() throws Exception {
569     testVerification("ecdsa_brainpoolP320r1_sha384_test.json", "ECDSA", Format.ASN, true);
570   }
571 
572   @Test
573   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP384r1Sha384()574   public void testBrainpoolP384r1Sha384() throws Exception {
575     testVerification("ecdsa_brainpoolP384r1_sha384_test.json", "ECDSA", Format.ASN, true);
576   }
577 
578   @Test
579   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP512r1Sha512()580   public void testBrainpoolP512r1Sha512() throws Exception {
581     testVerification("ecdsa_brainpoolP512r1_sha512_test.json", "ECDSA", Format.ASN, true);
582   }
583 
584   // SHA-3 signatures
585   @Test
586   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp224r1Sha3_224()587   public void testSecp224r1Sha3_224 () throws Exception {
588     testVerification("ecdsa_secp224r1_sha3_224_test.json", "ECDSA", Format.ASN, true);
589   }
590 
591   @Test
592   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp224r1Sha3_256()593   public void testSecp224r1Sha3_256 () throws Exception {
594     testVerification("ecdsa_secp224r1_sha3_256_test.json", "ECDSA", Format.ASN, true);
595   }
596 
597   @Test
598   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp224r1Sha3_512()599   public void testSecp224r1Sha3_512 () throws Exception {
600     testVerification("ecdsa_secp224r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
601   }
602 
603   @Test
604   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp256r1Sha3_256()605   public void testSecp256r1Sha3_256 () throws Exception {
606     testVerification("ecdsa_secp256r1_sha3_256_test.json", "ECDSA", Format.ASN, true);
607   }
608 
609   @Test
610   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp256r1Sha3_512()611   public void testSecp256r1Sha3_512 () throws Exception {
612     testVerification("ecdsa_secp256r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
613   }
614 
615   @Test
616   @Ignore // Secp256k1 curve and SHA3 algorithms not supported in AndroidKeystore
testSecp256k1Sha3_256()617   public void testSecp256k1Sha3_256 () throws Exception {
618     testVerification("ecdsa_secp256k1_sha3_256_test.json", "ECDSA", Format.ASN, true);
619   }
620 
621   @Test
622   @Ignore // Secp256k1 curve and SHA3 algorithms not supported in AndroidKeystore
testSecp256k1Sha3_512()623   public void testSecp256k1Sha3_512 () throws Exception {
624     testVerification("ecdsa_secp256k1_sha3_512_test.json", "ECDSA", Format.ASN, true);
625   }
626 
627   @Test
628   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp384r1Sha3_384()629   public void testSecp384r1Sha3_384 () throws Exception {
630     testVerification("ecdsa_secp384r1_sha3_384_test.json", "ECDSA", Format.ASN, true);
631   }
632 
633   @Test
634   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp384r1Sha3_512()635   public void testSecp384r1Sha3_512 () throws Exception {
636     testVerification("ecdsa_secp384r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
637   }
638 
639   @Test
640   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testSecp521r1Sha3_512()641   public void testSecp521r1Sha3_512 () throws Exception {
642     testVerification("ecdsa_secp521r1_sha3_512_test.json", "ECDSA", Format.ASN, true);
643   }
644 
645   // jdk11 adds P1363 encoded signatures.
646   @Test
647   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp224r1Sha224inP1363Format()648   public void testSecp224r1Sha224inP1363Format() throws Exception {
649     testVerification("ecdsa_secp224r1_sha224_p1363_test.json", "ECDSA", Format.P1363, true);
650   }
651 
652   @Test
653   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp224r1Sha256inP1363Format()654   public void testSecp224r1Sha256inP1363Format() throws Exception {
655     testVerification("ecdsa_secp224r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
656   }
657 
658   @Test
659   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp224r1Sha512inP1363Format()660   public void testSecp224r1Sha512inP1363Format() throws Exception {
661     testVerification("ecdsa_secp224r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
662   }
663 
664   @Test
665   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp256r1Sha256inP1363Format()666   public void testSecp256r1Sha256inP1363Format() throws Exception {
667     testVerification("ecdsa_secp256r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
668   }
669 
670   @Test
671   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp256r1Sha512inP1363Format()672   public void testSecp256r1Sha512inP1363Format() throws Exception {
673     testVerification("ecdsa_secp256r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
674   }
675 
676   @Test
677   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp384r1Sha384inP1363Format()678   public void testSecp384r1Sha384inP1363Format() throws Exception {
679     testVerification("ecdsa_secp384r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
680   }
681 
682   @Test
683   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp384r1Sha512inP1363Format()684   public void testSecp384r1Sha512inP1363Format() throws Exception {
685     testVerification("ecdsa_secp384r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
686   }
687 
688   @Test
689   @Ignore // P1363 encoding not supported in AndroidKeyStore
testSecp521r1Sha512inP1363Format()690   public void testSecp521r1Sha512inP1363Format() throws Exception {
691     testVerification("ecdsa_secp521r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
692   }
693 
694   @Test
695   @Ignore // Secp256k1 curve not supported in AndroidKeystore
testSecp256k1Sha256inP1363Format()696   public void testSecp256k1Sha256inP1363Format() throws Exception {
697     testVerification("ecdsa_secp256k1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
698   }
699 
700   @Test
701   @Ignore // Secp256k1 curve not supported in AndroidKeystore
testSecp256k1Sha512inP1363Format()702   public void testSecp256k1Sha512inP1363Format() throws Exception {
703     testVerification("ecdsa_secp256k1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
704   }
705 
706   @Test
707   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP224r1Sha224inP1363Format()708   public void testBrainpoolP224r1Sha224inP1363Format() throws Exception {
709     testVerification("ecdsa_brainpoolP224r1_sha224_p1363_test.json", "ECDSA", Format.P1363, true);
710   }
711 
712   @Test
713   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP256r1Sha256inP1363Format()714   public void testBrainpoolP256r1Sha256inP1363Format() throws Exception {
715     testVerification("ecdsa_brainpoolP256r1_sha256_p1363_test.json", "ECDSA", Format.P1363, true);
716   }
717 
718   @Test
719   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP320r1Sha384inP1363Format()720   public void testBrainpoolP320r1Sha384inP1363Format() throws Exception {
721     testVerification("ecdsa_brainpoolP320r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
722   }
723 
724   @Test
725   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP384r1Sha384inP1363Format()726   public void testBrainpoolP384r1Sha384inP1363Format() throws Exception {
727     testVerification("ecdsa_brainpoolP384r1_sha384_p1363_test.json", "ECDSA", Format.P1363, true);
728   }
729 
730   @Test
731   @Ignore // Brainpool curves are not supported in AndroidKeyStore
testBrainpoolP512r1Sha512inP1363Format()732   public void testBrainpoolP512r1Sha512inP1363Format() throws Exception {
733     testVerification("ecdsa_brainpoolP512r1_sha512_p1363_test.json", "ECDSA", Format.P1363, true);
734   }
735 
736   // Testing RSA PKCS#1 v1.5 signatures.
737   @Test
testRsaSigning()738   public void testRsaSigning() throws Exception {
739     testSigning("rsa_sig_gen_misc_test.json", "RSA", Format.RAW, true);
740   }
741   @Test
testRsaSigning_StrongBox()742   public void testRsaSigning_StrongBox() throws Exception {
743     KeyStoreUtil.assumeStrongBox();
744     testSigning("rsa_sig_gen_misc_test.json", "RSA", Format.RAW, true, true);
745   }
746 
747   @Test
testRsaSignatures()748   public void testRsaSignatures() throws Exception {
749     testVerification("rsa_signature_test.json", "RSA", Format.RAW, false);
750   }
751 
752   @Test
testRsaSignature2048sha224()753   public void testRsaSignature2048sha224() throws Exception {
754     testVerification("rsa_signature_2048_sha224_test.json", "RSA", Format.RAW, false);
755   }
756 
757   @Test
testRsaSignatures2048sha256()758   public void testRsaSignatures2048sha256() throws Exception {
759     testVerification("rsa_signature_2048_sha256_test.json", "RSA", Format.RAW, false);
760   }
761 
762   @Test
testRsaSignatures2048sha384()763   public void testRsaSignatures2048sha384() throws Exception {
764     testVerification("rsa_signature_2048_sha384_test.json", "RSA", Format.RAW, false);
765   }
766 
767   @Test
testRsaSignatures2048sha512()768   public void testRsaSignatures2048sha512() throws Exception {
769     testVerification("rsa_signature_2048_sha512_test.json", "RSA", Format.RAW, false);
770   }
771 
772   @Test
testRsaSignatures3072sha256()773   public void testRsaSignatures3072sha256() throws Exception {
774     testVerification("rsa_signature_3072_sha256_test.json", "RSA", Format.RAW, false);
775   }
776 
777   @Test
testRsaSignatures3072sha384()778   public void testRsaSignatures3072sha384() throws Exception {
779     testVerification("rsa_signature_3072_sha384_test.json", "RSA", Format.RAW, false);
780   }
781 
782   @Test
testRsaSignatures3072sha512()783   public void testRsaSignatures3072sha512() throws Exception {
784     testVerification("rsa_signature_3072_sha512_test.json", "RSA", Format.RAW, false);
785   }
786 
787   @Test
testRsaSignatures4096sha384()788   public void testRsaSignatures4096sha384() throws Exception {
789     testVerification("rsa_signature_4096_sha384_test.json", "RSA", Format.RAW, false);
790   }
791 
792   @Test
testRsaSignatures4096sha512()793   public void testRsaSignatures4096sha512() throws Exception {
794     testVerification("rsa_signature_4096_sha512_test.json", "RSA", Format.RAW, false);
795   }
796 
797   // RSA signatures with truncated hashes. Tests may be skipped if the provider
798   // does not support the hash.
799   @Test
800   @Ignore // SHA-512/224 algorithm not supported in AndrdoiKeyStore
testRsaSignatures2048sha512_224()801   public void testRsaSignatures2048sha512_224() throws Exception {
802     testVerification("rsa_signature_2048_sha512_224_test.json", "RSA", Format.RAW, true);
803   }
804 
805   @Test
806   @Ignore // SHA-512/256 algorithm not supported in AndrdoiKeyStore
testRsaSignatures2048sha512_256()807   public void testRsaSignatures2048sha512_256() throws Exception {
808     testVerification("rsa_signature_2048_sha512_256_test.json", "RSA", Format.RAW, true);
809   }
810 
811   @Test
812   @Ignore // SHA-512/256 algorithm not supported in AndrdoiKeyStore
testRsaSignatures3072sha512_256()813   public void testRsaSignatures3072sha512_256() throws Exception {
814     testVerification("rsa_signature_3072_sha512_256_test.json", "RSA", Format.RAW, true);
815   }
816 
817   @Test
818   @Ignore // SHA-512/256 algorithm not supported in AndrdoiKeyStore
testRsaSignatures4096sha512_256()819   public void testRsaSignatures4096sha512_256() throws Exception {
820     testVerification("rsa_signature_4096_sha512_256_test.json", "RSA", Format.RAW, true);
821   }
822 
823   // RSA signatures with SHA-3. Not every provider supports SHA-3. Hence the tests
824   // may be skipped.
825   @Test
826   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignature2048sha3_224()827   public void testRsaSignature2048sha3_224() throws Exception {
828     testVerification("rsa_signature_2048_sha3_224_test.json", "RSA", Format.RAW, true);
829   }
830 
831   @Test
832   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignatures2048sha3_256()833   public void testRsaSignatures2048sha3_256() throws Exception {
834     testVerification("rsa_signature_2048_sha3_256_test.json", "RSA", Format.RAW, true);
835   }
836 
837   @Test
838   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignatures2048sha3_512()839   public void testRsaSignatures2048sha3_512() throws Exception {
840     testVerification("rsa_signature_2048_sha3_512_test.json", "RSA", Format.RAW, true);
841   }
842 
843   @Test
844   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignatures3072sha3_256()845   public void testRsaSignatures3072sha3_256() throws Exception {
846     testVerification("rsa_signature_3072_sha3_256_test.json", "RSA", Format.RAW, true);
847   }
848 
849   @Test
850   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignatures3072sha3_384()851   public void testRsaSignatures3072sha3_384() throws Exception {
852     testVerification("rsa_signature_3072_sha3_384_test.json", "RSA", Format.RAW, true);
853   }
854 
855   @Test
856   @Ignore // SHA3 algorithms are not supported in AndroidKeyStore
testRsaSignatures3072sha3_512()857   public void testRsaSignatures3072sha3_512() throws Exception {
858     testVerification("rsa_signature_3072_sha3_512_test.json", "RSA", Format.RAW, true);
859   }
860 
861   // EdDSA
862   @Test
863   @Ignore // Ed25519 algorithm not supported in AndroidKeyStore
testEd25519Verify()864   public void testEd25519Verify() throws Exception {
865     testVerification("eddsa_test.json", "ED25519", Format.RAW, true);
866   }
867 
868   @Test
869   @Ignore // Ed448 algorithm not supported in AndroidKeyStore
testEd448Verify()870   public void testEd448Verify() throws Exception {
871     testVerification("ed448_test.json", "ED448", Format.RAW, true);
872   }
873 
874   // DSA
875   // Two signature encodings for DSA are tested below: ASN encoded signatures
876   // and P1363 encoded signatures.
877   @Test
878   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048Sha224()879   public void testDsa2048Sha224() throws Exception {
880     testVerification("dsa_2048_224_sha224_test.json", "DSA", Format.ASN, true);
881   }
882 
883   // NIST allows 2048-bit DSA keys with either a 224-bit q or a 256-bit q.
884   // In both cases the security level is 112-bit.
885   // Jdk generates DSA keys with a 224-bit q (unless specified).
886   @Test
887   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048JdkSha256()888   public void testDsa2048JdkSha256() throws Exception {
889     testVerification("dsa_2048_224_sha256_test.json", "DSA", Format.ASN, true);
890   }
891 
892   // OpenSSL generates DSA keys with a 256-bit q (unless specified).
893   @Test
894   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048Sha256()895   public void testDsa2048Sha256() throws Exception {
896     testVerification("dsa_2048_256_sha256_test.json", "DSA", Format.ASN, true);
897   }
898 
899   @Test
900   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa3072Sha256()901   public void testDsa3072Sha256() throws Exception {
902     testVerification("dsa_3072_256_sha256_test.json", "DSA", Format.ASN, true);
903   }
904 
905   // DSA tests using P1363 formated signatures.
906   @Test
907   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048Sha224inP1363Format()908   public void testDsa2048Sha224inP1363Format() throws Exception {
909     testVerification("dsa_2048_224_sha224_p1363_test.json", "DSA", Format.P1363, true);
910   }
911 
912   @Test
913   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048JdkSha256inP1363Format()914   public void testDsa2048JdkSha256inP1363Format() throws Exception {
915     testVerification("dsa_2048_224_sha256_p1363_test.json", "DSA", Format.P1363, true);
916   }
917 
918   @Test
919   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa2048Sha256inP1363Format()920   public void testDsa2048Sha256inP1363Format() throws Exception {
921     testVerification("dsa_2048_256_sha256_p1363_test.json", "DSA", Format.P1363, true);
922   }
923 
924   @Test
925   @Ignore // DSA algorithm not supported in AndroidKeyStore
testDsa3072Sha256inP1363Format()926   public void testDsa3072Sha256inP1363Format() throws Exception {
927     testVerification("dsa_3072_256_sha256_p1363_test.json", "DSA", Format.P1363, true);
928   }
929 }
930 
931