Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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 @@ -29,7 +29,6 @@
import java.io.OutputStream;
import java.io.IOException;

import java.security.Principal;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;

Expand Down Expand Up @@ -64,11 +63,6 @@ public final class StartTlsResponseImpl extends StartTlsResponse {

private static final boolean debug = false;

/*
* The dNSName type in a subjectAltName extension of an X.509 certificate
*/
private static final int DNSNAME_TYPE = 2;

/*
* The server's hostname.
*/
Expand Down Expand Up @@ -111,9 +105,9 @@ public final class StartTlsResponseImpl extends StartTlsResponse {
private transient HostnameVerifier verifier = null;

/*
* The flag to indicate that the TLS connection is closed.
* The flag to indicate that close() was invoked
*/
private transient boolean isClosed = true;
private transient boolean closed;

private static final long serialVersionUID = -1126624615143411328L;

Expand All @@ -133,6 +127,7 @@ public StartTlsResponseImpl() {}
* enable.
* @see #negotiate
*/
@Override
public void setEnabledCipherSuites(String[] suites) {
// The impl does accept null suites, although the spec requires
// a non-null list.
Expand All @@ -150,6 +145,7 @@ public void setEnabledCipherSuites(String[] suites) {
* @param verifier The non-null hostname verifier callback.
* @see #negotiate
*/
@Override
public void setHostnameVerifier(HostnameVerifier verifier) {
this.verifier = verifier;
}
Expand All @@ -165,6 +161,7 @@ public void setHostnameVerifier(HostnameVerifier verifier) {
* @see #setEnabledCipherSuites
* @see #setHostnameVerifier
*/
@Override
public SSLSession negotiate() throws IOException {

return negotiate(null);
Expand Down Expand Up @@ -200,9 +197,10 @@ public SSLSession negotiate() throws IOException {
* @see #setEnabledCipherSuites
* @see #setHostnameVerifier
*/
@Override
public SSLSession negotiate(SSLSocketFactory factory) throws IOException {

if (isClosed && sslSocket != null) {
if (closed) {
throw new IOException("TLS connection is closed.");
}

Expand All @@ -223,7 +221,6 @@ public SSLSession negotiate(SSLSocketFactory factory) throws IOException {
SSLPeerUnverifiedException verifExcep = null;
try {
if (verify(hostname, sslSession)) {
isClosed = false;
return sslSession;
}
} catch (SSLPeerUnverifiedException e) {
Expand All @@ -232,18 +229,18 @@ public SSLSession negotiate(SSLSocketFactory factory) throws IOException {
}
if ((verifier != null) &&
verifier.verify(hostname, sslSession)) {
isClosed = false;
return sslSession;
}

// Verification failed
close();
sslSession.invalidate();
if (verifExcep == null) {
verifExcep = new SSLPeerUnverifiedException(
"hostname of the server '" + hostname +
"' does not match the hostname in the " +
"server's certificate.");
verifExcep = new SSLPeerUnverifiedException("hostname of the server '"
+ hostname + "' does not match the hostname in the server's certificate.");
}
sslSession.invalidate();
try {
close();
} catch (IOException ioe) {
verifExcep.addSuppressed(ioe);
}
throw verifExcep;
}
Expand All @@ -255,15 +252,13 @@ public SSLSession negotiate(SSLSocketFactory factory) throws IOException {
* @throws IOException If an IO error was encountered while closing the
* TLS connection
*/
@Override
public void close() throws IOException {

if (isClosed) {
if (closed) {
return;
}

if (debug) {
System.out.println("StartTLS: replacing SSL " +
"streams with originals");
System.out.println("StartTLS: closing");
}

// Replace SSL streams with the original streams
Expand All @@ -273,9 +268,13 @@ public void close() throws IOException {
if (debug) {
System.out.println("StartTLS: closing SSL Socket");
}
sslSocket.close();

isClosed = true;
try {
if (sslSocket != null) {
sslSocket.close();
}
} finally {
closed = true;
}
}

/**
Expand All @@ -298,9 +297,8 @@ public void setConnection(Connection ldapConnection, String hostname) {
* Returns the default SSL socket factory.
*
* @return The default SSL socket factory.
* @throws IOException If TLS is not supported.
*/
private SSLSocketFactory getDefaultFactory() throws IOException {
private SSLSocketFactory getDefaultFactory() {

if (defaultFactory != null) {
return defaultFactory;
Expand Down Expand Up @@ -370,9 +368,13 @@ private SSLSocket startHandshake(SSLSocketFactory factory)
System.out.println("StartTLS: Got IO error during handshake");
e.printStackTrace();
}

sslSocket.close();
isClosed = true;
try {
close();
} catch (IOException ioe) {
if (e != ioe) {
e.addSuppressed(ioe);
}
}
throw e; // pass up exception
}

Expand Down Expand Up @@ -441,20 +443,4 @@ private boolean verify(String hostname, SSLSession session)
"server's certificate.", e);
}
}

/*
* Get the peer principal from the session
*/
private static Principal getPeerPrincipal(SSLSession session)
throws SSLPeerUnverifiedException {
Principal principal;
try {
principal = session.getPeerPrincipal();
} catch (AbstractMethodError e) {
// if the JSSE provider does not support it, return null, since
// we need it only for Kerberos.
principal = null;
}
return principal;
}
}
Loading