JDK-4773451 : Support IP address based virtual hosting in default KeyManager implementation
  • Type: Enhancement
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86
  • Submitted: 2002-11-04
  • Updated: 2014-05-02
  • Resolved: 2014-05-02
Related Reports
Relates :  
Description

Name: nt126004			Date: 11/04/2002


FULL PRODUCT VERSION :
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)


FULL OPERATING SYSTEM VERSION : Linux version 2.2.20 (gcc
version egcs-2.91.66 19990314/Linux (egcs-1.1.2
release))

patched redhat 6.1


A DESCRIPTION OF THE PROBLEM :
When using multiple SSLServerSockets with each listening on
it's own IP address, the JVM is not correctly sending the
correct certificate to the connecting client's web browser.
 Regardless of which domain/IP the browser attempts to
connect to, the JVM always maps the domain/IP for the first
listed certificate in the keystore.

Example:  domains abc.com, def.com, ghi.com each have their
own self-signed certificate in keystore , each created using
'keytool -genkey' and created in same order.  Each also
being domain mapped to their own IP address and served
through their own SSLServerSocket.

When a client attempts to connect to abc.com, all is well.
The correct certificate is presented to the client and
connection succeeds.  However, when the client attempt to
connect to either def.com or ghi.com, they are presented
with the certificate for abc.com.

If client connecting to def.com or ghi.com elects to accept
that incorrect certificate, connection succeeds to proper
site, despite use of incorrect certificate.  So correct
domain/IP mapping is not the issue.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.  map 2 different domains to different IP's
2.  use keytool -genkey to create certificates for both
3.  write simple listeners using SSLServerSocket at each domain
4.  attempt to connect to each domain with a web browser
(I've tried Mozilla, Netscape and IE) and pay attention to
the certificate presented.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected: client should be presented with the proper
certificate for the domain being connected to.

Actual: client is presented with the first certificate in
the keystore.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

import javax.net.*;
import javax.net.ssl.*;
import java.net.*;


public class TestSSLServer extends Thread implements Runnable
{

	private static String[] arg;



	public TestSSLServer()
	{
	}



	/**
	 * Pass in the 2 domain names to listen at.
	 */
	public static void main(String argv[])
	{
		arg = argv;
		// startup the one and only thread of this class
		new Thread(new TestSSLServer()).start();
	}



	public void run()
	{
		try
		{
			ServerSocketFactory factory = SSLServerSocketFactory.getDefault();

			// create socket 1
			ServerSocket s1 = factory.createServerSocket(443, 1, InetAddress.getByName(arg[0]));
			TcpServer ts1 = new TcpServer(s1);
			ts1.start();

			// create socket 2
			ServerSocket s2 = factory.createServerSocket(443, 1, InetAddress.getByName(arg[1]));
			TcpServer ts2 = new TcpServer(s2);
			ts2.start();

			sleep(60000);
		}
		catch(Throwable t)
		{
			t.printStackTrace();
		}
		
	}
	
	
	
	class TcpServer extends Thread
	{
		private ServerSocket ss;
		
		
		public TcpServer(ServerSocket p_ss)
		{
			ss = p_ss;
		}
		
		public void run()
		{
			try
			{
				while(true)
				{
					Socket newSocket = ss.accept();
					newSocket.getOutputStream().write("hello".getBytes());
				}
			}
			catch(Throwable t)
			{
				t.printStackTrace();
			}
		}
	}
}


---------- END SOURCE ----------

CUSTOMER WORKAROUND:
We did find a work around with help from hot dispatch. We ended up creating
a key store for each domain that we want to serve a https connection for. It
would be easier if we could put all the keys in one key store per the bug
report and have JVM manage the keys correctly. I guess this is longer
critical for us since we were able to work around it.
(Review ID: 163381) 
======================================================================

Comments
This has already been addressed partially before the support for SNI was added in JDK 8 (See JDK-7068321). With the support for SNI, it is now fully addressed and can be closed.
02-05-2014

WORK AROUND Setup a separate SSLContext with an appropriately populated KeyManager for each IP address. ###@###.### 2002-11-05
05-11-2002

EVALUATION This type of virtual hosting is not something we currently claim to support, changing to RFE. We will look at this for a future release. ###@###.### 2002-11-05
05-11-2002