Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java
41161 views
1
/*
2
* Copyright (c) 2009, 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
package sun.security.provider.certpath;
26
27
import java.io.IOException;
28
import java.io.OutputStream;
29
import java.net.URI;
30
import java.net.URL;
31
import java.net.HttpURLConnection;
32
import java.net.URLEncoder;
33
import java.security.cert.CertificateException;
34
import java.security.cert.CertPathValidatorException;
35
import java.security.cert.CertPathValidatorException.BasicReason;
36
import java.security.cert.CRLReason;
37
import java.security.cert.Extension;
38
import java.security.cert.TrustAnchor;
39
import java.security.cert.X509Certificate;
40
import java.util.Base64;
41
import java.util.Collections;
42
import java.util.Date;
43
import java.util.List;
44
import java.util.Map;
45
46
import sun.security.action.GetIntegerAction;
47
import sun.security.util.Debug;
48
import sun.security.util.Event;
49
import sun.security.util.IOUtils;
50
import sun.security.validator.Validator;
51
import sun.security.x509.AccessDescription;
52
import sun.security.x509.AuthorityInfoAccessExtension;
53
import sun.security.x509.GeneralName;
54
import sun.security.x509.GeneralNameInterface;
55
import sun.security.x509.PKIXExtensions;
56
import sun.security.x509.URIName;
57
import sun.security.x509.X509CertImpl;
58
59
/**
60
* This is a class that checks the revocation status of a certificate(s) using
61
* OCSP. It is not a PKIXCertPathChecker and therefore can be used outside of
62
* the CertPathValidator framework. It is useful when you want to
63
* just check the revocation status of a certificate, and you don't want to
64
* incur the overhead of validating all of the certificates in the
65
* associated certificate chain.
66
*
67
* @author Sean Mullan
68
*/
69
public final class OCSP {
70
71
private static final Debug debug = Debug.getInstance("certpath");
72
73
private static final int DEFAULT_CONNECT_TIMEOUT = 15000;
74
75
/**
76
* Integer value indicating the timeout length, in seconds, to be
77
* used for the OCSP check. A timeout of zero is interpreted as
78
* an infinite timeout.
79
*/
80
private static final int CONNECT_TIMEOUT = initializeTimeout();
81
82
/**
83
* Initialize the timeout length by getting the OCSP timeout
84
* system property. If the property has not been set, or if its
85
* value is negative, set the timeout length to the default.
86
*/
87
private static int initializeTimeout() {
88
@SuppressWarnings("removal")
89
Integer tmp = java.security.AccessController.doPrivileged(
90
new GetIntegerAction("com.sun.security.ocsp.timeout"));
91
if (tmp == null || tmp < 0) {
92
return DEFAULT_CONNECT_TIMEOUT;
93
}
94
// Convert to milliseconds, as the system property will be
95
// specified in seconds
96
return tmp * 1000;
97
}
98
99
private OCSP() {}
100
101
102
/**
103
* Obtains the revocation status of a certificate using OCSP.
104
*
105
* @param cert the certificate to be checked
106
* @param issuerCert the issuer certificate
107
* @param responderURI the URI of the OCSP responder
108
* @param responderCert the OCSP responder's certificate
109
* @param date the time the validity of the OCSP responder's certificate
110
* should be checked against. If null, the current time is used.
111
* @return the RevocationStatus
112
* @throws IOException if there is an exception connecting to or
113
* communicating with the OCSP responder
114
* @throws CertPathValidatorException if an exception occurs while
115
* encoding the OCSP Request or validating the OCSP Response
116
*/
117
118
// Called by com.sun.deploy.security.TrustDecider
119
public static RevocationStatus check(X509Certificate cert,
120
X509Certificate issuerCert,
121
URI responderURI,
122
X509Certificate responderCert,
123
Date date)
124
throws IOException, CertPathValidatorException
125
{
126
return check(cert, issuerCert, responderURI, responderCert, date,
127
Collections.<Extension>emptyList(),
128
Validator.VAR_PLUGIN_CODE_SIGNING);
129
}
130
131
132
public static RevocationStatus check(X509Certificate cert,
133
X509Certificate issuerCert, URI responderURI,
134
X509Certificate responderCert, Date date, List<Extension> extensions,
135
String variant)
136
throws IOException, CertPathValidatorException
137
{
138
return check(cert, responderURI, null, issuerCert, responderCert, date,
139
extensions, variant);
140
}
141
142
public static RevocationStatus check(X509Certificate cert,
143
URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
144
X509Certificate responderCert, Date date,
145
List<Extension> extensions, String variant)
146
throws IOException, CertPathValidatorException
147
{
148
CertId certId;
149
try {
150
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
151
certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
152
} catch (CertificateException | IOException e) {
153
throw new CertPathValidatorException
154
("Exception while encoding OCSPRequest", e);
155
}
156
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
157
responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
158
responderCert, date, extensions, variant);
159
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
160
}
161
162
/**
163
* Checks the revocation status of a list of certificates using OCSP.
164
*
165
* @param certIds the CertIds to be checked
166
* @param responderURI the URI of the OCSP responder
167
* @param issuerInfo the issuer's certificate and/or subject and public key
168
* @param responderCert the OCSP responder's certificate
169
* @param date the time the validity of the OCSP responder's certificate
170
* should be checked against. If null, the current time is used.
171
* @param extensions zero or more OCSP extensions to be included in the
172
* request. If no extensions are requested, an empty {@code List} must
173
* be used. A {@code null} value is not allowed.
174
* @return the OCSPResponse
175
* @throws IOException if there is an exception connecting to or
176
* communicating with the OCSP responder
177
* @throws CertPathValidatorException if an exception occurs while
178
* encoding the OCSP Request or validating the OCSP Response
179
*/
180
static OCSPResponse check(List<CertId> certIds, URI responderURI,
181
OCSPResponse.IssuerInfo issuerInfo,
182
X509Certificate responderCert, Date date,
183
List<Extension> extensions, String variant)
184
throws IOException, CertPathValidatorException
185
{
186
byte[] nonce = null;
187
for (Extension ext : extensions) {
188
if (ext.getId().equals(PKIXExtensions.OCSPNonce_Id.toString())) {
189
nonce = ext.getValue();
190
}
191
}
192
193
OCSPResponse ocspResponse = null;
194
try {
195
byte[] response = getOCSPBytes(certIds, responderURI, extensions);
196
ocspResponse = new OCSPResponse(response);
197
198
// verify the response
199
ocspResponse.verify(certIds, issuerInfo, responderCert, date,
200
nonce, variant);
201
} catch (IOException ioe) {
202
throw new CertPathValidatorException(
203
"Unable to determine revocation status due to network error",
204
ioe, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
205
}
206
207
return ocspResponse;
208
}
209
210
211
/**
212
* Send an OCSP request, then read and return the OCSP response bytes.
213
*
214
* @param certIds the CertIds to be checked
215
* @param responderURI the URI of the OCSP responder
216
* @param extensions zero or more OCSP extensions to be included in the
217
* request. If no extensions are requested, an empty {@code List} must
218
* be used. A {@code null} value is not allowed.
219
*
220
* @return the OCSP response bytes
221
*
222
* @throws IOException if there is an exception connecting to or
223
* communicating with the OCSP responder
224
*/
225
public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
226
List<Extension> extensions) throws IOException {
227
OCSPRequest request = new OCSPRequest(certIds, extensions);
228
byte[] bytes = request.encodeBytes();
229
230
if (debug != null) {
231
debug.println("connecting to OCSP service at: " + responderURI);
232
}
233
Event.report(Event.ReporterCategory.CRLCHECK, "event.ocsp.check",
234
responderURI.toString());
235
236
URL url;
237
HttpURLConnection con = null;
238
try {
239
String encodedGetReq = responderURI.toString() + "/" +
240
URLEncoder.encode(Base64.getEncoder().encodeToString(bytes),
241
"UTF-8");
242
243
if (encodedGetReq.length() <= 255) {
244
url = new URL(encodedGetReq);
245
con = (HttpURLConnection)url.openConnection();
246
con.setDoOutput(true);
247
con.setDoInput(true);
248
con.setRequestMethod("GET");
249
} else {
250
url = responderURI.toURL();
251
con = (HttpURLConnection)url.openConnection();
252
con.setConnectTimeout(CONNECT_TIMEOUT);
253
con.setReadTimeout(CONNECT_TIMEOUT);
254
con.setDoOutput(true);
255
con.setDoInput(true);
256
con.setRequestMethod("POST");
257
con.setRequestProperty
258
("Content-type", "application/ocsp-request");
259
con.setRequestProperty
260
("Content-length", String.valueOf(bytes.length));
261
OutputStream out = con.getOutputStream();
262
out.write(bytes);
263
out.flush();
264
}
265
266
// Check the response
267
if (debug != null &&
268
con.getResponseCode() != HttpURLConnection.HTTP_OK) {
269
debug.println("Received HTTP error: " + con.getResponseCode()
270
+ " - " + con.getResponseMessage());
271
}
272
273
int contentLength = con.getContentLength();
274
if (contentLength == -1) {
275
contentLength = Integer.MAX_VALUE;
276
}
277
278
return IOUtils.readExactlyNBytes(con.getInputStream(),
279
contentLength);
280
} finally {
281
if (con != null) {
282
con.disconnect();
283
}
284
}
285
}
286
287
/**
288
* Returns the URI of the OCSP Responder as specified in the
289
* certificate's Authority Information Access extension, or null if
290
* not specified.
291
*
292
* @param cert the certificate
293
* @return the URI of the OCSP Responder, or null if not specified
294
*/
295
// Called by com.sun.deploy.security.TrustDecider
296
public static URI getResponderURI(X509Certificate cert) {
297
try {
298
return getResponderURI(X509CertImpl.toImpl(cert));
299
} catch (CertificateException ce) {
300
// treat this case as if the cert had no extension
301
return null;
302
}
303
}
304
305
static URI getResponderURI(X509CertImpl certImpl) {
306
307
// Examine the certificate's AuthorityInfoAccess extension
308
AuthorityInfoAccessExtension aia =
309
certImpl.getAuthorityInfoAccessExtension();
310
if (aia == null) {
311
return null;
312
}
313
314
List<AccessDescription> descriptions = aia.getAccessDescriptions();
315
for (AccessDescription description : descriptions) {
316
if (description.getAccessMethod().equals(
317
AccessDescription.Ad_OCSP_Id)) {
318
319
GeneralName generalName = description.getAccessLocation();
320
if (generalName.getType() == GeneralNameInterface.NAME_URI) {
321
URIName uri = (URIName) generalName.getName();
322
return uri.getURI();
323
}
324
}
325
}
326
return null;
327
}
328
329
/**
330
* The Revocation Status of a certificate.
331
*/
332
public static interface RevocationStatus {
333
public enum CertStatus { GOOD, REVOKED, UNKNOWN };
334
335
/**
336
* Returns the revocation status.
337
*/
338
CertStatus getCertStatus();
339
/**
340
* Returns the time when the certificate was revoked, or null
341
* if it has not been revoked.
342
*/
343
Date getRevocationTime();
344
/**
345
* Returns the reason the certificate was revoked, or null if it
346
* has not been revoked.
347
*/
348
CRLReason getRevocationReason();
349
350
/**
351
* Returns a Map of additional extensions.
352
*/
353
Map<String, Extension> getSingleExtensions();
354
}
355
}
356
357