Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/security/KeyAgreement/KeySpecTest.java
41149 views
1
/*
2
* Copyright (c) 2018, 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
/*
25
* @test
26
* @bug 8184359
27
* @summary Standard tests on KeySpec, KeyFactory, KeyPairs and Keys.
28
* Arguments order <KeyExchangeAlgorithm> <Provider> <KeyGenAlgorithm> <Curve*>
29
* @run main KeySpecTest DiffieHellman SunJCE DiffieHellman
30
* @run main KeySpecTest ECDH SunEC EC
31
* @run main KeySpecTest XDH SunEC XDH X25519
32
* @run main KeySpecTest XDH SunEC XDH X448
33
*/
34
import java.io.ByteArrayInputStream;
35
import java.io.ByteArrayOutputStream;
36
import java.io.IOException;
37
import java.io.ObjectInputStream;
38
import java.io.ObjectOutputStream;
39
import java.security.KeyFactory;
40
import java.security.KeyPair;
41
import java.security.KeyPairGenerator;
42
import java.security.PrivateKey;
43
import java.security.PublicKey;
44
import java.security.spec.ECPrivateKeySpec;
45
import java.security.spec.ECPublicKeySpec;
46
import java.security.spec.PKCS8EncodedKeySpec;
47
import java.security.spec.X509EncodedKeySpec;
48
import java.security.spec.NamedParameterSpec;
49
import java.security.spec.XECPublicKeySpec;
50
import java.security.spec.XECPrivateKeySpec;
51
import java.security.spec.KeySpec;
52
import java.util.ArrayList;
53
import java.util.List;
54
import java.util.Arrays;
55
import javax.crypto.KeyAgreement;
56
import javax.crypto.spec.DHPrivateKeySpec;
57
import javax.crypto.spec.DHPublicKeySpec;
58
59
public class KeySpecTest {
60
61
public static void main(String[] args) throws Exception {
62
63
String kaAlgo = args[0];
64
String provider = args[1];
65
String kpgAlgo = args[2];
66
KeyPair kp = genKeyPair(provider, kpgAlgo,
67
(args.length > 3) ? args[3] : kpgAlgo);
68
testKeySpecs(provider, kaAlgo, kpgAlgo, kp);
69
testEncodedKeySpecs(provider, kaAlgo, kpgAlgo, kp);
70
}
71
72
/**
73
* Generate keyPair based on KeyPairGenerator algorithm.
74
*/
75
private static KeyPair genKeyPair(String provider, String kpgAlgo,
76
String kpgInit) throws Exception {
77
78
KeyPairGenerator kpg = KeyPairGenerator.getInstance(kpgAlgo, provider);
79
switch (kpgInit) {
80
case "DiffieHellman":
81
kpg.initialize(512);
82
break;
83
case "EC":
84
kpg.initialize(256);
85
break;
86
case "X25519":
87
kpg.initialize(255);
88
break;
89
case "X448":
90
kpg.initialize(448);
91
break;
92
default:
93
throw new RuntimeException("Invalid Algo name " + kpgInit);
94
}
95
return kpg.generateKeyPair();
96
}
97
98
/**
99
* Standard Test with Keys and the one generated through Spec.
100
*/
101
private static void testKeySpecs(String provider, String kaAlgo,
102
String kpgAlgo, KeyPair kp) throws Exception {
103
104
KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);
105
// For each public KeySpec supported by KeyPairGenerator
106
for (Class pubSpecType
107
: getCompatibleKeySpecs(kpgAlgo, KeyType.PUBLIC)) {
108
//For each private KeySpec supported by KeyPairGenerator
109
for (Class priSpecType
110
: getCompatibleKeySpecs(kpgAlgo, KeyType.PRIVATE)) {
111
// Transform original PublicKey through KeySpec
112
KeySpec pubSpec = kf.getKeySpec(kp.getPublic(), pubSpecType);
113
PublicKey pubKey = kf.generatePublic(pubSpec);
114
// Transform original PrivateKey through KeySpec
115
KeySpec priSpec = kf.getKeySpec(kp.getPrivate(), priSpecType);
116
PrivateKey priKey = kf.generatePrivate(priSpec);
117
118
// Test the keys are equal after transformation through KeySpec.
119
testKeyEquals(kp, pubKey, priKey);
120
// Test the keys are serializable.
121
testSerialize(kp);
122
// Test Parameter name.
123
if (!kaAlgo.equals("DiffieHellman")) {
124
testParamName(priSpec, pubSpec);
125
}
126
// Compare KeyAgreement secret generated from original keys
127
// and by the keys after transformed through KeySpec.
128
if (!Arrays.equals(getKeyAgreementSecret(provider, kaAlgo,
129
kp.getPublic(), kp.getPrivate()),
130
getKeyAgreementSecret(provider, kaAlgo,
131
pubKey, priKey))) {
132
throw new RuntimeException("KeyAgreement secret mismatch.");
133
}
134
}
135
}
136
}
137
138
/**
139
* Standard Test with Keys and the one generated from encoded bytes.
140
*/
141
private static void testEncodedKeySpecs(String provider, String kaAlgo,
142
String kpgAlgo, KeyPair kp) throws Exception {
143
144
KeyFactory kf = KeyFactory.getInstance(kpgAlgo, provider);
145
PKCS8EncodedKeySpec priSpec
146
= new PKCS8EncodedKeySpec(kp.getPrivate().getEncoded());
147
PrivateKey priKey = kf.generatePrivate(priSpec);
148
149
X509EncodedKeySpec pubSpec
150
= new X509EncodedKeySpec(kp.getPublic().getEncoded());
151
PublicKey pubKey = kf.generatePublic(pubSpec);
152
153
// Test the keys are equal after transformation through KeySpec.
154
testKeyEquals(kp, pubKey, priKey);
155
// Test the keys are serializable.
156
testSerialize(kp);
157
// Test Parameter name.
158
if (!kaAlgo.equals("DiffieHellman")) {
159
testParamName(priSpec, pubSpec);
160
}
161
// Compare KeyAgreement secret generated from original keys
162
// and by the keys after transformed through KeySpec.
163
if (!Arrays.equals(getKeyAgreementSecret(provider, kaAlgo,
164
kp.getPublic(), kp.getPrivate()),
165
getKeyAgreementSecret(provider, kaAlgo, pubKey, priKey))) {
166
throw new RuntimeException("KeyAgreement secret mismatch.");
167
}
168
}
169
170
private enum KeyType {
171
PUBLIC, PRIVATE;
172
}
173
174
/**
175
* Provides Compatible KeySpec Type list for KeyPairGenerator algorithm.
176
*/
177
private static List<Class> getCompatibleKeySpecs(String kpgAlgo,
178
KeyType type) {
179
180
List<Class> specs = new ArrayList<>();
181
switch (kpgAlgo) {
182
case "DiffieHellman":
183
if (type == KeyType.PUBLIC) {
184
return Arrays.asList(X509EncodedKeySpec.class,
185
DHPublicKeySpec.class);
186
} else {
187
return Arrays.asList(PKCS8EncodedKeySpec.class,
188
DHPrivateKeySpec.class);
189
}
190
case "EC":
191
if (type == KeyType.PUBLIC) {
192
return Arrays.asList(X509EncodedKeySpec.class,
193
ECPublicKeySpec.class);
194
} else {
195
return Arrays.asList(PKCS8EncodedKeySpec.class,
196
ECPrivateKeySpec.class);
197
}
198
case "XDH":
199
if (type == KeyType.PUBLIC) {
200
return Arrays.asList(X509EncodedKeySpec.class,
201
XECPublicKeySpec.class);
202
} else {
203
return Arrays.asList(PKCS8EncodedKeySpec.class,
204
XECPrivateKeySpec.class);
205
}
206
}
207
return specs;
208
}
209
210
/**
211
* Generate KeyAgreement Secret.
212
*/
213
private static byte[] getKeyAgreementSecret(String provider, String kaAlgo,
214
PublicKey pubKey, PrivateKey priKey) throws Exception {
215
216
KeyAgreement ka = KeyAgreement.getInstance(kaAlgo, provider);
217
ka.init(priKey);
218
ka.doPhase(pubKey, true);
219
return ka.generateSecret();
220
}
221
222
/**
223
* Compare original KeyPair with transformed ones.
224
*/
225
private static void testKeyEquals(KeyPair kp, PublicKey pubKey,
226
PrivateKey priKey) {
227
228
if (!kp.getPrivate().equals(priKey)
229
&& kp.getPrivate().hashCode() != priKey.hashCode()) {
230
throw new RuntimeException("PrivateKey is not equal with PrivateKey"
231
+ " generated through KeySpec");
232
}
233
if (!kp.getPublic().equals(pubKey)
234
&& kp.getPublic().hashCode() != pubKey.hashCode()) {
235
throw new RuntimeException("PublicKey is not equal with PublicKey"
236
+ " generated through KeySpec");
237
}
238
}
239
240
/**
241
* Compare the parameter names of Public/Private KeySpec from a pair.
242
*/
243
private static void testParamName(KeySpec priSpec, KeySpec pubSpec) {
244
245
if (priSpec instanceof XECPrivateKeySpec
246
&& pubSpec instanceof XECPublicKeySpec) {
247
if (((NamedParameterSpec) ((XECPrivateKeySpec) priSpec)
248
.getParams()).getName()
249
!= ((NamedParameterSpec) ((XECPublicKeySpec) pubSpec)
250
.getParams()).getName()) {
251
throw new RuntimeException("Curve name mismatch found");
252
}
253
}
254
}
255
256
/**
257
* Test serialization of KeyPair and Keys it holds.
258
*/
259
private static void testSerialize(KeyPair keyPair) throws Exception {
260
261
// Verify Serialized PrivateKey instance.
262
if (!keyPair.getPrivate().equals(
263
deserializedCopy(keyPair.getPrivate(), PrivateKey.class))) {
264
throw new RuntimeException("PrivateKey is not equal with PrivateKey"
265
+ " generated through Serialization");
266
}
267
// Verify Serialized PublicKey instance.
268
if (!keyPair.getPublic().equals(
269
deserializedCopy(keyPair.getPublic(), PublicKey.class))) {
270
throw new RuntimeException("PublicKey is not equal with PublicKey"
271
+ " generated through Serialization");
272
}
273
// Verify Serialized KeyPair instance.
274
KeyPair copy = deserializedCopy(keyPair, KeyPair.class);
275
if (!keyPair.getPrivate().equals(copy.getPrivate())) {
276
throw new RuntimeException("PrivateKey is not equal with PrivateKey"
277
+ " generated through Serialized KeyPair");
278
}
279
if (!keyPair.getPublic().equals(copy.getPublic())) {
280
throw new RuntimeException("PublicKey is not equal with PublicKey"
281
+ " generated through Serialized KeyPair");
282
}
283
}
284
285
private static <T extends Object> T deserializedCopy(T orig, Class<T> type)
286
throws IOException, ClassNotFoundException {
287
return deserialize(serialize(orig), type);
288
}
289
290
/**
291
* Deserialize the Key object.
292
*/
293
private static <T extends Object> T deserialize(byte[] serialized,
294
Class<T> type) throws IOException, ClassNotFoundException {
295
296
T key = null;
297
try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
298
ObjectInputStream ois = new ObjectInputStream(bis)) {
299
key = (T) ois.readObject();
300
}
301
return key;
302
}
303
304
/**
305
* Serialize the given Key object.
306
*/
307
private static <T extends Object> byte[] serialize(T key)
308
throws IOException {
309
310
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
311
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
312
oos.writeObject(key);
313
return bos.toByteArray();
314
}
315
}
316
}
317
318