18 * |
18 * |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 * or visit www.oracle.com if you need additional information or have any |
20 * or visit www.oracle.com if you need additional information or have any |
21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 import java.security.InvalidKeyException; |
23 import java.security.*; |
24 import java.security.Key; |
|
25 import java.security.KeyFactory; |
|
26 import java.security.KeyPair; |
|
27 import java.security.KeyPairGenerator; |
|
28 import java.security.NoSuchAlgorithmException; |
|
29 import java.security.NoSuchProviderException; |
|
30 import java.security.PrivateKey; |
|
31 import java.security.PublicKey; |
|
32 import java.security.Signature; |
|
33 import java.security.SignatureException; |
|
34 import java.security.interfaces.RSAPrivateKey; |
24 import java.security.interfaces.RSAPrivateKey; |
35 import java.security.interfaces.RSAPublicKey; |
25 import java.security.interfaces.RSAPublicKey; |
36 import java.security.spec.InvalidKeySpecException; |
26 import java.security.spec.*; |
37 import java.security.spec.PKCS8EncodedKeySpec; |
27 import java.util.*; |
38 import java.security.spec.RSAPrivateKeySpec; |
|
39 import java.security.spec.RSAPublicKeySpec; |
|
40 import java.security.spec.X509EncodedKeySpec; |
|
41 import java.util.Arrays; |
|
42 import java.util.stream.IntStream; |
28 import java.util.stream.IntStream; |
43 import static javax.crypto.Cipher.PRIVATE_KEY; |
29 import static javax.crypto.Cipher.PRIVATE_KEY; |
44 import static javax.crypto.Cipher.PUBLIC_KEY; |
30 import static javax.crypto.Cipher.PUBLIC_KEY; |
45 |
31 |
|
32 import jdk.test.lib.SigTestUtil; |
|
33 import static jdk.test.lib.SigTestUtil.SignatureType; |
|
34 |
46 /** |
35 /** |
47 * @test |
36 * @test |
48 * @bug 8044199 |
37 * @bug 8044199 8146293 |
49 * @summary Create a signature for RSA and get its signed data. re-initiate |
38 * @summary Create a signature for RSA and get its signed data. re-initiate |
50 * the signature with the public key. The signature can be verified |
39 * the signature with the public key. The signature can be verified |
51 * by acquired signed data. |
40 * by acquired signed data. |
|
41 * @library /test/lib |
|
42 * @build jdk.test.lib.SigTestUtil |
52 * @run main SignatureTest 512 |
43 * @run main SignatureTest 512 |
53 * @run main SignatureTest 768 |
44 * @run main SignatureTest 768 |
54 * @run main SignatureTest 1024 |
45 * @run main SignatureTest 1024 |
55 * @run main SignatureTest 2048 |
46 * @run main SignatureTest 2048 |
56 * @run main/timeout=240 SignatureTest 4096 |
47 * @run main/timeout=240 SignatureTest 4096 |
57 * @run main/timeout=240 SignatureTest 5120 |
48 * @run main/timeout=240 SignatureTest 5120 |
58 * @run main/timeout=240 SignatureTest 6144 |
49 * @run main/timeout=480 SignatureTest 6144 |
59 */ |
50 */ |
60 public class SignatureTest { |
51 public class SignatureTest { |
61 /** |
52 /** |
62 * ALGORITHM name, fixed as RSA. |
53 * ALGORITHM name, fixed as RSA. |
63 */ |
54 */ |
76 /** |
67 /** |
77 * How much times signature initial updated. |
68 * How much times signature initial updated. |
78 */ |
69 */ |
79 private static final int UPDATE_TIMES_HUNDRED = 100; |
70 private static final int UPDATE_TIMES_HUNDRED = 100; |
80 |
71 |
81 /** |
|
82 * Signature algorithms to test |
|
83 */ |
|
84 private static final String[] SIGN_ALG = {"MD2withRSA", "MD5withRSA", |
|
85 "SHA1withRSA", "SHA256withRSA"}; |
|
86 |
|
87 public static void main(String[] args) throws Exception { |
72 public static void main(String[] args) throws Exception { |
88 int testSize = Integer.parseInt(args[0]); |
73 int keySize = Integer.parseInt(args[0]); |
|
74 Iterable<String> md_alg_pkcs15 = |
|
75 SigTestUtil.getDigestAlgorithms(SignatureType.RSA, keySize); |
|
76 |
|
77 Iterable<String> md_alg_pss = |
|
78 SigTestUtil.getDigestAlgorithms(SignatureType.RSASSA_PSS, keySize); |
89 |
79 |
90 byte[] data = new byte[100]; |
80 byte[] data = new byte[100]; |
91 IntStream.range(0, data.length).forEach(j -> { |
81 IntStream.range(0, data.length).forEach(j -> { |
92 data[j] = (byte) j; |
82 data[j] = (byte) j; |
93 }); |
83 }); |
94 |
84 |
95 // create a key pair |
85 // create a key pair |
96 KeyPair kpair = generateKeys(KEYALG, testSize); |
86 KeyPair kpair = generateKeys(KEYALG, keySize); |
97 Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate()); |
87 Key[] privs = manipulateKey(PRIVATE_KEY, kpair.getPrivate()); |
98 Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic()); |
88 Key[] pubs = manipulateKey(PUBLIC_KEY, kpair.getPublic()); |
|
89 |
|
90 test(SignatureType.RSA, md_alg_pkcs15, privs, pubs, data); |
|
91 test(SignatureType.RSASSA_PSS, md_alg_pss, privs, pubs, data); |
|
92 } |
|
93 |
|
94 private static void test(SignatureType type, Iterable<String> digestAlgs, |
|
95 Key[] privs, Key[] pubs, byte[] data) throws RuntimeException { |
|
96 |
99 // For signature algorithm, create and verify a signature |
97 // For signature algorithm, create and verify a signature |
100 |
|
101 Arrays.stream(privs).forEach(priv |
98 Arrays.stream(privs).forEach(priv |
102 -> Arrays.stream(pubs).forEach(pub |
99 -> Arrays.stream(pubs).forEach(pub |
103 -> Arrays.stream(SIGN_ALG).forEach(testAlg -> { |
100 -> digestAlgs.forEach(digestAlg -> { |
104 try { |
101 try { |
|
102 AlgorithmParameterSpec sigParams = |
|
103 SigTestUtil.generateDefaultParameter(type, digestAlg); |
|
104 String sigAlg = SigTestUtil.generateSigAlg(type, digestAlg); |
105 checkSignature(data, (PublicKey) pub, (PrivateKey) priv, |
105 checkSignature(data, (PublicKey) pub, (PrivateKey) priv, |
106 testAlg); |
106 sigAlg, sigParams); |
107 } catch (NoSuchAlgorithmException | InvalidKeyException | |
107 } catch (NoSuchAlgorithmException | InvalidKeyException | |
108 SignatureException | NoSuchProviderException ex) { |
108 SignatureException | NoSuchProviderException | |
|
109 InvalidAlgorithmParameterException ex) { |
109 throw new RuntimeException(ex); |
110 throw new RuntimeException(ex); |
110 } |
111 } |
111 } |
112 } |
112 ))); |
113 ))); |
113 |
|
114 } |
114 } |
115 |
115 |
116 private static KeyPair generateKeys(String keyalg, int size) |
116 private static KeyPair generateKeys(String keyalg, int size) |
117 throws NoSuchAlgorithmException { |
117 throws NoSuchAlgorithmException { |
118 KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg); |
118 KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg); |
158 } |
158 } |
159 throw new RuntimeException("We shouldn't reach here"); |
159 throw new RuntimeException("We shouldn't reach here"); |
160 } |
160 } |
161 |
161 |
162 private static void checkSignature(byte[] data, PublicKey pub, |
162 private static void checkSignature(byte[] data, PublicKey pub, |
163 PrivateKey priv, String sigalg) throws NoSuchAlgorithmException, |
163 PrivateKey priv, String sigAlg, AlgorithmParameterSpec sigParams) |
164 InvalidKeyException, SignatureException, NoSuchProviderException { |
164 throws NoSuchAlgorithmException, InvalidKeyException, |
165 Signature sig = Signature.getInstance(sigalg, PROVIDER); |
165 SignatureException, NoSuchProviderException, |
|
166 InvalidAlgorithmParameterException { |
|
167 System.out.println("Testing " + sigAlg); |
|
168 Signature sig = Signature.getInstance(sigAlg, PROVIDER); |
|
169 sig.setParameter(sigParams); |
|
170 |
166 sig.initSign(priv); |
171 sig.initSign(priv); |
167 for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { |
172 for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { |
168 sig.update(data); |
173 sig.update(data); |
169 } |
174 } |
170 byte[] signedData = sig.sign(); |
175 byte[] signedData = sig.sign(); |
171 |
176 |
172 // Make sure signature verifies with original data |
177 // Make sure signature verifies with original data |
|
178 sig.setParameter(sigParams); |
173 sig.initVerify(pub); |
179 sig.initVerify(pub); |
174 for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { |
180 for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) { |
175 sig.update(data); |
181 sig.update(data); |
176 } |
182 } |
177 if (!sig.verify(signedData)) { |
183 if (!sig.verify(signedData)) { |
178 throw new RuntimeException("Failed to verify " + sigalg |
184 throw new RuntimeException("Failed to verify " + sigAlg |
179 + " signature"); |
185 + " signature"); |
180 } |
186 } |
181 |
187 |
182 // Make sure signature does NOT verify when the original data |
188 // Make sure signature does NOT verify when the original data |
183 // has changed |
189 // has changed |