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/CertificateAuthoritiesExtension.java
41159 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. 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
package sun.security.ssl;
27
28
import java.io.IOException;
29
import java.nio.ByteBuffer;
30
import java.security.cert.X509Certificate;
31
import java.text.MessageFormat;
32
import java.util.*;
33
import javax.net.ssl.SSLProtocolException;
34
import javax.security.auth.x500.X500Principal;
35
import sun.security.ssl.SSLExtension.ExtensionConsumer;
36
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
37
import sun.security.ssl.SSLHandshake.HandshakeMessage;
38
39
/**
40
* Pack of the "certificate_authorities" extensions.
41
*/
42
final class CertificateAuthoritiesExtension {
43
static final HandshakeProducer chNetworkProducer =
44
new CHCertificateAuthoritiesProducer();
45
static final ExtensionConsumer chOnLoadConsumer =
46
new CHCertificateAuthoritiesConsumer();
47
48
static final HandshakeProducer crNetworkProducer =
49
new CRCertificateAuthoritiesProducer();
50
static final ExtensionConsumer crOnLoadConsumer =
51
new CRCertificateAuthoritiesConsumer();
52
53
static final SSLStringizer ssStringizer =
54
new CertificateAuthoritiesStringizer();
55
56
/**
57
* The "certificate_authorities" extension.
58
*/
59
static final class CertificateAuthoritiesSpec implements SSLExtensionSpec {
60
final List<byte[]> authorities; // certificate authorities
61
62
private CertificateAuthoritiesSpec(List<byte[]> authorities) {
63
this.authorities = authorities;
64
}
65
66
private CertificateAuthoritiesSpec(HandshakeContext hc,
67
ByteBuffer m) throws IOException {
68
if (m.remaining() < 3) { // 2: the length of the list
69
// 1: at least one byte authorities
70
throw hc.conContext.fatal(Alert.DECODE_ERROR,
71
new SSLProtocolException(
72
"Invalid certificate_authorities extension: " +
73
"insufficient data"));
74
}
75
76
int listLen = Record.getInt16(m);
77
if (listLen == 0) {
78
throw hc.conContext.fatal(Alert.DECODE_ERROR,
79
"Invalid certificate_authorities extension: " +
80
"no certificate authorities");
81
}
82
83
if (listLen > m.remaining()) {
84
throw hc.conContext.fatal(Alert.DECODE_ERROR,
85
"Invalid certificate_authorities extension: " +
86
"insufficient data");
87
}
88
89
this.authorities = new LinkedList<>();
90
while (listLen > 0) {
91
// opaque DistinguishedName<1..2^16-1>;
92
byte[] encoded = Record.getBytes16(m);
93
listLen -= (2 + encoded.length);
94
authorities.add(encoded);
95
}
96
}
97
98
private static List<byte[]> getEncodedAuthorities(
99
X509Certificate[] trustedCerts) {
100
List<byte[]> authorities = new ArrayList<>(trustedCerts.length);
101
int sizeAccount = 0;
102
for (X509Certificate cert : trustedCerts) {
103
X500Principal x500Principal = cert.getSubjectX500Principal();
104
byte[] encodedPrincipal = x500Principal.getEncoded();
105
sizeAccount += encodedPrincipal.length;
106
if (sizeAccount > 0xFFFF) { // the size limit of this extension
107
// If there too many trusts CAs such that they exceed the
108
// size limit of the extension, enabling this extension
109
// does not really make sense as there is no way to
110
// indicate the peer certificate selection accurately.
111
// In such cases, the extension is just ignored, rather
112
// than fatal close, for better compatibility and
113
// interoperability.
114
return Collections.emptyList();
115
}
116
117
if (encodedPrincipal.length != 0) {
118
authorities.add(encodedPrincipal);
119
}
120
}
121
122
return authorities;
123
}
124
125
X500Principal[] getAuthorities() {
126
X500Principal[] principals = new X500Principal[authorities.size()];
127
int i = 0;
128
for (byte[] encoded : authorities) {
129
principals[i++] = new X500Principal(encoded);
130
}
131
132
return principals;
133
}
134
135
@Override
136
public String toString() {
137
MessageFormat messageFormat = new MessageFormat(
138
"\"certificate authorities\": '['\n{0}']'", Locale.ENGLISH);
139
StringBuilder builder = new StringBuilder(512);
140
for (byte[] encoded : authorities) {
141
X500Principal principal = new X500Principal(encoded);
142
builder.append(principal.toString());
143
builder.append("\n");
144
}
145
Object[] messageFields = {
146
Utilities.indent(builder.toString())
147
};
148
149
return messageFormat.format(messageFields);
150
}
151
}
152
153
private static final
154
class CertificateAuthoritiesStringizer implements SSLStringizer {
155
@Override
156
public String toString(HandshakeContext hc, ByteBuffer buffer) {
157
try {
158
return (new CertificateAuthoritiesSpec(hc, buffer))
159
.toString();
160
} catch (IOException ioe) {
161
// For debug logging only, so please swallow exceptions.
162
return ioe.getMessage();
163
}
164
}
165
}
166
167
/**
168
* Network data producer of a "certificate_authorities" extension in
169
* the ClientHello handshake message.
170
*/
171
private static final
172
class CHCertificateAuthoritiesProducer implements HandshakeProducer {
173
174
// Prevent instantiation of this class.
175
private CHCertificateAuthoritiesProducer() {
176
// blank
177
}
178
179
@Override
180
public byte[] produce(ConnectionContext context,
181
HandshakeMessage message) throws IOException {
182
// The producing happens in client side only.
183
ClientHandshakeContext chc = (ClientHandshakeContext)context;
184
185
// Is it a supported and enabled extension?
186
if (!chc.sslConfig.isAvailable(
187
SSLExtension.CH_CERTIFICATE_AUTHORITIES)) {
188
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
189
SSLLogger.fine(
190
"Ignore unavailable " +
191
"certificate_authorities extension");
192
}
193
194
return null; // ignore the extension
195
}
196
197
// Produce the extension.
198
X509Certificate[] caCerts =
199
chc.sslContext.getX509TrustManager().getAcceptedIssuers();
200
if (caCerts.length == 0) {
201
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
202
SSLLogger.fine(
203
"No available certificate authorities");
204
}
205
206
return null; // ignore the extension
207
}
208
209
List<byte[]> encodedCAs =
210
CertificateAuthoritiesSpec.getEncodedAuthorities(caCerts);
211
if (encodedCAs.isEmpty()) {
212
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
213
SSLLogger.warning(
214
"The number of CAs exceeds the maximum size" +
215
"of the certificate_authorities extension");
216
}
217
218
return null; // ignore the extension
219
}
220
221
CertificateAuthoritiesSpec spec =
222
new CertificateAuthoritiesSpec(encodedCAs);
223
224
int vectorLen = 0;
225
for (byte[] encoded : spec.authorities) {
226
vectorLen += encoded.length + 2;
227
}
228
229
byte[] extData = new byte[vectorLen + 2];
230
ByteBuffer m = ByteBuffer.wrap(extData);
231
Record.putInt16(m, vectorLen);
232
for (byte[] encoded : spec.authorities) {
233
Record.putBytes16(m, encoded);
234
}
235
236
// Update the context.
237
chc.handshakeExtensions.put(
238
SSLExtension.CH_CERTIFICATE_AUTHORITIES, spec);
239
240
return extData;
241
}
242
}
243
244
/**
245
* Network data consumer of a "certificate_authorities" extension in
246
* the ClientHello handshake message.
247
*/
248
private static final
249
class CHCertificateAuthoritiesConsumer implements ExtensionConsumer {
250
251
// Prevent instantiation of this class.
252
private CHCertificateAuthoritiesConsumer() {
253
// blank
254
}
255
256
@Override
257
public void consume(ConnectionContext context,
258
HandshakeMessage message, ByteBuffer buffer) throws IOException {
259
260
// The consuming happens in server side only.
261
ServerHandshakeContext shc = (ServerHandshakeContext)context;
262
263
// Is it a supported and enabled extension?
264
if (!shc.sslConfig.isAvailable(
265
SSLExtension.CH_CERTIFICATE_AUTHORITIES)) {
266
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
267
SSLLogger.fine(
268
"Ignore unavailable " +
269
"certificate_authorities extension");
270
}
271
272
return; // ignore the extension
273
}
274
275
// Parse the extension.
276
CertificateAuthoritiesSpec spec =
277
new CertificateAuthoritiesSpec(shc, buffer);
278
279
// Update the context.
280
shc.peerSupportedAuthorities = spec.getAuthorities();
281
shc.handshakeExtensions.put(
282
SSLExtension.CH_CERTIFICATE_AUTHORITIES, spec);
283
284
// No impact on session resumption.
285
}
286
}
287
288
/**
289
* Network data producer of a "certificate_authorities" extension in
290
* the CertificateRequest handshake message.
291
*/
292
private static final
293
class CRCertificateAuthoritiesProducer implements HandshakeProducer {
294
295
// Prevent instantiation of this class.
296
private CRCertificateAuthoritiesProducer() {
297
// blank
298
}
299
300
@Override
301
public byte[] produce(ConnectionContext context,
302
HandshakeMessage message) throws IOException {
303
// The producing happens in server side only.
304
ServerHandshakeContext shc = (ServerHandshakeContext)context;
305
306
// Is it a supported and enabled extension?
307
if (!shc.sslConfig.isAvailable(
308
SSLExtension.CR_CERTIFICATE_AUTHORITIES)) {
309
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
310
SSLLogger.fine(
311
"Ignore unavailable " +
312
"certificate_authorities extension");
313
}
314
315
return null; // ignore the extension
316
}
317
318
// Produce the extension.
319
X509Certificate[] caCerts =
320
shc.sslContext.getX509TrustManager().getAcceptedIssuers();
321
if (caCerts.length == 0) {
322
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
323
SSLLogger.fine(
324
"No available certificate authorities");
325
}
326
327
return null; // ignore the extension
328
}
329
330
List<byte[]> encodedCAs =
331
CertificateAuthoritiesSpec.getEncodedAuthorities(caCerts);
332
if (encodedCAs.isEmpty()) {
333
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
334
SSLLogger.warning(
335
"Too many certificate authorities to use " +
336
"the certificate_authorities extension");
337
}
338
339
return null; // ignore the extension
340
}
341
342
CertificateAuthoritiesSpec spec =
343
new CertificateAuthoritiesSpec(encodedCAs);
344
345
int vectorLen = 0;
346
for (byte[] encoded : spec.authorities) {
347
vectorLen += encoded.length + 2;
348
}
349
350
byte[] extData = new byte[vectorLen + 2];
351
ByteBuffer m = ByteBuffer.wrap(extData);
352
Record.putInt16(m, vectorLen);
353
for (byte[] encoded : spec.authorities) {
354
Record.putBytes16(m, encoded);
355
}
356
357
// Update the context.
358
shc.handshakeExtensions.put(
359
SSLExtension.CR_CERTIFICATE_AUTHORITIES, spec);
360
361
return extData;
362
}
363
}
364
365
/**
366
* Network data consumer of a "certificate_authorities" extension in
367
* the CertificateRequest handshake message.
368
*/
369
private static final
370
class CRCertificateAuthoritiesConsumer implements ExtensionConsumer {
371
372
// Prevent instantiation of this class.
373
private CRCertificateAuthoritiesConsumer() {
374
// blank
375
}
376
377
@Override
378
public void consume(ConnectionContext context,
379
HandshakeMessage message, ByteBuffer buffer) throws IOException {
380
381
// The consuming happens in client side only.
382
ClientHandshakeContext chc = (ClientHandshakeContext)context;
383
384
// Is it a supported and enabled extension?
385
if (!chc.sslConfig.isAvailable(
386
SSLExtension.CR_CERTIFICATE_AUTHORITIES)) {
387
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
388
SSLLogger.fine(
389
"Ignore unavailable " +
390
"certificate_authorities extension");
391
}
392
393
return; // ignore the extension
394
}
395
396
// Parse the extension.
397
CertificateAuthoritiesSpec spec =
398
new CertificateAuthoritiesSpec(chc, buffer);
399
400
// Update the context.
401
chc.peerSupportedAuthorities = spec.getAuthorities();
402
chc.handshakeExtensions.put(
403
SSLExtension.CR_CERTIFICATE_AUTHORITIES, spec);
404
405
// No impact on session resumption.
406
}
407
}
408
}
409
410