Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ec/ECDSAJavaVerify.java
41149 views
1
/*
2
* Copyright (c) 2020, 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 com.sun.jdi.Bootstrap;
25
import com.sun.jdi.VMDisconnectedException;
26
import com.sun.jdi.VirtualMachine;
27
import com.sun.jdi.connect.Connector;
28
import com.sun.jdi.connect.LaunchingConnector;
29
import com.sun.jdi.event.Event;
30
import com.sun.jdi.event.EventSet;
31
import com.sun.jdi.event.MethodEntryEvent;
32
import com.sun.jdi.request.MethodEntryRequest;
33
34
import java.security.AlgorithmParameters;
35
import java.security.KeyPair;
36
import java.security.KeyPairGenerator;
37
import java.security.SecureRandom;
38
import java.security.Signature;
39
import java.security.SignatureException;
40
import java.security.interfaces.ECPrivateKey;
41
import java.security.interfaces.ECPublicKey;
42
import java.security.spec.ECGenParameterSpec;
43
import java.security.spec.ECParameterSpec;
44
import java.util.Arrays;
45
import java.util.List;
46
import java.util.Map;
47
import java.util.Random;
48
49
/*
50
* @test
51
* @bug 8237218 8239928
52
* @modules jdk.crypto.ec
53
* jdk.jdi
54
* @requires os.family != "windows"
55
* @run main ECDSAJavaVerify debug
56
* @summary Support NIST Curves verification in java implementation.
57
* This test does not run stable on Windows. VMDisconnectedException
58
* might not be thrown at all.
59
*/
60
61
// ATTENTION: This test depends on method names inside the non-exported
62
// class sun.security.ec.ECDSASignature.
63
public class ECDSAJavaVerify {
64
65
static final String[] ALL_ALGS = new String[] {
66
"SHA1withECDSA", "SHA256withECDSA", "SHA384withECDSA", "SHA512withECDSA"};
67
68
static final String[] ALL_CURVES = new String[] {
69
"secp256r1", "secp384r1", "secp521r1"};
70
71
public static void main(String[] args) throws Exception {
72
if (args.length == 1) {
73
// Debugging a new process with no arg
74
debug();
75
} else if (args.length == 3) {
76
// If one test case fail, re-run it with first 3 columns
77
new Test().run(Integer.parseInt(args[0]), args[1], args[2]);
78
} else {
79
// Run all test cases
80
Test t = new Test();
81
Random r = new Random();
82
83
for (String sigAlg : ALL_ALGS) {
84
for (String curve : ALL_CURVES) {
85
t.run(r.nextInt(1000000), sigAlg, curve);
86
}
87
}
88
}
89
}
90
91
static void debug() throws Exception {
92
93
LaunchingConnector launchingConnector = Bootstrap
94
.virtualMachineManager().defaultConnector();
95
96
Map<String, Connector.Argument> arguments
97
= launchingConnector.defaultArguments();
98
arguments.get("main").setValue(ECDSAJavaVerify.class.getName());
99
arguments.get("options").setValue(
100
"-cp " + System.getProperty("test.classes"));
101
VirtualMachine vm = launchingConnector.launch(arguments);
102
103
MethodEntryRequest req = vm.eventRequestManager()
104
.createMethodEntryRequest();
105
req.addClassFilter("sun.security.ec.ECDSASignature");
106
req.enable();
107
108
int numberOfTests = ALL_ALGS.length * ALL_CURVES.length * 2;
109
110
// Expected methods to call. 'J' for java impl, 'N' for native impl
111
char[] expected = new char[numberOfTests];
112
113
int pos = 0;
114
for (String dummy : ALL_ALGS) {
115
for (String curve : ALL_CURVES) {
116
char caller = 'J';
117
// For each case, Signature::verify is called twice
118
expected[pos++] = caller;
119
expected[pos++] = caller;
120
}
121
}
122
123
// Test result
124
// '.': not run yet
125
// '-': enter engineVerify
126
// 'v': expected impl called
127
// 'x': unexpected impl called
128
// Note: some error cases fail before any impl called. Ex: if there
129
// is a DER encoding error.
130
char[] result = new char[numberOfTests];
131
Arrays.fill(result, '.');
132
133
String stdout, stderr;
134
135
try {
136
EventSet eventSet;
137
pos = -1; // will become 0 when entering 'engineVerify'
138
while ((eventSet = vm.eventQueue().remove()) != null) {
139
for (Event event : eventSet) {
140
if (event instanceof MethodEntryEvent) {
141
MethodEntryEvent e = (MethodEntryEvent)event;
142
switch (e.method().name()) {
143
case "engineVerify":
144
result[++pos] = '-';
145
break;
146
case "verifySignedDigestImpl": // the java impl
147
result[pos] = expected[pos] != 'J' ? 'x' : 'v';
148
break;
149
}
150
}
151
vm.resume();
152
}
153
}
154
} catch (VMDisconnectedException e) {
155
System.out.println("Virtual Machine is disconnected.");
156
} finally {
157
stderr = new String(vm.process().getErrorStream().readAllBytes());
158
stdout = new String(vm.process().getInputStream().readAllBytes());
159
}
160
161
int exitCode = vm.process().waitFor();
162
System.out.println(" exit: " + exitCode);
163
System.out.println("stderr:\n" + stderr);
164
System.out.println("stdout:\n" + stdout);
165
166
String sResult = new String(result);
167
168
System.out.println(" Cases: " + new String(expected));
169
System.out.println("Result: " + sResult);
170
171
if (pos != numberOfTests - 1 || sResult.contains("x")
172
|| sResult.contains(".")) {
173
throw new Exception("Unexpected result");
174
}
175
176
if (stdout.contains("fail") || exitCode != 0) {
177
throw new Exception("Test failed");
178
}
179
}
180
181
static class Test {
182
183
public boolean run(int seed, String sigAlg, String curve)
184
throws Exception {
185
186
// A determined SecureRandom based on seed. If there is anything
187
// wrong, we can reproduce the problem using the seed.
188
Random r = new Random(seed);
189
SecureRandom rand = new SecureRandom() {
190
@Override
191
public void nextBytes(byte[] bytes) {
192
r.nextBytes(bytes);
193
}
194
};
195
196
AlgorithmParameters ap = AlgorithmParameters.getInstance("EC", "SunEC");
197
ap.init(new ECGenParameterSpec(curve));
198
ECParameterSpec spec = ap.getParameterSpec(ECParameterSpec.class);
199
200
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", "SunEC");
201
kpg.initialize(spec, rand);
202
KeyPair kp = kpg.generateKeyPair();
203
ECPrivateKey ecPrivateKey = (ECPrivateKey) kp.getPrivate();
204
ECPublicKey ecPublicKey = (ECPublicKey) kp.getPublic();
205
206
Signature s1 = Signature.getInstance(sigAlg, "SunEC");
207
s1.initSign(ecPrivateKey, rand);
208
byte[] msg = new byte[1234];
209
rand.nextBytes(msg);
210
s1.update(msg);
211
byte[] sig = s1.sign();
212
213
Signature s2 = Signature.getInstance(sigAlg, "SunEC");
214
s2.initVerify(ecPublicKey);
215
s2.update(msg);
216
217
boolean result1 = s2.verify(sig);
218
219
s2.initVerify(ecPublicKey);
220
// modify the signature in some random manner
221
if (rand.nextInt(10) < 8) {
222
sig[rand.nextInt(10000) % sig.length]
223
= (byte) rand.nextInt(10000);
224
} else {
225
int newLength = rand.nextInt(100);
226
if (newLength == sig.length) {
227
newLength += 1 + rand.nextInt(2);
228
}
229
sig = Arrays.copyOf(sig, newLength);
230
}
231
232
boolean result2;
233
try {
234
result2 = s2.verify(sig);
235
} catch (SignatureException se) {
236
result2 = false;
237
}
238
239
boolean finalResult = result1 && !result2;
240
System.out.printf("%10d %20s %20s -- %5s %5s -- %s\n",
241
seed, sigAlg, curve, result1, result2,
242
finalResult ? "succeed" : "fail");
243
244
return finalResult;
245
}
246
}
247
}
248
249