• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specified language governing permissions and
13 // limitations under the License.
14 //
15 ////////////////////////////////////////////////////////////////////////////////
16 
17 package com.google.crypto.tink.testing;
18 
19 import com.google.crypto.tink.internal.testing.TestFiles;
20 import com.google.crypto.tink.subtle.EllipticCurves;
21 import com.google.crypto.tink.subtle.Enums.HashType;
22 import com.google.gson.JsonArray;
23 import com.google.gson.JsonObject;
24 import com.google.gson.JsonParser;
25 import java.io.ByteArrayOutputStream;
26 import java.io.IOException;
27 import java.io.InputStream;
28 import java.nio.charset.Charset;
29 import java.security.NoSuchAlgorithmException;
30 
31 /** Wycheproof Test helpers. */
32 public final class WycheproofTestUtil {
33   private static final Charset UTF_8 = Charset.forName("UTF-8");
34 
35   /**
36    * Gets hash type from hash name.
37    *
38    * @param md the name of the message digest (e.g. "SHA-256").
39    * @return the hash type.
40    * @throws NoSuchAlgorithmException iff the hash name is unknown.
41    */
getHashType(String md)42   public static HashType getHashType(String md) throws NoSuchAlgorithmException {
43     switch (md) {
44       case "SHA-256":
45         return HashType.SHA256;
46       case "SHA-512":
47         return HashType.SHA512;
48       case "SHA-1":
49         return HashType.SHA1;
50       default:
51         throw new NoSuchAlgorithmException("Unsupported hash name: " + md);
52     }
53   }
54 
55   /**
56    * Returns the algorithm name for a digital signature algorithm with a given message digest. The
57    * algorithm names used in JCA are a bit inconsequential. E.g. a dash is necessary for message
58    * digests (e.g. "SHA-256") but are not used in the corresponding names for digital signatures
59    * (e.g. "SHA256WITHECDSA").
60    *
61    * <p>See http://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
62    *
63    * @param md the name of the message digest (e.g. "SHA-256")
64    * @param signatureAlgorithm the name of the signature algorithm (e.g. "ECDSA")
65    * @return the algorithm name for the signature scheme with the given hash.
66    */
getSignatureAlgorithmName(String md, String signatureAlgorithm)67   public static String getSignatureAlgorithmName(String md, String signatureAlgorithm) {
68     if (md.equals("SHA-256")) {
69       md = "SHA256";
70     } else if (md.equals("SHA-512")) {
71       md = "SHA512";
72     } else {
73       return "";
74     }
75     return md + "WITH" + signatureAlgorithm;
76   }
77 
78   /**
79    * Reads all bytes from {@code inputStream}.
80    */
readAll(InputStream inputStream)81   private static byte[] readAll(InputStream inputStream) throws IOException {
82     ByteArrayOutputStream result = new ByteArrayOutputStream();
83     byte[] buf = new byte[1024];
84     int count;
85     while ((count = inputStream.read(buf)) != -1) {
86       result.write(buf, 0, count);
87     }
88     return result.toByteArray();
89   }
90 
91   /** Gets JsonObject from file. */
readJson(String path)92   public static JsonObject readJson(String path) throws IOException {
93     JsonObject result;
94     try (InputStream inputStream = TestFiles.openInputFile(path)) {
95       result = JsonParser.parseString(new String(readAll(inputStream), UTF_8)).getAsJsonObject();
96     }
97     String algorithm = result.get("algorithm").getAsString();
98     String generatorVersion = result.get("generatorVersion").getAsString();
99     int numTests = result.get("numberOfTests").getAsInt();
100     System.out.println(
101         String.format(
102             "Read from %s total %d test cases for algorithm %s with generator version %s",
103             path, numTests, algorithm, generatorVersion));
104     return result;
105   }
106   /**
107    * Gets curve type from curve name.
108    *
109    * @throws NoSuchAlgorithmException iff the curve name is unknown.
110    */
getCurveType(String curveName)111   public static EllipticCurves.CurveType getCurveType(String curveName)
112       throws NoSuchAlgorithmException {
113     switch (curveName) {
114       case "secp256r1":
115         return EllipticCurves.CurveType.NIST_P256;
116       case "secp384r1":
117         return EllipticCurves.CurveType.NIST_P384;
118       case "secp521r1":
119         return EllipticCurves.CurveType.NIST_P521;
120       default:
121         throw new NoSuchAlgorithmException("Unknown curve name: " + curveName);
122     }
123   }
124 
125   /** @return true if the test case has one of the flags. */
checkFlags(JsonObject testcase, String... flags)126   public static boolean checkFlags(JsonObject testcase, String... flags) throws Exception {
127     JsonArray entries = testcase.get("flags").getAsJsonArray();
128     for (int i = 0; i < entries.size(); i++) {
129       for (String flag : flags) {
130         if (flag.equals(entries.get(i).getAsString())) {
131           return true;
132         }
133       }
134     }
135     return false;
136   }
137 
WycheproofTestUtil()138   private WycheproofTestUtil() {}
139 }
140