I find myself having to investigate why an SSL service is not working from time to time. Usually this happens when I’m on a remote shell and don’t have access to a web browser. Debugging cleartext services is usually easy because they usually return a banner or other data after making a connection to them. For instance with the HTTP protocol you can simply do something like:
# echo -e -n "HEAD / HTTP/1.0\r\n\r\n" | nc foo.bar.com 80
HTTP/1.1 500 No Context configured to process this request
Content-Type: text/html
Date: Wed, 26 Jan 2005 16:08:19 GMT
Server: Apache Tomcat/4.0.1 (HTTP/1.1 Connector)
Connection: close
The openssl command line tool has an option, s_client, that implements a generic client that can speak SSL/TLS. If we were to use nc to connect to the host on its SSL speaking port it would not return anything. So using the openssl tool we do this in order to test https://cisco.com:
# openssl s_client -connect cisco.com:443
CONNECTED(00000003)
depth=0 /C=US/ST=California/L=San Jose/O=Cisco Systems/OU=ITG-WSI(cco-sj-1)/CN=www.cisco.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 /C=US/ST=California/L=San Jose/O=Cisco Systems/OU=ITG-WSI(cco-sj-1)/CN=www.cisco.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 /C=US/ST=California/L=San Jose/O=Cisco Systems/OU=ITG-WSI(cco-sj-1)/CN=www.cisco.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/C=US/ST=California/L=San Jose/O=Cisco Systems/OU=ITG-WSI(cco-sj-1)/CN=www.cisco.com
i:/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDyDCCAzWgAwIBAgIQG0uiUxcuxmQb7twrU/JutzANBgkqhkiG9w0BAQUFADBf
MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXUlNBIERhdGEgU2VjdXJpdHksIEluYy4x
LjAsBgNVBAsTJVNlY3VyZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
HhcNMDQwNDA4MDAwMDAwWhcNMDYwNDI0MjM1OTU5WjCBgTELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExETAPBgNVBAcUCFNhbiBKb3NlMRYwFAYDVQQK
FA1DaXNjbyBTeXN0ZW1zMRowGAYDVQQLFBFJVEctV1NJKGNjby1zai0xKTEWMBQG
A1UEAxQNd3d3LmNpc2NvLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
3U8aY/Ucx4HQGFPqojIiPBqJ3AqJDP5ELC0+LYNj+FfPkiIRb5IkjW1eI/ko1W8K
qWVVmWmZ/LawudemBy/m3HxzC/h2qxWM0SZmOF6TdBgIauxo+0iy1g6cVfyoSBo4
g2Vr1Qui9Hygbi5ImTlo5lDSlq+oI1qDEmxKNIxjUJcCAwEAAaOCAWQwggFgMAkG
A1UdEwQCMAAwCwYDVR0PBAQDAgWgMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9j
cmwudmVyaXNpZ24uY29tL1JTQVNlY3VyZVNlcnZlci5jcmwwRAYDVR0gBD0wOzA5
BgtghkgBhvhFAQcXAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy52ZXJpc2ln
bi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA0BggrBgEF
BQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTBt
BggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglpbWFnZS9naWYwITAfMAcGBSsOAwIa
BBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNodHRwOi8vbG9nby52ZXJpc2lnbi5j
b20vdnNsb2dvLmdpZjANBgkqhkiG9w0BAQUFAAN+AInV44pc9opxUWRuRZGE02VL
OWx97/UT49Fi/VbL7VaR39EZ1gXAFtnNPFZ5+X/SUzUqQD0g04u/8cYpMsYPfsr/
vh6sym/jGXHNWaSkWGcUKM23b7XFJpYaZO1PHuYKN19vV32TlnsFJBNQ5YuW5UxT
EKF1Oatw5nzxpTpK
-----END CERTIFICATE-----
subject=/C=US/ST=California/L=San Jose/O=Cisco Systems/OU=ITG-WSI(cco-sj-1)/CN=www.cisco.com
issuer=/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority
---
No client certificate CA names sent
---
SSL handshake has read 1536 bytes and written 340 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
SSL-Session:
Protocol : TLSv1
Cipher : DHE-RSA-AES256-SHA
Session-ID: 2932C689345E5C302FE75477926FE21ACDB2CD8D86AF720B7FBF96BF94B17994
Session-ID-ctx:
Master-Key: 6D9817BBCE4723C870BAAB33FDCFFA7419DCFA192605760A93977763E31F48218C388A6D184CDE6A6C12EF8CE37DC8A1
Key-Arg : None
Krb5 Principal: None
Start Time: 1106755570
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
At this point we can interact with the web service just like we did with the HTTP service earlier:
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Wed, 26 Jan 2005 16:23:58 GMT
Server: Apache/1.0 (Unix) mod_ssl/2.8.16 OpenSSL/0.9.7d
Set-Cookie: CP_GUTC=198.7.47.200.7211106756640314; path=/; expires=Sun, 20-Jan-30 16:23:58 GMT; domain=.cisco.com
Last-Modified: Tue, 14 Dec 1999 19:03:53 GMT
ETag: "330c3-41-38569499"
Accept-Ranges: bytes
Content-Length: 65
Connection: close
Content-Type: text/html
I find it useful to use the -nbio argument along with the -state argument for openssl which runs it with non-blocking IO while printing states so you can use tools like grep:
# openssl s_client -connect cisco.com:443 -state -nbio 2>&1 | grep SSL
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:error in SSLv2/v3 read server hello A
SSL_connect:SSLv3 read server hello A
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server key exchange A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:error in SSLv3 read finished A
SSL_connect:error in SSLv3 read finished A
SSL_connect:SSLv3 read finished A
SSL handshake has read 1536 bytes and written 340 bytes
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
SSL-Session: