Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/security/ssl/SignatureScheme/SigSchemePropOrdering.java
41152 views
1
/*
2
* Copyright (c) 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
//
27
// SunJSSE does not support dynamic system properties, no way to re-use
28
// system properties in samevm/agentvm mode.
29
//
30
31
/*
32
* @test
33
* @bug 8255867
34
* @summary SignatureScheme JSSE property does not preserve ordering in handshake messages
35
* @library /javax/net/ssl/templates
36
* @run main/othervm SigSchemePropOrdering
37
*/
38
39
import java.nio.ByteBuffer;
40
import java.util.*;
41
import java.util.AbstractMap.SimpleImmutableEntry;
42
import javax.net.ssl.SSLEngine;
43
import javax.net.ssl.SSLException;
44
45
public class SigSchemePropOrdering extends SSLEngineTemplate {
46
47
// Helper map to correlate integral SignatureScheme identifiers to
48
// their IANA string name counterparts.
49
static final Map<Integer, String> sigSchemeMap = Map.ofEntries(
50
new SimpleImmutableEntry(0x0401, "rsa_pkcs1_sha256"),
51
new SimpleImmutableEntry(0x0501, "rsa_pkcs1_sha384"),
52
new SimpleImmutableEntry(0x0601, "rsa_pkcs1_sha512"),
53
new SimpleImmutableEntry(0x0403, "ecdsa_secp256r1_sha256"),
54
new SimpleImmutableEntry(0x0503, "ecdsa_secp384r1_sha384"),
55
new SimpleImmutableEntry(0x0603, "ecdsa_secp521r1_sha512"),
56
new SimpleImmutableEntry(0x0804, "rsa_pss_rsae_sha256"),
57
new SimpleImmutableEntry(0x0805, "rsa_pss_rsae_sha384"),
58
new SimpleImmutableEntry(0x0806, "rsa_pss_rsae_sha512"),
59
new SimpleImmutableEntry(0x0807, "ed25519"),
60
new SimpleImmutableEntry(0x0808, "ed448"),
61
new SimpleImmutableEntry(0x0809, "rsa_pss_pss_sha256"),
62
new SimpleImmutableEntry(0x080a, "rsa_pss_pss_sha384"),
63
new SimpleImmutableEntry(0x080b, "rsa_pss_pss_sha512"),
64
new SimpleImmutableEntry(0x0101, "rsa_md5"),
65
new SimpleImmutableEntry(0x0201, "rsa_pkcs1_sha1"),
66
new SimpleImmutableEntry(0x0202, "dsa_sha1"),
67
new SimpleImmutableEntry(0x0203, "ecdsa_sha1"),
68
new SimpleImmutableEntry(0x0301, "rsa_sha224"),
69
new SimpleImmutableEntry(0x0302, "dsa_sha224"),
70
new SimpleImmutableEntry(0x0303, "ecdsa_sha224"),
71
new SimpleImmutableEntry(0x0402, "rsa_pkcs1_sha256"));
72
73
// Other useful TLS definitions for these tests
74
private static final int TLS_HS_CLI_HELLO = 1;
75
private static final int TLS_HS_CERT_REQ = 13;
76
private static final int HELLO_EXT_SIG_ALGS = 13;
77
78
private static final String SIG_SCHEME_STR =
79
"rsa_pkcs1_sha256,rsa_pss_rsae_sha256,rsa_pss_pss_sha256," +
80
"ed448,ed25519,ecdsa_secp256r1_sha256";
81
82
SigSchemePropOrdering() throws Exception {
83
super();
84
}
85
86
public static void main(String[] args) throws Exception {
87
System.setProperty("javax.net.debug", "ssl:handshake");
88
System.setProperty("jdk.tls.client.SignatureSchemes", SIG_SCHEME_STR);
89
System.setProperty("jdk.tls.server.SignatureSchemes", SIG_SCHEME_STR);
90
new SigSchemePropOrdering().run();
91
}
92
93
@Override
94
protected SSLEngine configureClientEngine(SSLEngine clientEngine) {
95
clientEngine.setUseClientMode(true);
96
clientEngine.setEnabledProtocols(new String[] { "TLSv1.2" });
97
return clientEngine;
98
}
99
100
@Override
101
protected SSLEngine configureServerEngine(SSLEngine serverEngine) {
102
serverEngine.setUseClientMode(false);
103
serverEngine.setWantClientAuth(true);
104
return serverEngine;
105
}
106
107
private void run() throws Exception {
108
// Start the handshake. Check the ClientHello's signature_algorithms
109
// extension and make sure the ordering matches what we specified
110
// in the property above.
111
List<String> expectedSS = Arrays.asList(SIG_SCHEME_STR.split(","));
112
113
clientEngine.wrap(clientOut, cTOs);
114
cTOs.flip();
115
116
List<String> actualSS = getSigSchemesCliHello(
117
extractHandshakeMsg(cTOs, TLS_HS_CLI_HELLO));
118
119
// Make sure the ordering is correct
120
if (!expectedSS.equals(actualSS)) {
121
System.out.println("FAIL: Mismatch between property ordering " +
122
"and ClientHello message");
123
System.out.print("Expected SigSchemes: ");
124
expectedSS.forEach(ss -> System.out.print(ss + " "));
125
System.out.println();
126
System.out.print("Actual SigSchemes: ");
127
actualSS.forEach(ss -> System.out.print(ss + " "));
128
System.out.println();
129
throw new RuntimeException(
130
"FAIL: Expected and Actual values differ.");
131
}
132
133
// Consume the ClientHello and get the server flight of handshake
134
// messages. We expect that it will be one TLS record containing
135
// multiple handshake messages, one of which is a CertificateRequest.
136
serverEngine.unwrap(cTOs, serverIn);
137
runDelegatedTasks(serverEngine);
138
139
// Wrap the server flight
140
serverEngine.wrap(serverOut, sTOc);
141
sTOc.flip();
142
143
actualSS = getSigSchemesCertReq(
144
extractHandshakeMsg(sTOc, TLS_HS_CERT_REQ));
145
146
// Make sure the ordering is correct
147
if (!expectedSS.equals(actualSS)) {
148
System.out.println("FAIL: Mismatch between property ordering " +
149
"and CertificateRequest message");
150
System.out.print("Expected SigSchemes: ");
151
expectedSS.forEach(ss -> System.out.print(ss + " "));
152
System.out.println();
153
System.out.print("Actual SigSchemes: ");
154
actualSS.forEach(ss -> System.out.print(ss + " "));
155
System.out.println();
156
throw new RuntimeException(
157
"FAIL: Expected and Actual values differ.");
158
}
159
}
160
161
/**
162
* Given a TLS record containing one or more handshake messages, return
163
* the specific handshake message as a ByteBuffer (a slice of the record)
164
*
165
* @param tlsRecord a ByteBuffer containing a TLS record. It is assumed
166
* that the position of the ByteBuffer is on the first byte of the TLS
167
* record header.
168
* @param hsMsgId the message identifier for the handshake message being
169
* sought.
170
*
171
* @return a ByteBuffer containing the TLS handshake message. The position
172
* of the returned ByteBuffer will be on the first byte of the TLS
173
* handshake message data, immediately following the handshake header.
174
* If the message is not found, null will be returned.
175
*
176
* @throws SSLException if the incoming ByteBuffer does not contain a
177
* well-formed TLS message.
178
*/
179
private static ByteBuffer extractHandshakeMsg(ByteBuffer tlsRecord,
180
int hsMsgId) throws SSLException {
181
Objects.requireNonNull(tlsRecord);
182
tlsRecord.mark();
183
184
// Process the TLS record header
185
int type = Byte.toUnsignedInt(tlsRecord.get());
186
int ver_major = Byte.toUnsignedInt(tlsRecord.get());
187
int ver_minor = Byte.toUnsignedInt(tlsRecord.get());
188
int recLen = Short.toUnsignedInt(tlsRecord.getShort());
189
190
// Simple sanity checks
191
if (type != 22) {
192
throw new SSLException("Not a handshake: Type = " + type);
193
} else if (recLen > tlsRecord.remaining()) {
194
throw new SSLException("Incomplete record in buffer: " +
195
"Record length = " + recLen + ", Remaining = " +
196
tlsRecord.remaining());
197
}
198
199
while (tlsRecord.hasRemaining()) {
200
// Grab the handshake message header.
201
int msgHdr = tlsRecord.getInt();
202
int msgType = (msgHdr >> 24) & 0x000000FF;
203
int msgLen = msgHdr & 0x00FFFFFF;
204
205
if (msgType == hsMsgId) {
206
// Slice the buffer such that it contains the entire
207
// handshake message (less the handshake header).
208
ByteBuffer buf = tlsRecord.slice(tlsRecord.position(), msgLen);
209
tlsRecord.reset();
210
return buf;
211
} else {
212
// Skip to the next handshake message, if there is one
213
tlsRecord.position(tlsRecord.position() + msgLen);
214
}
215
}
216
217
tlsRecord.reset();
218
return null;
219
}
220
221
222
/**
223
* Parses the ClientHello message and extracts from it a list of
224
* SignatureScheme values in string form. It is assumed that the provided
225
* ByteBuffer has its position set at the first byte of the ClientHello
226
* message body (AFTER the handshake header) and contains the entire
227
* hello message. Upon successful completion of this method the ByteBuffer
228
* will have its position reset to the initial offset in the buffer.
229
* If an exception is thrown the position at the time of the exception
230
* will be preserved.
231
*
232
* @param data the ByteBuffer containing the ClientHello bytes
233
*
234
* @returns A List of the signature schemes in string form. If no
235
* signature_algorithms extension is present in the client hello then
236
* an empty list will be returned.
237
*/
238
private static List<String> getSigSchemesCliHello(ByteBuffer data) {
239
Objects.requireNonNull(data);
240
data.mark();
241
242
// Skip over the protocol version and client random
243
data.position(data.position() + 34);
244
245
// Jump past the session ID (if there is one)
246
int sessLen = Byte.toUnsignedInt(data.get());
247
if (sessLen != 0) {
248
data.position(data.position() + sessLen);
249
}
250
251
// Jump past the cipher suites
252
int csLen = Short.toUnsignedInt(data.getShort());
253
if (csLen != 0) {
254
data.position(data.position() + csLen);
255
}
256
257
// ...and the compression
258
int compLen = Byte.toUnsignedInt(data.get());
259
if (compLen != 0) {
260
data.position(data.position() + compLen);
261
}
262
263
// Now for the fun part. Go through the extensions and look
264
// for the two status request exts.
265
List<String> extSigAlgs = new ArrayList();
266
int extsLen = Short.toUnsignedInt(data.getShort());
267
while (data.hasRemaining()) {
268
int extType = Short.toUnsignedInt(data.getShort());
269
int extLen = Short.toUnsignedInt(data.getShort());
270
if (extType == HELLO_EXT_SIG_ALGS) {
271
// Start processing signature algorithms
272
int sigSchemeLen = Short.toUnsignedInt(data.getShort());
273
for (int ssOff = 0; ssOff < sigSchemeLen; ssOff += 2) {
274
String schemeName = sigSchemeMap.get(
275
Short.toUnsignedInt(data.getShort()));
276
if (schemeName != null) {
277
extSigAlgs.add(schemeName);
278
}
279
}
280
} else {
281
// Not the extension we're looking for. Skip past the
282
// extension data
283
data.position(data.position() + extLen);
284
}
285
}
286
287
// We should be at the end of the ClientHello
288
data.reset();
289
return extSigAlgs;
290
}
291
292
/**
293
* Parses the CertificateRequest message and extracts from it a list of
294
* SignatureScheme values in string form. It is assumed that the provided
295
* ByteBuffer has its position set at the first byte of the
296
* CertificateRequest message body (AFTER the handshake header) and
297
* contains the entire CR message. Upon successful completion of this
298
* method the ByteBuffer will have its position reset to the initial
299
* offset in the buffer.
300
* If an exception is thrown the position at the time of the exception
301
* will be preserved.
302
*
303
* @param data the ByteBuffer containing the CertificateRequest bytes
304
*
305
* @returns A List of the signature schemes in string form. If no
306
* signature_algorithms extension is present in the CertificateRequest
307
* then an empty list will be returned.
308
*/
309
private static List<String> getSigSchemesCertReq(ByteBuffer data) {
310
Objects.requireNonNull(data);
311
data.mark();
312
313
// Jump past the certificate types
314
int certTypeLen = Byte.toUnsignedInt(data.get());
315
if (certTypeLen != 0) {
316
data.position(data.position() + certTypeLen);
317
}
318
319
// Collect the SignatureAndHashAlgorithms
320
List<String> extSigAlgs = new ArrayList();
321
int sigSchemeLen = Short.toUnsignedInt(data.getShort());
322
for (int ssOff = 0; ssOff < sigSchemeLen; ssOff += 2) {
323
String schemeName = sigSchemeMap.get(
324
Short.toUnsignedInt(data.getShort()));
325
if (schemeName != null) {
326
extSigAlgs.add(schemeName);
327
}
328
}
329
330
data.reset();
331
return extSigAlgs;
332
}
333
}
334
335