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