Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ec/ed/EdDSATest.java
41152 views
1
/*
2
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
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
21
* questions.
22
*/
23
24
import static javax.crypto.Cipher.PRIVATE_KEY;
25
import static javax.crypto.Cipher.PUBLIC_KEY;
26
import java.io.ByteArrayInputStream;
27
import java.io.ByteArrayOutputStream;
28
import java.io.IOException;
29
import java.io.ObjectInputStream;
30
import java.io.ObjectOutputStream;
31
import java.security.InvalidKeyException;
32
import java.security.Key;
33
import java.security.KeyFactory;
34
import java.security.KeyPair;
35
import java.security.KeyPairGenerator;
36
import java.security.NoSuchAlgorithmException;
37
import java.security.NoSuchProviderException;
38
import java.security.PrivateKey;
39
import java.security.PublicKey;
40
import java.security.SecureRandom;
41
import java.security.Signature;
42
import java.security.interfaces.EdECPrivateKey;
43
import java.security.interfaces.EdECPublicKey;
44
import java.security.spec.PKCS8EncodedKeySpec;
45
import java.security.spec.X509EncodedKeySpec;
46
import java.security.spec.EdECPrivateKeySpec;
47
import java.security.spec.EdECPublicKeySpec;
48
import java.security.spec.InvalidKeySpecException;
49
import java.security.spec.NamedParameterSpec;
50
import java.security.spec.EdDSAParameterSpec;
51
import java.util.Arrays;
52
import java.util.HexFormat;
53
54
/*
55
* @test
56
* @bug 8209632
57
* @summary Test Signature with variation of serialized EDDSA Keys.
58
* @library /test/lib
59
* @build jdk.test.lib.Convert
60
* @run main EdDSATest
61
*/
62
public class EdDSATest {
63
64
private static final String EDDSA = "EdDSA";
65
private static final String ED25519 = "Ed25519";
66
private static final String ED448 = "Ed448";
67
private static final String OIDN25519 = "1.3.101.112";
68
private static final String OID25519 = "OID.1.3.101.112";
69
private static final String OIDN448 = "1.3.101.113";
70
private static final String OID448 = "OID.1.3.101.113";
71
private static final String PROVIDER = "SunEC";
72
private static final byte[] MSG = "TEST".getBytes();
73
private static final SecureRandom S_RND = new SecureRandom(new byte[]{0x1});
74
75
public static void main(String[] args) throws Exception {
76
77
for (boolean random : new boolean[]{true, false}) {
78
79
// Default Parameter
80
test(PROVIDER, EDDSA, null, random);
81
test(PROVIDER, ED25519, null, random);
82
test(PROVIDER, ED448, null, random);
83
84
// With named parameter
85
test(PROVIDER, EDDSA, ED25519, random);
86
test(PROVIDER, ED25519, ED25519, random);
87
test(PROVIDER, OIDN25519, ED25519, random);
88
test(PROVIDER, OID25519, ED25519, random);
89
test(PROVIDER, ED448, ED448, random);
90
test(PROVIDER, OIDN448, ED448, random);
91
test(PROVIDER, OID448, ED448, random);
92
93
// With size parameter
94
test(PROVIDER, EDDSA, 255, random);
95
test(PROVIDER, ED25519, 255, random);
96
test(PROVIDER, OIDN25519, 255, random);
97
test(PROVIDER, OID25519, 255, random);
98
test(PROVIDER, ED448, 448, random);
99
test(PROVIDER, OIDN448, 448, random);
100
test(PROVIDER, OID448, 448, random);
101
}
102
}
103
104
// Test signature using a KeyPair and the corresponding transformed one.
105
private static void test(String provider, String name, Object param,
106
boolean random) throws Exception {
107
108
System.out.printf("Case Algo:%s, Param:%s, Intitiate with random:%s%n",
109
name, param, random);
110
KeyPair origkp = genKeyPair(provider, name, param, random);
111
testSignature(provider, name, origkp, origkp);
112
NamedParameterSpec namedSpec = namedParamSpec(name);
113
// Test all possible transformed private/public keys
114
for (Key priKey : manipulateKey(provider, name, PRIVATE_KEY,
115
origkp.getPrivate(), namedSpec)) {
116
for (Key pubKey : manipulateKey(provider, name, PUBLIC_KEY,
117
origkp.getPublic(), namedSpec)) {
118
EdECPrivateKey pri = (EdECPrivateKey) priKey;
119
EdECPublicKey pub = (EdECPublicKey) pubKey;
120
// Test the keys are serializable.
121
testSerialize(origkp, new KeyPair(pub, pri));
122
// Test signature
123
testSignature(provider, name, origkp, new KeyPair(pub, pri));
124
}
125
}
126
System.out.println("Passed.");
127
}
128
129
private static KeyPair genKeyPair(String provider, String name,
130
Object param, boolean random) throws Exception {
131
132
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
133
if (random) {
134
if (param instanceof Integer) {
135
kpg.initialize((Integer) param, S_RND);
136
} else if (param instanceof String) {
137
kpg.initialize(new NamedParameterSpec((String) param), S_RND);
138
}
139
} else {
140
if (param instanceof Integer) {
141
kpg.initialize((Integer) param);
142
} else if (param instanceof String) {
143
kpg.initialize(new NamedParameterSpec((String) param));
144
}
145
}
146
equals(kpg.getProvider().getName(), provider);
147
equals(kpg.getAlgorithm(), name);
148
return kpg.generateKeyPair();
149
}
150
151
private static NamedParameterSpec namedParamSpec(String algo) {
152
NamedParameterSpec namedSpec = switch (algo) {
153
case EDDSA
154
, OIDN25519, OID25519 -> new NamedParameterSpec(ED25519);
155
case OIDN448
156
, OID448 -> new NamedParameterSpec(ED448);
157
default->
158
new NamedParameterSpec(algo);
159
};
160
return namedSpec;
161
}
162
163
private static Key[] manipulateKey(String provider, String name, int type,
164
Key key, NamedParameterSpec namedSpec)
165
throws NoSuchAlgorithmException, InvalidKeySpecException,
166
NoSuchProviderException, InvalidKeyException {
167
168
KeyFactory kf = KeyFactory.getInstance(name, provider);
169
switch (type) {
170
case PUBLIC_KEY:
171
return new Key[]{
172
kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
173
kf.generatePublic(kf.getKeySpec(
174
key, EdECPublicKeySpec.class)),
175
kf.generatePublic(new EdECPublicKeySpec(namedSpec,
176
((EdECPublicKey) key).getPoint())),
177
kf.translateKey(key)
178
};
179
case PRIVATE_KEY:
180
return new Key[]{
181
kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())),
182
kf.generatePrivate(
183
kf.getKeySpec(key, EdECPrivateKeySpec.class)),
184
kf.generatePrivate(new EdECPrivateKeySpec(namedSpec,
185
((EdECPrivateKey) key).getBytes().get())),
186
kf.translateKey(key)
187
};
188
}
189
throw new RuntimeException("We shouldn't reach here");
190
}
191
192
/**
193
* Test Signature with a set of parameter combination.
194
*/
195
private static void testSignature(String provider, String name,
196
KeyPair origkp, KeyPair kp) throws Exception {
197
198
signAndVerify(provider, name, origkp, kp, null);
199
// Test Case with Pre-Hash enabled and disabled.
200
for (boolean preHash : new boolean[]{true, false}) {
201
signAndVerify(provider, name, origkp, kp,
202
new EdDSAParameterSpec(preHash));
203
// Test Case with Context combined.
204
for (byte[] context : new byte[][]{
205
{}, "a".getBytes(), new byte[255]}) {
206
signAndVerify(provider, name, origkp, kp,
207
new EdDSAParameterSpec(preHash, context));
208
}
209
}
210
}
211
212
private static void signAndVerify(String provider, String name,
213
KeyPair origkp, KeyPair kp, EdDSAParameterSpec params)
214
throws Exception {
215
216
Signature sig = Signature.getInstance(name, provider);
217
if (params != null) {
218
sig.setParameter(params);
219
}
220
sig.initSign(origkp.getPrivate());
221
sig.update(MSG);
222
byte[] origSign = sig.sign();
223
224
sig.update(MSG);
225
byte[] computedSig = sig.sign();
226
equals(origSign, computedSig);
227
// EdDSA signatures size (64 and 114 bytes) for Ed25519 and Ed448.
228
int expectedSigSize = edSignatureSize(name);
229
equals(origSign.length, expectedSigSize);
230
sig.initSign(kp.getPrivate());
231
sig.update(MSG);
232
equals(computedSig, sig.sign());
233
// Use same signature instance to verify with transformed PublicKey.
234
sig.initVerify(kp.getPublic());
235
sig.update(MSG);
236
if (!sig.verify(origSign)) {
237
throw new RuntimeException(String.format("Signature did not verify"
238
+ " for name:%s, prehash:%s, context:%s", name,
239
(params == null) ? null : params.isPrehash(),
240
(params == null) ? null : params.getContext().get()));
241
}
242
243
// Create a new signature to re-verify.
244
sig = Signature.getInstance(name, provider);
245
if (params != null) {
246
sig.setParameter(params);
247
}
248
// Verify the signature with transformed PublicKey.
249
sig.initVerify(kp.getPublic());
250
sig.update(MSG);
251
if (!sig.verify(origSign)) {
252
throw new RuntimeException(String.format("Signature did not verify"
253
+ " for name:%s, prehash:%s, context:%s",
254
name, (params == null) ? null : params.isPrehash(),
255
(params == null) ? null : params.getContext().get()));
256
}
257
equals(sig.getAlgorithm(), name);
258
equals(sig.getProvider().getName(), provider);
259
}
260
261
private static int edSignatureSize(String algo) {
262
int size = switch (algo) {
263
case EDDSA
264
, ED25519, OIDN25519, OID25519 -> 64;
265
case ED448
266
, OIDN448, OID448 -> 114;
267
default->
268
-1;
269
};
270
return size;
271
}
272
273
/**
274
* Compare original KeyPair with transformed ones.
275
*/
276
private static void testKeyEquals(KeyPair origkp, PublicKey pubKey,
277
PrivateKey priKey) {
278
279
if (!origkp.getPrivate().equals(priKey)
280
&& !Arrays.equals(origkp.getPrivate().getEncoded(),
281
priKey.getEncoded())
282
&& origkp.getPrivate().hashCode() != priKey.hashCode()) {
283
throw new RuntimeException(
284
"PrivateKey is not equal with transformed one");
285
}
286
if (!origkp.getPublic().equals(pubKey)
287
&& !Arrays.equals(origkp.getPublic().getEncoded(),
288
pubKey.getEncoded())
289
&& origkp.getPublic().hashCode() != pubKey.hashCode()) {
290
throw new RuntimeException(
291
"PublicKey is not equal with transformed one");
292
}
293
}
294
295
/**
296
* Test serialization of KeyPair and Keys.
297
*/
298
private static void testSerialize(KeyPair origkp, KeyPair kp)
299
throws Exception {
300
301
testKeyEquals(origkp, kp.getPublic(), kp.getPrivate());
302
PrivateKey priv = deserializedCopy(kp.getPrivate(), PrivateKey.class);
303
PublicKey pub = deserializedCopy(kp.getPublic(), PublicKey.class);
304
testKeyEquals(origkp, pub, priv);
305
// Verify Serialized KeyPair instance.
306
KeyPair copy = deserializedCopy(kp, KeyPair.class);
307
testKeyEquals(origkp, copy.getPublic(), copy.getPrivate());
308
}
309
310
private static <T extends Object> T deserializedCopy(T origkp, Class<T> type)
311
throws IOException, ClassNotFoundException {
312
return deserialize(serialize(origkp), type);
313
}
314
315
/**
316
* Deserialize the Key object.
317
*/
318
private static <T extends Object> T deserialize(byte[] serialized,
319
Class<T> type) throws IOException, ClassNotFoundException {
320
321
T key = null;
322
try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
323
ObjectInputStream ois = new ObjectInputStream(bis)) {
324
key = (T) ois.readObject();
325
}
326
return key;
327
}
328
329
/**
330
* Serialize the given Key object.
331
*/
332
private static <T extends Object> byte[] serialize(T key)
333
throws IOException {
334
335
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
336
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
337
oos.writeObject(key);
338
return bos.toByteArray();
339
}
340
}
341
342
private static void equals(Object actual, Object expected) {
343
if (!actual.equals(expected)) {
344
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
345
actual, expected));
346
}
347
}
348
349
private static void equals(byte[] actual, byte[] expected) {
350
if (!Arrays.equals(actual, expected)) {
351
throw new RuntimeException(String.format("Actual array: %s, "
352
+ "Expected array:%s", HexFormat.of().withUpperCase().formatHex(actual),
353
HexFormat.of().withUpperCase().formatHex(expected)));
354
}
355
}
356
}
357
358