This commit is contained in:
David Dehaven 2016-03-11 11:27:12 -08:00
commit 1a08d0a1d9
4 changed files with 144 additions and 111 deletions
jdk
src/java.base/share/classes
test/sun/security/mscapi

@ -91,7 +91,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
* can call with more than 255 slots. This limits the number of static and
* dynamic arguments one can pass to bootstrap method. Since there are potential
* concatenation strategies that use {@code MethodHandle} combinators, we need
* to reserve a few empty slots on the parameter lists to to capture the
* to reserve a few empty slots on the parameter lists to capture the
* temporal results. This is why bootstrap methods in this factory do not accept
* more than 200 argument slots. Users requiring more than 200 argument slots in
* concatenation are expected to split the large concatenation in smaller

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -700,7 +700,7 @@ static final class CertificateStatus extends HandshakeMessage
* OCSP response data is provided.
*/
CertificateStatus(StatusRequestType type, X509Certificate[] chain,
Map<X509Certificate, byte[]> responses) throws SSLException {
Map<X509Certificate, byte[]> responses) {
statusType = type;
encodedResponsesLen = 0;
encodedResponses = new ArrayList<>(chain.length);
@ -715,7 +715,7 @@ static final class CertificateStatus extends HandshakeMessage
encodedResponses.add(respDER);
encodedResponsesLen = 3 + respDER.length;
} else {
throw new SSLHandshakeException("Zero-length or null " +
throw new IllegalArgumentException("Zero-length or null " +
"OCSP Response");
}
} else if (statusType == StatusRequestType.OCSP_MULTI) {
@ -732,8 +732,8 @@ static final class CertificateStatus extends HandshakeMessage
}
}
} else {
throw new SSLHandshakeException("Unsupported StatusResponseType: " +
statusType);
throw new IllegalArgumentException(
"Unsupported StatusResponseType: " + statusType);
}
}

@ -36,7 +36,6 @@ import java.security.spec.ECParameterSpec;
import java.math.BigInteger;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.*;
import sun.security.action.GetLongAction;
@ -67,7 +66,6 @@ final class ServerHandshaker extends Handshaker {
// our authentication info
private X509Certificate[] certs;
private Map<X509Certificate, byte[]> responseMap;
private PrivateKey privateKey;
private Object serviceCreds;
@ -118,7 +116,6 @@ final class ServerHandshaker extends Handshaker {
LegacyAlgorithmConstraints.PROPERTY_TLS_LEGACY_ALGS,
new SSLAlgorithmDecomposer());
private boolean staplingActive = false;
private long statusRespTimeout;
static {
@ -578,16 +575,6 @@ final class ServerHandshaker extends Handshaker {
}
}
// Check if the client has asserted the status_request[_v2] extension(s)
CertStatusReqExtension statReqExt = (CertStatusReqExtension)
mesg.extensions.get(ExtensionType.EXT_STATUS_REQUEST);
CertStatusReqListV2Extension statReqExtV2 =
(CertStatusReqListV2Extension)mesg.extensions.get(
ExtensionType.EXT_STATUS_REQUEST_V2);
// Keep stapling active if at least one of the extensions has been set
staplingActive = sslContext.isStaplingEnabled(false) &&
(statReqExt != null || statReqExtV2 != null);
/*
* FIRST, construct the ServerHello using the options and priorities
* from the ClientHello. Update the (pending) cipher spec as we do
@ -883,79 +870,17 @@ final class ServerHandshaker extends Handshaker {
m1.extensions.add(maxFragLenExt);
}
StatusRequestType statReqType = null;
StatusRequest statReqData = null;
if (staplingActive && !resumingSession) {
ExtensionType statusRespExt = ExtensionType.EXT_STATUS_REQUEST;
// Determine which type of stapling we are doing and assert the
// proper extension in the server hello.
// Favor status_request_v2 over status_request and ocsp_multi
// over ocsp.
// If multiple ocsp or ocsp_multi types exist, select the first
// instance of a given type
if (statReqExtV2 != null) { // RFC 6961 stapling
statusRespExt = ExtensionType.EXT_STATUS_REQUEST_V2;
List<CertStatusReqItemV2> reqItems =
statReqExtV2.getRequestItems();
int ocspIdx = -1;
int ocspMultiIdx = -1;
for (int pos = 0; pos < reqItems.size(); pos++) {
CertStatusReqItemV2 item = reqItems.get(pos);
if (ocspIdx < 0 && item.getType() ==
StatusRequestType.OCSP) {
ocspIdx = pos;
} else if (ocspMultiIdx < 0 && item.getType() ==
StatusRequestType.OCSP_MULTI) {
ocspMultiIdx = pos;
}
}
if (ocspMultiIdx >= 0) {
statReqType = reqItems.get(ocspMultiIdx).getType();
statReqData = reqItems.get(ocspMultiIdx).getRequest();
} else if (ocspIdx >= 0) {
statReqType = reqItems.get(ocspIdx).getType();
statReqData = reqItems.get(ocspIdx).getRequest();
} else {
// Some unknown type. We will not do stapling for
// this connection since we cannot understand the
// requested type.
staplingActive = false;
}
} else { // RFC 6066 stapling
statReqType = StatusRequestType.OCSP;
statReqData = statReqExt.getRequest();
}
if (statReqType != null && statReqData != null) {
StatusResponseManager statRespMgr =
sslContext.getStatusResponseManager();
if (statRespMgr != null) {
responseMap = statRespMgr.get(statReqType, statReqData,
certs, statusRespTimeout, TimeUnit.MILLISECONDS);
if (!responseMap.isEmpty()) {
// We now can safely assert status_request[_v2] in our
// ServerHello, and know for certain that we can provide
// responses back to this client for this connection.
if (statusRespExt == ExtensionType.EXT_STATUS_REQUEST) {
m1.extensions.add(new CertStatusReqExtension());
} else if (statusRespExt ==
ExtensionType.EXT_STATUS_REQUEST_V2) {
m1.extensions.add(
new CertStatusReqListV2Extension());
}
}
} else {
// This should not happen if stapling is active, but
// if lazy initialization of the StatusResponseManager
// doesn't occur we should turn off stapling.
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Warning: lazy initialization " +
"of the StatusResponseManager failed. " +
"Stapling has been disabled.");
staplingActive = false;
}
}
StaplingParameters staplingParams = processStapling(mesg);
if (staplingParams != null) {
// We now can safely assert status_request[_v2] in our
// ServerHello, and know for certain that we can provide
// responses back to this client for this connection.
if (staplingParams.statusRespExt ==
ExtensionType.EXT_STATUS_REQUEST) {
m1.extensions.add(new CertStatusReqExtension());
} else if (staplingParams.statusRespExt ==
ExtensionType.EXT_STATUS_REQUEST_V2) {
m1.extensions.add(new CertStatusReqListV2Extension());
}
}
@ -1031,24 +956,15 @@ final class ServerHandshaker extends Handshaker {
* supports status stapling and there is at least one response to
* return to the client.
*/
if (staplingActive && !responseMap.isEmpty()) {
try {
CertificateStatus csMsg = new CertificateStatus(statReqType,
certs, responseMap);
if (debug != null && Debug.isOn("handshake")) {
csMsg.print(System.out);
}
csMsg.write(output);
handshakeState.update(csMsg, resumingSession);
responseMap = null;
} catch (SSLException ssle) {
// We don't want the exception to be fatal, we just won't
// send the message if we fail on construction.
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Failed during CertificateStatus " +
"construction: " + ssle);
}
if (staplingParams != null) {
CertificateStatus csMsg = new CertificateStatus(
staplingParams.statReqType, certs,
staplingParams.responseMap);
if (debug != null && Debug.isOn("handshake")) {
csMsg.print(System.out);
}
csMsg.write(output);
handshakeState.update(csMsg, resumingSession);
}
/*
@ -2078,4 +1994,121 @@ final class ServerHandshaker extends Handshaker {
session.setPeerCertificates(peerCerts);
}
private StaplingParameters processStapling(ClientHello mesg) {
StaplingParameters params = null;
ExtensionType ext;
StatusRequestType type = null;
StatusRequest req = null;
Map<X509Certificate, byte[]> responses;
// If this feature has not been enabled, then no more processing
// is necessary. Also we will only staple if we're doing a full
// handshake.
if (!sslContext.isStaplingEnabled(false) || resumingSession) {
return null;
}
// Check if the client has asserted the status_request[_v2] extension(s)
CertStatusReqExtension statReqExt = (CertStatusReqExtension)
mesg.extensions.get(ExtensionType.EXT_STATUS_REQUEST);
CertStatusReqListV2Extension statReqExtV2 =
(CertStatusReqListV2Extension)mesg.extensions.get(
ExtensionType.EXT_STATUS_REQUEST_V2);
// Keep processing only if either status_request or status_request_v2
// has been sent in the ClientHello.
if (statReqExt == null && statReqExtV2 == null) {
return null;
}
// Determine which type of stapling we are doing and assert the
// proper extension in the server hello.
// Favor status_request_v2 over status_request and ocsp_multi
// over ocsp.
// If multiple ocsp or ocsp_multi types exist, select the first
// instance of a given type
ext = ExtensionType.EXT_STATUS_REQUEST;
if (statReqExtV2 != null) { // RFC 6961 stapling
ext = ExtensionType.EXT_STATUS_REQUEST_V2;
List<CertStatusReqItemV2> reqItems =
statReqExtV2.getRequestItems();
int ocspIdx = -1;
int ocspMultiIdx = -1;
for (int pos = 0; pos < reqItems.size(); pos++) {
CertStatusReqItemV2 item = reqItems.get(pos);
if (ocspIdx < 0 && item.getType() ==
StatusRequestType.OCSP) {
ocspIdx = pos;
} else if (ocspMultiIdx < 0 && item.getType() ==
StatusRequestType.OCSP_MULTI) {
ocspMultiIdx = pos;
}
}
if (ocspMultiIdx >= 0) {
type = reqItems.get(ocspMultiIdx).getType();
req = reqItems.get(ocspMultiIdx).getRequest();
} else if (ocspIdx >= 0) {
type = reqItems.get(ocspIdx).getType();
req = reqItems.get(ocspIdx).getRequest();
}
} else { // RFC 6066 stapling
type = StatusRequestType.OCSP;
req = statReqExt.getRequest();
}
// If, after walking through the extensions we were unable to
// find a suitable StatusRequest, then stapling is disabled.
// Both statReqType and statReqData must have been set to continue.
if (type == null || req == null) {
return null;
}
// Get the OCSP responses from the StatusResponseManager
StatusResponseManager statRespMgr =
sslContext.getStatusResponseManager();
if (statRespMgr != null) {
responses = statRespMgr.get(type, req, certs, statusRespTimeout,
TimeUnit.MILLISECONDS);
if (!responses.isEmpty()) {
// If this RFC 6066-style stapling (SSL cert only) then the
// response cannot be zero length
if (type == StatusRequestType.OCSP) {
byte[] respDER = responses.get(certs[0]);
if (respDER == null || respDER.length <= 0) {
return null;
}
}
params = new StaplingParameters(ext, type, req, responses);
}
} else {
// This should not happen, but if lazy initialization of the
// StatusResponseManager doesn't occur we should turn off stapling.
if (debug != null && Debug.isOn("handshake")) {
System.out.println("Warning: lazy initialization " +
"of the StatusResponseManager failed. " +
"Stapling has been disabled.");
}
}
return params;
}
/**
* Inner class used to hold stapling parameters needed by the handshaker
* when stapling is active.
*/
private class StaplingParameters {
private final ExtensionType statusRespExt;
private final StatusRequestType statReqType;
private final StatusRequest statReqData;
private final Map<X509Certificate, byte[]> responseMap;
StaplingParameters(ExtensionType ext, StatusRequestType type,
StatusRequest req, Map<X509Certificate, byte[]> responses) {
statusRespExt = ext;
statReqType = type;
statReqData = req;
responseMap = responses;
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,7 @@ import java.security.SignatureException;
/*
* @test
* @bug 8050374
* @key randomness
* @key randomness intermittent
* @summary This test validates signature verification
* Signature.verify(byte[], int, int). The test uses RandomFactory to
* get random set of clear text data to sign. After the signature