Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/validator/EndEntityChecker.java
41159 views
1
/*
2
* Copyright (c) 2002, 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.validator;
27
28
import java.util.*;
29
30
import java.security.cert.*;
31
import sun.security.util.KnownOIDs;
32
import sun.security.x509.NetscapeCertTypeExtension;
33
34
/**
35
* Class to check if an end entity cert is suitable for use in some
36
* context.<p>
37
*
38
* This class is used internally by the validator. Currently, seven variants
39
* are supported defined as VAR_XXX constants in the Validator class:
40
* <ul>
41
* <li>Generic. No additional requirements, all certificates are ok.
42
*
43
* <li>TLS server. Requires that a String parameter is passed to
44
* validate that specifies the name of the TLS key exchange algorithm
45
* in use. See the JSSE X509TrustManager spec for details.
46
*
47
* <li>TLS client.
48
*
49
* <li>Code signing.
50
*
51
* <li>JCE code signing. Some early JCE code signing certs issued to
52
* providers had incorrect extensions. In this mode the checks
53
* are relaxed compared to standard code signing checks in order to
54
* allow these certificates to pass.
55
*
56
* <li>Plugin code signing. WebStart and Plugin require their own variant
57
* which is equivalent to VAR_CODE_SIGNING with additional checks for
58
* compatibility/special cases. See also PKIXValidator.
59
*
60
* <li>TSA Server (see RFC 3161, section 2.3).
61
*
62
* </ul>
63
*
64
* @author Andreas Sterbenz
65
*/
66
class EndEntityChecker {
67
68
// extended key usage OIDs for TLS server, TLS client, code signing
69
// and any usage
70
71
private static final String OID_EXTENDED_KEY_USAGE =
72
SimpleValidator.OID_EXTENDED_KEY_USAGE;
73
74
private static final String OID_EKU_TLS_SERVER =
75
KnownOIDs.serverAuth.value();
76
77
private static final String OID_EKU_TLS_CLIENT =
78
KnownOIDs.clientAuth.value();
79
80
private static final String OID_EKU_CODE_SIGNING =
81
KnownOIDs.codeSigning.value();
82
83
private static final String OID_EKU_TIME_STAMPING =
84
KnownOIDs.KP_TimeStamping.value();
85
86
private static final String OID_EKU_ANY_USAGE =
87
KnownOIDs.anyExtendedKeyUsage.value();
88
89
// the Netscape Server-Gated-Cryptography EKU extension OID
90
private static final String OID_EKU_NS_SGC =
91
KnownOIDs.NETSCAPE_ExportApproved.value();
92
93
// the Microsoft Server-Gated-Cryptography EKU extension OID
94
private static final String OID_EKU_MS_SGC =
95
KnownOIDs.MICROSOFT_ExportApproved.value();
96
97
// the recognized extension OIDs
98
private static final String OID_SUBJECT_ALT_NAME =
99
KnownOIDs.SubjectAlternativeName.value();
100
101
private static final String NSCT_SSL_CLIENT =
102
NetscapeCertTypeExtension.SSL_CLIENT;
103
104
private static final String NSCT_SSL_SERVER =
105
NetscapeCertTypeExtension.SSL_SERVER;
106
107
private static final String NSCT_CODE_SIGNING =
108
NetscapeCertTypeExtension.OBJECT_SIGNING;
109
110
// bit numbers in the key usage extension
111
private static final int KU_SIGNATURE = 0;
112
private static final int KU_KEY_ENCIPHERMENT = 2;
113
private static final int KU_KEY_AGREEMENT = 4;
114
115
// TLS key exchange algorithms requiring digitalSignature key usage
116
private static final Collection<String> KU_SERVER_SIGNATURE =
117
Arrays.asList("DHE_DSS", "DHE_RSA", "ECDHE_ECDSA", "ECDHE_RSA",
118
"RSA_EXPORT", "UNKNOWN");
119
120
// TLS key exchange algorithms requiring keyEncipherment key usage
121
private static final Collection<String> KU_SERVER_ENCRYPTION =
122
Arrays.asList("RSA");
123
124
// TLS key exchange algorithms requiring keyAgreement key usage
125
private static final Collection<String> KU_SERVER_KEY_AGREEMENT =
126
Arrays.asList("DH_DSS", "DH_RSA", "ECDH_ECDSA", "ECDH_RSA");
127
128
// variant of this end entity cert checker
129
private final String variant;
130
131
// type of the validator this checker belongs to
132
private final String type;
133
134
private EndEntityChecker(String type, String variant) {
135
this.type = type;
136
this.variant = variant;
137
}
138
139
static EndEntityChecker getInstance(String type, String variant) {
140
return new EndEntityChecker(type, variant);
141
}
142
143
void check(X509Certificate[] chain, Object parameter,
144
boolean checkUnresolvedCritExts) throws CertificateException {
145
146
if (variant.equals(Validator.VAR_GENERIC)) {
147
return; // no checks
148
}
149
150
Set<String> exts = getCriticalExtensions(chain[0]);
151
if (variant.equals(Validator.VAR_TLS_SERVER)) {
152
checkTLSServer(chain[0], (String)parameter, exts);
153
} else if (variant.equals(Validator.VAR_TLS_CLIENT)) {
154
checkTLSClient(chain[0], exts);
155
} else if (variant.equals(Validator.VAR_CODE_SIGNING)) {
156
checkCodeSigning(chain[0], exts);
157
} else if (variant.equals(Validator.VAR_JCE_SIGNING)) {
158
checkCodeSigning(chain[0], exts);
159
} else if (variant.equals(Validator.VAR_PLUGIN_CODE_SIGNING)) {
160
checkCodeSigning(chain[0], exts);
161
} else if (variant.equals(Validator.VAR_TSA_SERVER)) {
162
checkTSAServer(chain[0], exts);
163
} else {
164
throw new CertificateException("Unknown variant: " + variant);
165
}
166
167
// if neither VAR_GENERIC variant nor unknown variant
168
if (checkUnresolvedCritExts) {
169
checkRemainingExtensions(exts);
170
}
171
172
// check if certificate should be distrusted according to policies
173
// set in the jdk.security.caDistrustPolicies security property
174
for (CADistrustPolicy policy : CADistrustPolicy.POLICIES) {
175
policy.checkDistrust(variant, chain);
176
}
177
}
178
179
/**
180
* Utility method returning the Set of critical extensions for
181
* certificate cert (never null).
182
*/
183
private Set<String> getCriticalExtensions(X509Certificate cert) {
184
Set<String> exts = cert.getCriticalExtensionOIDs();
185
if (exts == null) {
186
exts = Collections.emptySet();
187
}
188
return exts;
189
}
190
191
/**
192
* Utility method checking if there are any unresolved critical extensions.
193
* @throws CertificateException if so.
194
*/
195
private void checkRemainingExtensions(Set<String> exts)
196
throws CertificateException {
197
// basic constraints irrelevant in EE certs
198
exts.remove(SimpleValidator.OID_BASIC_CONSTRAINTS);
199
200
// If the subject field contains an empty sequence, the subjectAltName
201
// extension MUST be marked critical.
202
// We do not check the validity of the critical extension, just mark
203
// it recognizable here.
204
exts.remove(OID_SUBJECT_ALT_NAME);
205
206
if (!exts.isEmpty()) {
207
throw new CertificateException("Certificate contains unsupported "
208
+ "critical extensions: " + exts);
209
}
210
}
211
212
/**
213
* Utility method checking if the extended key usage extension in
214
* certificate cert allows use for expectedEKU.
215
*/
216
private boolean checkEKU(X509Certificate cert, Set<String> exts,
217
String expectedEKU) throws CertificateException {
218
List<String> eku = cert.getExtendedKeyUsage();
219
if (eku == null) {
220
return true;
221
}
222
return eku.contains(expectedEKU) || eku.contains(OID_EKU_ANY_USAGE);
223
}
224
225
/**
226
* Utility method checking if bit 'bit' is set in this certificates
227
* key usage extension.
228
* @throws CertificateException if not
229
*/
230
private boolean checkKeyUsage(X509Certificate cert, int bit)
231
throws CertificateException {
232
boolean[] keyUsage = cert.getKeyUsage();
233
if (keyUsage == null) {
234
return true;
235
}
236
return (keyUsage.length > bit) && keyUsage[bit];
237
}
238
239
/**
240
* Check whether this certificate can be used for TLS client
241
* authentication.
242
* @throws CertificateException if not.
243
*/
244
private void checkTLSClient(X509Certificate cert, Set<String> exts)
245
throws CertificateException {
246
if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
247
throw new ValidatorException
248
("KeyUsage does not allow digital signatures",
249
ValidatorException.T_EE_EXTENSIONS, cert);
250
}
251
252
if (checkEKU(cert, exts, OID_EKU_TLS_CLIENT) == false) {
253
throw new ValidatorException("Extended key usage does not "
254
+ "permit use for TLS client authentication",
255
ValidatorException.T_EE_EXTENSIONS, cert);
256
}
257
258
if (!SimpleValidator.getNetscapeCertTypeBit(cert, NSCT_SSL_CLIENT)) {
259
throw new ValidatorException
260
("Netscape cert type does not permit use for SSL client",
261
ValidatorException.T_EE_EXTENSIONS, cert);
262
}
263
264
// remove extensions we checked
265
exts.remove(SimpleValidator.OID_KEY_USAGE);
266
exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE);
267
exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE);
268
}
269
270
/**
271
* Check whether this certificate can be used for TLS server authentication
272
* using the specified authentication type parameter. See X509TrustManager
273
* specification for details.
274
* @throws CertificateException if not.
275
*/
276
private void checkTLSServer(X509Certificate cert, String parameter,
277
Set<String> exts) throws CertificateException {
278
if (KU_SERVER_ENCRYPTION.contains(parameter)) {
279
if (checkKeyUsage(cert, KU_KEY_ENCIPHERMENT) == false) {
280
throw new ValidatorException
281
("KeyUsage does not allow key encipherment",
282
ValidatorException.T_EE_EXTENSIONS, cert);
283
}
284
} else if (KU_SERVER_SIGNATURE.contains(parameter)) {
285
if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
286
throw new ValidatorException
287
("KeyUsage does not allow digital signatures",
288
ValidatorException.T_EE_EXTENSIONS, cert);
289
}
290
} else if (KU_SERVER_KEY_AGREEMENT.contains(parameter)) {
291
if (checkKeyUsage(cert, KU_KEY_AGREEMENT) == false) {
292
throw new ValidatorException
293
("KeyUsage does not allow key agreement",
294
ValidatorException.T_EE_EXTENSIONS, cert);
295
}
296
} else {
297
throw new CertificateException("Unknown authType: " + parameter);
298
}
299
300
if (checkEKU(cert, exts, OID_EKU_TLS_SERVER) == false) {
301
// check for equivalent but now obsolete Server-Gated-Cryptography
302
// (aka Step-Up, 128 bit) EKU OIDs
303
if ((checkEKU(cert, exts, OID_EKU_MS_SGC) == false) &&
304
(checkEKU(cert, exts, OID_EKU_NS_SGC) == false)) {
305
throw new ValidatorException
306
("Extended key usage does not permit use for TLS "
307
+ "server authentication",
308
ValidatorException.T_EE_EXTENSIONS, cert);
309
}
310
}
311
312
if (!SimpleValidator.getNetscapeCertTypeBit(cert, NSCT_SSL_SERVER)) {
313
throw new ValidatorException
314
("Netscape cert type does not permit use for SSL server",
315
ValidatorException.T_EE_EXTENSIONS, cert);
316
}
317
318
// remove extensions we checked
319
exts.remove(SimpleValidator.OID_KEY_USAGE);
320
exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE);
321
exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE);
322
}
323
324
/**
325
* Check whether this certificate can be used for code signing.
326
* @throws CertificateException if not.
327
*/
328
private void checkCodeSigning(X509Certificate cert, Set<String> exts)
329
throws CertificateException {
330
if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
331
throw new ValidatorException
332
("KeyUsage does not allow digital signatures",
333
ValidatorException.T_EE_EXTENSIONS, cert);
334
}
335
336
if (checkEKU(cert, exts, OID_EKU_CODE_SIGNING) == false) {
337
throw new ValidatorException
338
("Extended key usage does not permit use for code signing",
339
ValidatorException.T_EE_EXTENSIONS, cert);
340
}
341
342
// do not check Netscape cert type for JCE code signing checks
343
// (some certs were issued with incorrect extensions)
344
if (variant.equals(Validator.VAR_JCE_SIGNING) == false) {
345
if (!SimpleValidator.getNetscapeCertTypeBit(cert, NSCT_CODE_SIGNING)) {
346
throw new ValidatorException
347
("Netscape cert type does not permit use for code signing",
348
ValidatorException.T_EE_EXTENSIONS, cert);
349
}
350
exts.remove(SimpleValidator.OID_NETSCAPE_CERT_TYPE);
351
}
352
353
// remove extensions we checked
354
exts.remove(SimpleValidator.OID_KEY_USAGE);
355
exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE);
356
}
357
358
/**
359
* Check whether this certificate can be used by a time stamping authority
360
* server (see RFC 3161, section 2.3).
361
* @throws CertificateException if not.
362
*/
363
private void checkTSAServer(X509Certificate cert, Set<String> exts)
364
throws CertificateException {
365
if (checkKeyUsage(cert, KU_SIGNATURE) == false) {
366
throw new ValidatorException
367
("KeyUsage does not allow digital signatures",
368
ValidatorException.T_EE_EXTENSIONS, cert);
369
}
370
371
if (cert.getExtendedKeyUsage() == null) {
372
throw new ValidatorException
373
("Certificate does not contain an extended key usage " +
374
"extension required for a TSA server",
375
ValidatorException.T_EE_EXTENSIONS, cert);
376
}
377
378
if (checkEKU(cert, exts, OID_EKU_TIME_STAMPING) == false) {
379
throw new ValidatorException
380
("Extended key usage does not permit use for TSA server",
381
ValidatorException.T_EE_EXTENSIONS, cert);
382
}
383
384
// remove extensions we checked
385
exts.remove(SimpleValidator.OID_KEY_USAGE);
386
exts.remove(SimpleValidator.OID_EXTENDED_KEY_USAGE);
387
}
388
}
389
390