Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/ssl/ExtendedMasterSecretExtension.java
41159 views
1
/*
2
* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.
3
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation. Oracle designates this
9
* particular file as subject to the "Classpath" exception as provided
10
* by Oracle in the LICENSE file that accompanied this code.
11
*
12
* This code is distributed in the hope that it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15
* version 2 for more details (a copy is included in the LICENSE file that
16
* accompanied this code).
17
*
18
* You should have received a copy of the GNU General Public License version
19
* 2 along with this work; if not, write to the Free Software Foundation,
20
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21
*
22
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23
* or visit www.oracle.com if you need additional information or have any
24
* questions.
25
*/
26
27
package sun.security.ssl;
28
29
import java.io.IOException;
30
import java.nio.ByteBuffer;
31
import javax.net.ssl.SSLProtocolException;
32
import static sun.security.ssl.SSLExtension.CH_EXTENDED_MASTER_SECRET;
33
import sun.security.ssl.SSLExtension.ExtensionConsumer;
34
import static sun.security.ssl.SSLExtension.SH_EXTENDED_MASTER_SECRET;
35
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
36
import sun.security.ssl.SSLHandshake.HandshakeMessage;
37
38
/**
39
* Pack of the "extended_master_secret" extensions [RFC 7627].
40
*/
41
final class ExtendedMasterSecretExtension {
42
static final HandshakeProducer chNetworkProducer =
43
new CHExtendedMasterSecretProducer();
44
static final ExtensionConsumer chOnLoadConsumer =
45
new CHExtendedMasterSecretConsumer();
46
static final HandshakeAbsence chOnLoadAbsence =
47
new CHExtendedMasterSecretAbsence();
48
49
static final HandshakeProducer shNetworkProducer =
50
new SHExtendedMasterSecretProducer();
51
static final ExtensionConsumer shOnLoadConsumer =
52
new SHExtendedMasterSecretConsumer();
53
static final HandshakeAbsence shOnLoadAbsence =
54
new SHExtendedMasterSecretAbsence();
55
56
static final SSLStringizer emsStringizer =
57
new ExtendedMasterSecretStringizer();
58
59
/**
60
* The "extended_master_secret" extension.
61
*/
62
static final class ExtendedMasterSecretSpec implements SSLExtensionSpec {
63
// A nominal object that does not holding any real renegotiation info.
64
static final ExtendedMasterSecretSpec NOMINAL =
65
new ExtendedMasterSecretSpec();
66
67
private ExtendedMasterSecretSpec() {
68
// blank
69
}
70
71
private ExtendedMasterSecretSpec(HandshakeContext hc,
72
ByteBuffer m) throws IOException {
73
// Parse the extension.
74
if (m.hasRemaining()) {
75
throw hc.conContext.fatal(Alert.DECODE_ERROR,
76
new SSLProtocolException(
77
"Invalid extended_master_secret extension data: " +
78
"not empty"));
79
}
80
}
81
82
@Override
83
public String toString() {
84
return "<empty>";
85
}
86
}
87
88
private static final
89
class ExtendedMasterSecretStringizer implements SSLStringizer {
90
@Override
91
public String toString(HandshakeContext hc, ByteBuffer buffer) {
92
try {
93
return (new ExtendedMasterSecretSpec(hc, buffer)).toString();
94
} catch (IOException ioe) {
95
// For debug logging only, so please swallow exceptions.
96
return ioe.getMessage();
97
}
98
}
99
}
100
101
/**
102
* Network data producer of a "extended_master_secret" extension in
103
* the ClientHello handshake message.
104
*/
105
private static final
106
class CHExtendedMasterSecretProducer implements HandshakeProducer {
107
// Prevent instantiation of this class.
108
private CHExtendedMasterSecretProducer() {
109
// blank
110
}
111
112
@Override
113
public byte[] produce(ConnectionContext context,
114
HandshakeMessage message) throws IOException {
115
// The producing happens in client side only.
116
ClientHandshakeContext chc = (ClientHandshakeContext)context;
117
118
// Is it a supported and enabled extension?
119
if (!chc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||
120
!SSLConfiguration.useExtendedMasterSecret ||
121
!chc.conContext.protocolVersion.useTLS10PlusSpec()) {
122
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
123
SSLLogger.fine(
124
"Ignore unavailable extended_master_secret extension");
125
}
126
127
return null;
128
}
129
130
if (chc.handshakeSession == null ||
131
chc.handshakeSession.useExtendedMasterSecret) {
132
byte[] extData = new byte[0];
133
chc.handshakeExtensions.put(CH_EXTENDED_MASTER_SECRET,
134
ExtendedMasterSecretSpec.NOMINAL);
135
136
return extData;
137
}
138
139
return null;
140
}
141
}
142
143
/**
144
* Network data producer of a "extended_master_secret" extension in
145
* the ServerHello handshake message.
146
*/
147
private static final
148
class CHExtendedMasterSecretConsumer implements ExtensionConsumer {
149
// Prevent instantiation of this class.
150
private CHExtendedMasterSecretConsumer() {
151
// blank
152
}
153
154
@Override
155
public void consume(ConnectionContext context,
156
HandshakeMessage message, ByteBuffer buffer) throws IOException {
157
158
// The consuming happens in server side only.
159
ServerHandshakeContext shc = (ServerHandshakeContext)context;
160
161
// Is it a supported and enabled extension?
162
if (!shc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||
163
!SSLConfiguration.useExtendedMasterSecret ||
164
!shc.negotiatedProtocol.useTLS10PlusSpec()) {
165
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
166
SSLLogger.fine("Ignore unavailable extension: " +
167
CH_EXTENDED_MASTER_SECRET.name);
168
}
169
return; // ignore the extension
170
}
171
172
// Parse the extension.
173
ExtendedMasterSecretSpec spec =
174
new ExtendedMasterSecretSpec(shc, buffer);
175
if (shc.isResumption && shc.resumingSession != null &&
176
!shc.resumingSession.useExtendedMasterSecret) {
177
// For abbreviated handshake request, If the original
178
// session did not use the "extended_master_secret"
179
// extension but the new ClientHello contains the
180
// extension, then the server MUST NOT perform the
181
// abbreviated handshake. Instead, it SHOULD continue
182
// with a full handshake.
183
shc.isResumption = false;
184
shc.resumingSession = null;
185
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
186
SSLLogger.fine(
187
"abort session resumption which did not use " +
188
"Extended Master Secret extension");
189
}
190
}
191
192
// Update the context.
193
//
194
shc.handshakeExtensions.put(
195
CH_EXTENDED_MASTER_SECRET, ExtendedMasterSecretSpec.NOMINAL);
196
197
// No impact on session resumption.
198
}
199
}
200
201
/**
202
* The absence processing if a "extended_master_secret" extension is
203
* not present in the ClientHello handshake message.
204
*/
205
private static final
206
class CHExtendedMasterSecretAbsence implements HandshakeAbsence {
207
@Override
208
public void absent(ConnectionContext context,
209
HandshakeMessage message) throws IOException {
210
// The producing happens in server side only.
211
ServerHandshakeContext shc = (ServerHandshakeContext)context;
212
213
// Is it a supported and enabled extension?
214
if (!shc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||
215
!SSLConfiguration.useExtendedMasterSecret) {
216
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
217
SSLLogger.fine("Ignore unavailable extension: " +
218
CH_EXTENDED_MASTER_SECRET.name);
219
}
220
return; // ignore the extension
221
}
222
223
if (shc.negotiatedProtocol.useTLS10PlusSpec() &&
224
!SSLConfiguration.allowLegacyMasterSecret) {
225
// For full handshake, if the server receives a ClientHello
226
// without the extension, it SHOULD abort the handshake if
227
// it does not wish to interoperate with legacy clients.
228
//
229
// As if extended master extension is required for full
230
// handshake, it MUST be used in abbreviated handshake too.
231
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
232
"Extended Master Secret extension is required");
233
}
234
235
if (shc.isResumption && shc.resumingSession != null) {
236
if (shc.resumingSession.useExtendedMasterSecret) {
237
// For abbreviated handshake request, if the original
238
// session used the "extended_master_secret" extension
239
// but the new ClientHello does not contain it, the
240
// server MUST abort the abbreviated handshake.
241
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
242
"Missing Extended Master Secret extension " +
243
"on session resumption");
244
} else {
245
// For abbreviated handshake request, if neither the
246
// original session nor the new ClientHello uses the
247
// extension, the server SHOULD abort the handshake.
248
if (!SSLConfiguration.allowLegacyResumption) {
249
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
250
"Missing Extended Master Secret extension " +
251
"on session resumption");
252
} else { // Otherwise, continue with a full handshake.
253
shc.isResumption = false;
254
shc.resumingSession = null;
255
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
256
SSLLogger.fine(
257
"abort session resumption, " +
258
"missing Extended Master Secret extension");
259
}
260
}
261
}
262
}
263
}
264
}
265
266
/**
267
* Network data producer of a "extended_master_secret" extension in
268
* the ServerHello handshake message.
269
*/
270
private static final
271
class SHExtendedMasterSecretProducer implements HandshakeProducer {
272
// Prevent instantiation of this class.
273
private SHExtendedMasterSecretProducer() {
274
// blank
275
}
276
277
@Override
278
public byte[] produce(ConnectionContext context,
279
HandshakeMessage message) throws IOException {
280
// The producing happens in server side only.
281
ServerHandshakeContext shc = (ServerHandshakeContext)context;
282
283
if (shc.handshakeSession.useExtendedMasterSecret) {
284
byte[] extData = new byte[0];
285
shc.handshakeExtensions.put(SH_EXTENDED_MASTER_SECRET,
286
ExtendedMasterSecretSpec.NOMINAL);
287
288
return extData;
289
}
290
291
return null;
292
}
293
}
294
295
/**
296
* Network data consumer of a "extended_master_secret" extension in
297
* the ServerHello handshake message.
298
*/
299
private static final
300
class SHExtendedMasterSecretConsumer implements ExtensionConsumer {
301
// Prevent instantiation of this class.
302
private SHExtendedMasterSecretConsumer() {
303
// blank
304
}
305
306
@Override
307
public void consume(ConnectionContext context,
308
HandshakeMessage message, ByteBuffer buffer) throws IOException {
309
// The producing happens in client side only.
310
ClientHandshakeContext chc = (ClientHandshakeContext)context;
311
312
// In response to the client extended_master_secret extension
313
// request, which is mandatory for ClientHello message.
314
ExtendedMasterSecretSpec requstedSpec = (ExtendedMasterSecretSpec)
315
chc.handshakeExtensions.get(CH_EXTENDED_MASTER_SECRET);
316
if (requstedSpec == null) {
317
throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
318
"Server sent the extended_master_secret " +
319
"extension improperly");
320
}
321
322
// Parse the extension.
323
ExtendedMasterSecretSpec spec =
324
new ExtendedMasterSecretSpec(chc, buffer);
325
if (chc.isResumption && chc.resumingSession != null &&
326
!chc.resumingSession.useExtendedMasterSecret) {
327
throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,
328
"Server sent an unexpected extended_master_secret " +
329
"extension on session resumption");
330
}
331
332
// Update the context.
333
chc.handshakeExtensions.put(
334
SH_EXTENDED_MASTER_SECRET, ExtendedMasterSecretSpec.NOMINAL);
335
336
// No impact on session resumption.
337
}
338
}
339
340
/**
341
* The absence processing if a "extended_master_secret" extension is
342
* not present in the ServerHello handshake message.
343
*/
344
private static final
345
class SHExtendedMasterSecretAbsence implements HandshakeAbsence {
346
@Override
347
public void absent(ConnectionContext context,
348
HandshakeMessage message) throws IOException {
349
// The producing happens in client side only.
350
ClientHandshakeContext chc = (ClientHandshakeContext)context;
351
352
if (SSLConfiguration.useExtendedMasterSecret &&
353
!SSLConfiguration.allowLegacyMasterSecret) {
354
// For full handshake, if a client receives a ServerHello
355
// without the extension, it SHOULD abort the handshake if
356
// it does not wish to interoperate with legacy servers.
357
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
358
"Extended Master Secret extension is required");
359
}
360
361
if (chc.isResumption && chc.resumingSession != null) {
362
if (chc.resumingSession.useExtendedMasterSecret) {
363
// For abbreviated handshake, if the original session used
364
// the "extended_master_secret" extension but the new
365
// ServerHello does not contain the extension, the client
366
// MUST abort the handshake.
367
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
368
"Missing Extended Master Secret extension " +
369
"on session resumption");
370
} else if (SSLConfiguration.useExtendedMasterSecret &&
371
!SSLConfiguration.allowLegacyResumption &&
372
chc.negotiatedProtocol.useTLS10PlusSpec()) {
373
// Unlikely, abbreviated handshake should be discarded.
374
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
375
"Extended Master Secret extension is required");
376
}
377
}
378
}
379
}
380
}
381
382
383