2

I want to get the domain name in java before I determine which certificate I will use to send back. How can I achieve that?

Do I need to analyze the bytes somehow myself? or is there a library for this? or can some java SSL lib do it?

related post Extract Server Name Indication (SNI) from TLS client hello

but I am hoping to just use java library to get the host name.

Community
  • 1
  • 1
Dean Hiller
  • 19,235
  • 25
  • 129
  • 212
  • You don't need it before using the `SSLEngine,` you need it in your `KeyManager.getServerAliases()/chooseServerAlias()` methods. – user207421 Feb 10 '16 at 03:39
  • @EJP ok? so what method do I call when I receive the handshake message? KeyManagerFactory.processClientHelloHandshake(byte[] data)? I also see no methods on KeyManager here.... https://docs.oracle.com/javase/7/docs/api/index.html?javax/net/ssl/KeyManager.html – Dean Hiller Feb 10 '16 at 15:00
  • It will call you, not the other way around. The engine will call the methods I mentioned. – user207421 Feb 10 '16 at 17:19

2 Answers2

2

Quite unexplicable, this is impossible to do directly with SSLEngine.

I came across the same problem myself and ended up writing a library (TLS Channel). It does not do only that, it is actually a complete abstraction for SSLEngine, exposed as a ByteChannel. Regarding SNI, a function can be supplied to the server channel, to select SSLContexts depending on the supplied domain name.

Mariano Barrios
  • 461
  • 5
  • 10
  • 1
    There simply isn't anything that beats German engineers. This is absolutely fantastic! Thank you for making this available. I took the liberty to include your code for extracting SNIs in an edit suggestion. – Janus Varmarken Feb 21 '19 at 06:47
1

You don't need it before using the SSLEngine. You need it in your custom KeyManager implementation, in the chooseServerAlias() method. You will need to discover the domain name by one of the techniques listed below, then create your X509KeyManager implementation, configured appropriately so as to return the appropriate keystore alias, then construct an SSLContext, initialize it with your KeyManager, then construct your SSLEngine. During the handshake the engine will call your key manager.

  1. SNI. If the client supports SNI you can get the domain name from the initial ClientHello message as shown in your link. You will need to restore the ByteBuffer to its prior state after parsing it so that the SSLEngine can also parse it.

  2. Otherwise you're relying on the IP addresses of each domain being different. You must already have a SocketChannel, so you already know the target address of the connection, i.e. the address the client used to connect to you, via SocketChannel.getLocalAddress(), so all you can do is map the domain name from that, if your domains have different IP addresses.

user207421
  • 305,947
  • 44
  • 307
  • 483