Skip to content

Commit 533fac6

Browse files
committed
8328638: Fallback option for POST-only OCSP requests
8329213: Better validation for com.sun.security.ocsp.useget option Reviewed-by: serb Backport-of: 614db2ea9e10346475eef34629eab54878aa482d
1 parent 31ba7e0 commit 533fac6

File tree

5 files changed

+130
-5
lines changed

5 files changed

+130
-5
lines changed

src/java.base/share/classes/sun/security/action/GetPropertyAction.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727

2828
import java.security.AccessController;
2929
import java.security.PrivilegedAction;
30+
import java.util.Locale;
3031
import java.util.Properties;
32+
import sun.security.util.Debug;
3133

3234
/**
3335
* A convenience class for retrieving the string value of a system
@@ -159,4 +161,37 @@ public Properties run() {
159161
);
160162
}
161163
}
164+
165+
/**
166+
* Convenience method for fetching System property values that are booleans.
167+
*
168+
* @param prop the name of the System property
169+
* @param def a default value
170+
* @param dbg a Debug object, if null no debug messages will be sent
171+
*
172+
* @return a boolean value corresponding to the value in the System property.
173+
* If the property value is neither "true" or "false", the default value
174+
* will be returned.
175+
*/
176+
public static boolean privilegedGetBooleanProp(String prop, boolean def, Debug dbg) {
177+
String rawPropVal = privilegedGetProperty(prop, "");
178+
if ("".equals(rawPropVal)) {
179+
return def;
180+
}
181+
182+
String lower = rawPropVal.toLowerCase(Locale.ROOT);
183+
if ("true".equals(lower)) {
184+
return true;
185+
} else if ("false".equals(lower)) {
186+
return false;
187+
} else {
188+
if (dbg != null) {
189+
dbg.println("Warning: Unexpected value for " + prop +
190+
": " + rawPropVal +
191+
". Using default value: " + def);
192+
}
193+
return def;
194+
}
195+
}
196+
162197
}

src/java.base/share/classes/sun/security/provider/certpath/OCSP.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
4444
import java.util.Map;
4545

4646
import sun.security.action.GetIntegerAction;
47+
import sun.security.action.GetPropertyAction;
4748
import sun.security.util.Debug;
4849
import sun.security.util.Event;
4950
import sun.security.util.IOUtils;
@@ -79,6 +80,28 @@ public final class OCSP {
7980
*/
8081
private static final int CONNECT_TIMEOUT = initializeTimeout();
8182

83+
/**
84+
* Boolean value indicating whether OCSP client can use GET for OCSP
85+
* requests. There is an ambiguity in RFC recommendations.
86+
*
87+
* RFC 5019 says a stronger thing, "MUST":
88+
* "When sending requests that are less than or equal to 255 bytes in
89+
* total (after encoding) including the scheme and delimiters (http://),
90+
* server name and base64-encoded OCSPRequest structure, clients MUST
91+
* use the GET method (to enable OCSP response caching)."
92+
*
93+
* RFC 6960 says a weaker thing, "MAY":
94+
* "HTTP-based OCSP requests can use either the GET or the POST method to
95+
* submit their requests. To enable HTTP caching, small requests (that
96+
* after encoding are less than 255 bytes) MAY be submitted using GET."
97+
*
98+
* For performance reasons, we default to stronger behavior. But this
99+
* option also allows to fallback to weaker behavior in case of compatibility
100+
* problems.
101+
*/
102+
private static final boolean USE_GET = initializeBoolean(
103+
"com.sun.security.ocsp.useget", true);
104+
82105
/**
83106
* Initialize the timeout length by getting the OCSP timeout
84107
* system property. If the property has not been set, or if its
@@ -96,6 +119,15 @@ private static int initializeTimeout() {
96119
return tmp * 1000;
97120
}
98121

122+
private static boolean initializeBoolean(String prop, boolean def) {
123+
boolean value =
124+
GetPropertyAction.privilegedGetBooleanProp(prop, def, debug);
125+
if (debug != null) {
126+
debug.println(prop + " set to " + value);
127+
}
128+
return value;
129+
}
130+
99131
private OCSP() {}
100132

101133

@@ -244,7 +276,7 @@ public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
244276
encodedGetReq.append(URLEncoder.encode(
245277
Base64.getEncoder().encodeToString(bytes), "UTF-8"));
246278

247-
if (encodedGetReq.length() <= 255) {
279+
if (USE_GET && encodedGetReq.length() <= 255) {
248280
url = new URL(encodedGetReq.toString());
249281
con = (HttpURLConnection)url.openConnection();
250282
con.setDoOutput(true);

test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,14 +23,16 @@
2323

2424
/**
2525
* @test
26-
* @bug 8179503
26+
* @bug 8179503 8328638
2727
* @summary Java should support GET OCSP calls
2828
* @library /javax/net/ssl/templates /java/security/testlibrary
2929
* @build SimpleOCSPServer
3030
* @modules java.base/sun.security.util
3131
* java.base/sun.security.provider.certpath
3232
* java.base/sun.security.x509
3333
* @run main/othervm GetAndPostTests
34+
* @run main/othervm -Dcom.sun.security.ocsp.useget=false GetAndPostTests
35+
* @run main/othervm -Dcom.sun.security.ocsp.useget=foo GetAndPostTests
3436
*/
3537

3638
import java.io.ByteArrayInputStream;

test/jdk/java/security/testlibrary/SimpleOCSPServer.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -704,6 +704,9 @@ public CRLReason getRevocationReason() {
704704
* responses.
705705
*/
706706
private class OcspHandler implements Runnable {
707+
private final boolean USE_GET =
708+
!System.getProperty("com.sun.security.ocsp.useget", "").equals("false");
709+
707710
private final Socket sock;
708711
InetSocketAddress peerSockAddr;
709712

@@ -876,6 +879,12 @@ private LocalOcspRequest parseHttpOcspPost(InputStream inStream)
876879
// Okay, make sure we got what we needed from the header, then
877880
// read the remaining OCSP Request bytes
878881
if (properContentType && length >= 0) {
882+
if (USE_GET && length <= 255) {
883+
// Received a small POST request. Check that our client code properly
884+
// handled the relevant flag. We expect small GET requests, unless
885+
// explicitly disabled.
886+
throw new IOException("Should have received small GET, not POST.");
887+
}
879888
byte[] ocspBytes = new byte[length];
880889
inStream.read(ocspBytes);
881890
return new LocalOcspRequest(ocspBytes);

0 commit comments

Comments
 (0)