Now that I could link OpenSSL library to my program, I tried to use it for a simple client connection to a TLS server.
I found a client example code and run it. It seemed working fine until I found the subject of the server certificate shows the wrong host name from I requested.
It turned out that when a server hosts multiple domains (virtual hosting), the server returns the *default* certificate because it doesn’t know which domain the client wants. This clearly doesn’t work for any virtual-hosted sites.
By examining the WireShark packets sent by Chrome browser, I could spot “server_name” extension which includes the host name within a ClientHello request. This is called Server Name Indication (SNI) and it works pretty much in the same way as HTTP’s “host” header.
I could easily find the solution. It’s a simple function call to SSL_set_tlsext_host_name.
I could now get a valid response from the server by sending a minimum HTTP request : “GET /index.html HTTP/1.1\r\nHost: <server_host_name_here>\r\n\r\n”.
SNI is also useful for the middlemen to monitor which site you are accessing. It is said South Korean Government is checking the SNI field to prevent people from accessing ‘bad sites’ such as porn sites and North Korea’s official sites. They may have to change their tactics once TLS 1.3 prevails because it also encrypts SNI field.