Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/java.base/share/classes/java/io/Console.java
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,9 @@ private char[] readPassword0(boolean noNewLine, String fmt, Object ... args) {
ioe.addSuppressed(x);
}
if (ioe != null) {
Arrays.fill(passwd, ' ');
if (passwd != null) {
Arrays.fill(passwd, ' ');
}
try {
if (reader instanceof LineReader lr) {
lr.zeroOut();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1995, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2026, 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
Expand Down Expand Up @@ -2005,10 +2005,7 @@ private InputStream getInputStream0() throws IOException {
pi.finishTracking();
pi = null;
}
http.finished();
http = null;
inputStream = new EmptyInputStream();
connected = false;
noResponseBody();
}

if (respCode == 200 || respCode == 203 || respCode == 206 ||
Expand Down Expand Up @@ -2090,6 +2087,24 @@ private InputStream getInputStream0() throws IOException {
}
}

/**
* This method is called when a response with no response
* body is received, and arrange for the http client to
* be returned to the pool (or released) immediately when
* possible.
* @apiNote Used by {@link sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection}
* to preserve the TLS information after receiving an empty body.
* @implSpec
* Subclasses that override this method should call the super class
* implementation.
*/
protected void noResponseBody() {
http.finished();
http = null;
inputStream = new EmptyInputStream();
connected = false;
}

/*
* Creates a chained exception that has the same type as
* original exception and with the same message. Right now,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2026, 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
Expand Down Expand Up @@ -51,6 +51,7 @@
public abstract class AbstractDelegateHttpsURLConnection extends
HttpURLConnection {

private SSLSession savedSession = null;
protected AbstractDelegateHttpsURLConnection(URL url,
sun.net.www.protocol.http.Handler handler) throws IOException {
this(url, null, handler);
Expand Down Expand Up @@ -92,6 +93,7 @@ public void setNewClient (URL url)
public void setNewClient (URL url, boolean useCache)
throws IOException {
int readTimeout = getReadTimeout();
savedSession = null;
http = HttpsClient.New (getSSLSocketFactory(),
url,
getHostnameVerifier(),
Expand Down Expand Up @@ -184,6 +186,7 @@ public void connect() throws IOException {
if (!http.isCachedConnection() && http.needsTunneling()) {
doTunneling();
}
savedSession = null;
((HttpsClient)http).afterConnect();
}

Expand All @@ -204,18 +207,32 @@ protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout,
useCache, connectTimeout, this);
}

@Override
protected void noResponseBody() {
savedSession = ((HttpsClient)http).getSSLSession();
super.noResponseBody();
}

private SSLSession session() {
if (http instanceof HttpsClient https) {
return https.getSSLSession();
}
return savedSession;
}

/**
* Returns the cipher suite in use on this connection.
*/
public String getCipherSuite () {
if (cachedResponse != null) {
return ((SecureCacheResponse)cachedResponse).getCipherSuite();
}
if (http == null) {

var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
} else {
return ((HttpsClient)http).getCipherSuite ();
}
return session.getCipherSuite();
}

/**
Expand All @@ -231,11 +248,12 @@ public java.security.cert.Certificate[] getLocalCertificates() {
return l.toArray(new java.security.cert.Certificate[0]);
}
}
if (http == null) {

var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
} else {
return (((HttpsClient)http).getLocalCertificates ());
}
return session.getLocalCertificates();
}

/**
Expand All @@ -256,11 +274,11 @@ public java.security.cert.Certificate[] getServerCertificates()
}
}

if (http == null) {
var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
} else {
return (((HttpsClient)http).getServerCertificates ());
}
return session.getPeerCertificates();
}

/**
Expand All @@ -274,11 +292,11 @@ Principal getPeerPrincipal()
return ((SecureCacheResponse)cachedResponse).getPeerPrincipal();
}

if (http == null) {
var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
} else {
return (((HttpsClient)http).getPeerPrincipal());
}
return getPeerPrincipal(session);
}

/**
Expand All @@ -291,11 +309,11 @@ Principal getLocalPrincipal()
return ((SecureCacheResponse)cachedResponse).getLocalPrincipal();
}

if (http == null) {
var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
} else {
return (((HttpsClient)http).getLocalPrincipal());
}
return getLocalPrincipal(session);
}

SSLSession getSSLSession() {
Expand All @@ -307,11 +325,12 @@ SSLSession getSSLSession() {
}
}

if (http == null) {
var session = session();
if (session == null) {
throw new IllegalStateException("connection not yet open");
}

return ((HttpsClient)http).getSSLSession();
return session;
}

/*
Expand Down Expand Up @@ -354,7 +373,7 @@ protected HttpCallerInfo getHttpCallerInfo(URL url, String proxy, int port,
}
HttpsClient https = (HttpsClient)http;
try {
Certificate[] certs = https.getServerCertificates();
Certificate[] certs = https.getSSLSession().getPeerCertificates();
if (certs[0] instanceof X509Certificate x509Cert) {
return new HttpCallerInfo(url, proxy, port, x509Cert, authenticator);
}
Expand All @@ -372,7 +391,7 @@ protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator)
}
HttpsClient https = (HttpsClient)http;
try {
Certificate[] certs = https.getServerCertificates();
Certificate[] certs = https.getSSLSession().getPeerCertificates();
if (certs[0] instanceof X509Certificate x509Cert) {
return new HttpCallerInfo(url, x509Cert, authenticator);
}
Expand All @@ -381,4 +400,58 @@ protected HttpCallerInfo getHttpCallerInfo(URL url, Authenticator authenticator)
}
return super.getHttpCallerInfo(url, authenticator);
}

@Override
public void disconnect() {
super.disconnect();
savedSession = null;
}

/**
* Returns the principal with which the server authenticated
* itself, or throw a SSLPeerUnverifiedException if the
* server did not authenticate.
* @param session The {@linkplain #getSSLSession() SSL session}
*/
private static Principal getPeerPrincipal(SSLSession session)
throws SSLPeerUnverifiedException
{
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the provider does not support it, fallback to peer certs.
// return the X500Principal of the end-entity cert.
java.security.cert.Certificate[] certs =
session.getPeerCertificates();
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
return principal;
}

/**
* Returns the principal the client sent to the
* server, or null if the client did not authenticate.
* @param session The {@linkplain #getSSLSession() SSL session}
*/
private static Principal getLocalPrincipal(SSLSession session)
{
Principal principal;
try {
principal = session.getLocalPrincipal();
} catch (AbstractMethodError e) {
principal = null;
// if the provider does not support it, fallback to local certs.
// return the X500Principal of the end-entity cert.
java.security.cert.Certificate[] certs =
session.getLocalCertificates();
if (certs != null) {
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
}
return principal;
}



}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2026, 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
Expand Down Expand Up @@ -698,75 +698,6 @@ public void closeIdleConnection() {
}
}

/**
* Returns the cipher suite in use on this connection.
*/
String getCipherSuite() {
return session.getCipherSuite();
}

/**
* Returns the certificate chain the client sent to the
* server, or null if the client did not authenticate.
*/
public java.security.cert.Certificate [] getLocalCertificates() {
return session.getLocalCertificates();
}

/**
* Returns the certificate chain with which the server
* authenticated itself, or throw a SSLPeerUnverifiedException
* if the server did not authenticate.
*/
java.security.cert.Certificate [] getServerCertificates()
throws SSLPeerUnverifiedException
{
return session.getPeerCertificates();
}

/**
* Returns the principal with which the server authenticated
* itself, or throw a SSLPeerUnverifiedException if the
* server did not authenticate.
*/
Principal getPeerPrincipal()
throws SSLPeerUnverifiedException
{
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the provider does not support it, fallback to peer certs.
// return the X500Principal of the end-entity cert.
java.security.cert.Certificate[] certs =
session.getPeerCertificates();
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
return principal;
}

/**
* Returns the principal the client sent to the
* server, or null if the client did not authenticate.
*/
Principal getLocalPrincipal()
{
Principal principal;
try {
principal = session.getLocalPrincipal();
} catch (AbstractMethodError e) {
principal = null;
// if the provider does not support it, fallback to local certs.
// return the X500Principal of the end-entity cert.
java.security.cert.Certificate[] certs =
session.getLocalCertificates();
if (certs != null) {
principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
}
}
return principal;
}

/**
* Returns the {@code SSLSession} in use on this connection.
*/
Expand Down
Loading
Loading