Showing posts with label SSL. Show all posts
Showing posts with label SSL. Show all posts

Enforcing JDBC clients to use SSL with MySQL Server

1. First you need to enable SSL at both the server and the client as per my previous blog post.

2. There you would have noticed that - even though we enabled SSL at the server end - still the JDBC clients can connect with out using SSL.

3. To enforce SSL for the JDBC connection from the client end - we need to have REQUIRE SSL - in the GRANT statement for the MySQL user associated with the JDBC client.

e.g :

GRANT ALL ON regdb.* TO regadmin@localhost IDENTIFIED BY "regadmin" REQUIRE SSL;

4. Now regadmin user won't be able to connect to the regdb database without a JDBC connection over SSL.

How to fetch HTTPS end point certificate chain via Shell ?

You can do it through the web browser - and download each and every certificate...

Following is the easy way via shell..
$ openssl s_client -showcerts  -connect www.amazon.com:443 > ssl.log

depth=1 C = US, O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = Terms of use at https://www.verisign.com/rpa (c)09, CN = VeriSign Class 3 Secure Server CA - G2
verify error:num=20:unable to get local issuer certificate
verify return:0

CtrL+C

$ sed -n  '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' ssl.log  > cert.pem
The above will save the certificate chain corresponding to www.amazon.com in cert.pem file.
-----BEGIN CERTIFICATE-----
MIIE9jCCA96gAwIBAgIQJfXRLV5vC9Tq8qLJZvO0zjANBgkqhkiG9w0BAQUFADCB
tTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2Ug
YXQgaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMm
VmVyaVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwHhcNMTAwNzE1
MDAwMDAwWhcNMTMwNzE0MjM1OTU5WjBnMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
V2FzaGluZ3RvbjEQMA4GA1UEBxQHU2VhdHRsZTEYMBYGA1UEChQPQW1hem9uLmNv
bSBJbmMuMRcwFQYDVQQDFA53d3cuYW1hem9uLmNvbTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAvokOoa36fVhqoWrkO+115D7yGffzD/rZ72IQUnv83ZSWqDVr
G1BgLi55rHwuo4HejTf57m5PgsfkEgRVr1dplIzvLlB6bVMPW19iWF7P8t/0Tc5x
toLXhuVPd+SRquS9WmWqniBPOF60i+A2RYCo1SRcRp3xgMBrYqUfJl6uF0cCAwEA
AaOCAdEwggHNMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMEUGA1UdHwQ+MDwwOqA4
oDaGNGh0dHA6Ly9TVlJTZWN1cmUtRzItY3JsLnZlcmlzaWduLmNvbS9TVlJTZWN1
cmVHMi5jcmwwRAYDVR0gBD0wOzA5BgtghkgBhvhFAQcXAzAqMCgGCCsGAQUFBwIB
FhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMB0GA1UdJQQWMBQGCCsGAQUF
BwMBBggrBgEFBQcDAjAfBgNVHSMEGDAWgBSl7wsRzsBBA6NKZZBIshzgVy19RzB2
BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWdu
LmNvbTBABggrBgEFBQcwAoY0aHR0cDovL1NWUlNlY3VyZS1HMi1haWEudmVyaXNp
Z24uY29tL1NWUlNlY3VyZUcyLmNlcjBuBggrBgEFBQcBDARiMGChXqBcMFowWDBW
FglpbWFnZS9naWYwITAfMAcGBSsOAwIaBBRLa7kolgYMu9BSOJsprEsHiyEFGDAm
FiRodHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvMS5naWYwDQYJKoZIhvcN
AQEFBQADggEBAKgV/fW6WoiZDCo9KLt0gmU/QkchH9R41k2etuwXzRi3nvmD5ek5
io/dPGHXwOvxcjTkTz/nM0CpSZ9EsI2/M7F2laNQIY+PDB5ggl4gmPq/GTMaEqFh
YT+oXLiAmqA03N1SjJiFum3OvOBMqZs4xU1WELrvcoobCGh73VlD5TMbCj+9QyrL
7jQ2Q9Vp18p6g6mr5hXvlOiVZSv2nhFOXw4ZAXahMDYGUvEJ4M/UcRYNgLoSJp6T
Sxxfg0ws0Gk7xZkxxEyPJ75JmqwhPkpd4RjTOURiBBbazNjtPYjSpuOub+sTr/Ft
ftICSDU8L5qg9bxV6qR7it5iC3OcWEEcLFE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIGLDCCBZWgAwIBAgIQbk/6s8XmacTRZ8mSq+hYxDANBgkqhkiG9w0BAQUFADCB
wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL
EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1
dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
cmswHhcNMDkwMzI1MDAwMDAwWhcNMTkwMzI0MjM1OTU5WjCBtTELMAkGA1UEBhMC
VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
cnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQgaHR0cHM6Ly93
d3cudmVyaXNpZ24uY29tL3JwYSAoYykwOTEvMC0GA1UEAxMmVmVyaVNpZ24gQ2xh
c3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQDUVo9XOzcopkBj0pXVBXTatRlqltZxVy/iwDSMoJWzjOE3JPMu
7UNFBY6J1/raSrX4Po1Ox/lJUEU3QJ90qqBRVWHxYISJpZ6AjS+wIapFgsTPtBR/
RxUgKIKwaBLArlwH1/ZZzMtiVlxNSf8miKtUUTovStoOmOKJcrn892g8xB85essX
gfMMrQ/cYWIbEAsEHikYcV5iy0PevjG6cQIZTiapUdqMZGkD3pz9ff17Ybz8hHyI
XLTDe+1fK0YS8f0AAZqLW+mjBS6PLlve8xt4+GaRCMBeztWwNsrUqHugffkwer/4
3RlRKyC6/qfPoU6wZ/WAqiuDLtKOVImOHikLAgMBAAGjggKpMIICpTA0BggrBgEF
BQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlzaWduLmNvbTAS
BgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4RQEHFwMwVjAo
BggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2NwczAqBggrBgEF
BQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQGA1UdHwQtMCsw
KaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzIuY3JsMA4GA1Ud
DwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglpbWFnZS9naWYw
ITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNodHRwOi8vbG9n
by52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjApBgNVHREEIjAgpB4wHDEaMBgGA1UE
AxMRQ2xhc3MzQ0EyMDQ4LTEtNTIwHQYDVR0OBBYEFKXvCxHOwEEDo0plkEiyHOBX
LX1HMIHnBgNVHSMEgd8wgdyhgcekgcQwgcExCzAJBgNVBAYTAlVTMRcwFQYDVQQK
Ew5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5
OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYD
VQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrghB92f4Hz6getxB5Z/uniTTGMA0G
CSqGSIb3DQEBBQUAA4GBAGN0Lz1Tqi+X7CYRZhr+8d5BJxnSf9jBHPniOFY6H5Cu
OcUgdav4bC1nHynCIdcUiGNLsJsnY5H48KMBJLb7j+M9AgtvVP7UzNvWhb98lR5e
YhHB2QmcQrmy1KotmDojYMyimvFu6M+O0Ro8XhnF15s1sAIjJOUFuNWI4+D6ufRf
-----END CERTIFICATE-----

Curl with HTTPS

Wrote a blog sometime back on "How to invoke a web service call with curl ?" in RampartFAQ.com - but that doesn't explain how to work with Curl with HTTPS.

Today morning I got a question from one of my colleagues and thought of writing a blog on the $subject in detail..

Let's go with few examples..

1. Invoke https://www.amazon.com
$ curl https://www.amazon.com
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.amazon.com/">here</a>.</p>
</body></html>
2. Above won't print details about the SSL handshake. To view SSL handshake let's use -v as an argument
$ curl -v https://www.amazon.com
* About to connect() to www.amazon.com port 443 (#0)
*   Trying 72.21.214.128... connected
* Connected to www.amazon.com (72.21.214.128) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
*   subject: C=US; ST=Washington; L=Seattle; O=Amazon.com Inc.; CN=www.amazon.com
*   start date: 2010-07-15 00:00:00 GMT
*   expire date: 2013-07-14 23:59:59 GMT
*   common name: www.amazon.com (matched)
*   issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)09; CN=VeriSign Class 3 Secure Server CA - G2
*   SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.21.2 (x86_64-apple-darwin10.5.0) libcurl/7.21.2 OpenSSL/1.0.0b zlib/1.2.5 libidn/1.19
> Host: www.amazon.com
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 02 Dec 2010 07:22:22 GMT
< Server: Server
< Set-Cookie: skin=noskin; path=/; domain=.amazon.com; expires=Thu, 02-Dec-2010 07:22:22 GMT
< Location: http://www.amazon.com/
< Content-Length: 230
< nnCoection: close
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.amazon.com/">here</a>.</p>
</body></html>
* Connection #0 to host www.amazon.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
This HTTPS connection works fine, because, the client trusts the CA of the Amazon's SSL certificate.

By going through the logs you will see, the CA certificates are verified against the curl-ca-bundle.crt file located at /opt/local/share/curl/curl-ca-bundle.crt

If you have a look at the above file, you will see all the trusted CAs listed there..
Verisign Class 1 Public Primary Certification Authority
=======================================================
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCED9pHoGc8JpK83P/uUii5N0wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAxIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAx
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDlGb9to1ZhLZlIcfZn3rmN67eehoAKkQ76OCWvRoiC5XOooJskXQ0fzGVuDLDQ
VoQYh5oGmxChc9+0WDlrbsH2FdWoqD+qEgaNMax/sDTXjzRniAnNFBHiTkVWaR94AoDa3EeRKbs2
yWNcxeDXLYd7obcysHswuiovMaruo2fa2wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFgVKTk8d6Pa
XCUDfGD67gmZPCcQcMgMCeazh88K4hiWNWLMv5sneYlfycQJ9M61Hd8qveXbhpxoJeUwfLaJFf5n
0a3hUKw8fGJLj7qE1xIVGx/KXQ/BUpQqEZnae88MNhPVNdwQGVnqlMEAv3WP2fr9dgTbYruQagPZ
RjXZ+Hxb
-----END CERTIFICATE-----

Verisign Class 3 Public Primary Certification Authority
=======================================================
-----BEGIN CERTIFICATE-----
MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
D/xwzoiQ
-----END CERTIFICATE-----
In the case of Amazon, it's Verisign who the CA is..

3. Let's try to invoke https://amazon.com [Not www.amazon.com]
$ curl -v https://amazon.com
* About to connect() to amazon.com port 443 (#0)
*   Trying 72.21.210.250... connected
* Connected to amazon.com (72.21.210.250) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
*   subject: C=US; ST=Washington; L=Seattle; O=Amazon.com Inc.; CN=www.amazon.com
*   start date: 2010-07-15 00:00:00 GMT
*   expire date: 2013-07-14 23:59:59 GMT
* SSL: certificate subject name 'www.amazon.com' does not match target host name 'amazon.com'
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
curl: (51) SSL: certificate subject name 'www.amazon.com' does not match target host name 'amazon.com'
This fails.. Why ? It's the same CA which is trusted by the Curl client - but it fails due to the host name verification. The certificate was issued to www.amazon.com - not for amazon.com

4. Let's try to invoke https://amazon.com [Not www.amazon.com] - by disabling SSL validations with the argument -k
curl -v -k https://amazon.com
* About to connect() to amazon.com port 443 (#0)
*   Trying 72.21.210.250... connected
* Connected to amazon.com (72.21.210.250) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
*   subject: C=US; ST=Washington; L=Seattle; O=Amazon.com Inc.; CN=www.amazon.com
*   start date: 2010-07-15 00:00:00 GMT
*   expire date: 2013-07-14 23:59:59 GMT
*   common name: www.amazon.com (does not match 'amazon.com')
*   issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)09; CN=VeriSign Class 3 Secure Server CA - G2
*   SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.21.2 (x86_64-apple-darwin10.5.0) libcurl/7.21.2 OpenSSL/1.0.0b zlib/1.2.5 libidn/1.19
> Host: amazon.com
> Accept: */*
> 
< HTTP/1.1 301 Moved Permanently
< Date: Thu, 02 Dec 2010 07:38:04 GMT
< Server: Server
< Location: https://www.amazon.com/
< Content-Length: 231
< Cneonction: close
< Content-Type: text/html; charset=iso-8859-1
< 
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://www.amazon.com/">here</a>.</p>
</body></html>
* Connection #0 to host amazon.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
This succeeds.. since we asked Curl to ignore SSL validation issues..

5. Let's try to invoke a service with a certificate issued from a CA not trusted by Curl. I am using WSO2 ESB here - which ships with a self-signed certificate - so, obviously not trusted by Curl
$ curl -v https://localhost:9447/carbon
* About to connect() to localhost port 9447 (#0)
*   Trying ::1... connected
* Connected to localhost (::1) port 9447 (#0)
* successfully set certificate verify locations:
*   CAfile: /opt/local/share/curl/curl-ca-bundle.crt
  CApath: none
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
You will see, above fails since server certification is not trusted.

6. Let's improve step-5 - by asking Curl to trust our CA certificate.
$ curl -v --cacert esbcert.pem  https://localhost:9447/carbon
Here we specify CA certificate of the ESB - with the argument --cacert

Notes :

1. To find the path of the trusted CA bundle

$ curl-config --ca

2. To set your own trusted CA bundle

$ export CURL_CA_BUNDLE=my-ca-bundle.crt

SSL Debugging - Part - II - Intercepting traffic between WSO2 Carbon FE and BE

All WSO2 products are based on WSO2 Carbon, which sits as the core for all of them.

We do have a clear Front-End [FE], Back-End [BE] separation - where the FE web application talks to the BE, via web service calls.

This benefits the end user - which adds the flexibility of developing his own client to the corresponding back end functionality in a language independent manner.

All UI components you see in the default distribution talk to the BE services via SOAP over HTTPS.

In case of digging in to an issue - since this is on HTTPS - it's hard to intercept the communication channel and figure what exact messages being passed from FE to BE.

This is how you can do it - to intercept messages flowing over SSL.

Prerequisites:
1. ssldump
2. The private key of WSO2 Carbon, in PEM format - you can download it from here.

Run the following command from where you have the private key, and start any WSO2 Carbon based product - say on HTTPS port 9443

:\> sudo ssldump -Ad -k wso2carbon.pem -p wso2carbon -i lo0 host localhost and port 9443

Make sure to have the correct interface set as per your system.[-i lo0] and start the ssldump before you start the server.

Now you can track all the messages between FE and BE in clear text.
1 8 0.0621 (0.0007) C>SV3.1(203) application_data
---------------------------------------------------------------
POST /services/AuthenticationAdmin HTTP/1.1
Content-Type: application/soap+xml; charset=UTF-8; action="urn:login"
User-Agent: Axis2
Host: localhost:9443
Transfer-Encoding: chunked

---------------------------------------------------------------
1 9 0.0626 (0.0005) C>SV3.1(399) application_data
---------------------------------------------------------------
173
    <?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
 <soapenv:Body>
  <ns1:login xmlns:ns1="http://authentication.services.core.carbon.wso2.org">
   <ns1:username>admin</ns1:username>
   <ns1:password>admin</ns1:password>
   <ns1:remoteAddress>0:0:0:0:0:0:0:1%0</ns1:remoteAddress>
  </ns1:login>
 </soapenv:Body>
</soapenv:Envelope>
0

---------------------------------------------------------------
1 10 0.2071 (0.1445) S>CV3.1(544) application_data
---------------------------------------------------------------
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=37FC902E5E7C6C0D081E28B4DF067A76; Path=/; Secure
Content-Type: application/soap+xml;charset=UTF-8
Transfer-Encoding: chunked
Date: Fri, 19 Nov 2010 02:44:26 GMT

11f
    <?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
 <soapenv:Body>
  <ns:loginResponse
   xmlns:ns="http://authentication.services.core.carbon.wso2.org">
   <ns:return>true</ns:return>
  </ns:loginResponse>
 </soapenv:Body>
</soapenv:Envelope>

SSL Debugging - Part - I

We've been involved in many cases solving issues related to SSL.

The latest one I came across was at a customer site, where WSO2 ESB wants to communicate with an SSL end point(WCF) hosted on IIS 7.

The only thing here what we have to do is, importing the CA certificate of the WCF end point to the ESB's client-trustore.jks [which is under ESB_HOME\resources\security].

This worked well at the start - but in one machine it started to fail - with no clue at all..

This is where we need some handy SSL debugging tools - and the easiest one is setting the system property javax.net.debug=all. For example you need to start the WSO2 ESB as,

:\> sh wso2server.sh -Djavax.net.debug=all

Once you set this, it will print the entire SSL handshake.

By going through the logs, we could figure out the issue - where by mistake in this particular machine, in IIS, for this end point - 'Require SSL' being set to Accept, instead of Ignore.

What does that mean.. and why did that fail..?

When we set the above parameter to Accept, the server validates the client certificate only if it's been sent in the request from the client.

In our case at the ESB end we set following two system properties,

System.setProperty("javax.net.ssl.keyStore", "keyStorePath");
System.setProperty("javax.net.ssl.keyStorePassword", "password");


When you set these two, the client will automatically attach the client certificate to the SSL handshake - in our case it failed because we were not expecting mutual authentication, so IIS didn't trust ESB as a client.

Another tool comes in handy while SSL debugging is openssl s_client.

There was a case, where WSO2 ESB talking to an SSL end point behind an Apache server - in that case all the configuration options we provided didn't work - so the option left behind was to test the SSL setup of the Apache server in an independent manner - and proved us Apache server had issues in SSL setup. There we used openssl s_client. For example if you want to verify the SSL handshake with the end point, localhost:9443, you can use the following command.

:\>openssl s_client -connect localhost:9443 -state -nbio 2>&1 | grep "^SSL"

The above will result in the following out put.
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:SSLv3 read finished A
SSL handshake has read 1149 bytes and written 293 bytes
SSL-Session:
To see all the options available with s_client, type the following,

:\>openssl s_client --help

Let's finish off the first part of the SSL debugging series with ssldump.

ssldump is an SSL/TLS network protocol analyzer. It identifies TCP connections on the chosen network interface and attempts to interpret them as SSL/TLS traffic. When it identifies SSL/TLS traffic, it decodes the records and displays them in a textual form to stdout.

:\>sudo ssldump -i en1 port 443

The above prints following [only a part displayed], when I visit https://cloud.wso2.com.
New TCP connection #1: 192.168.1.3(49986) <-> ec2-184-73-175-181.compute-1.amazonaws.com(443)
1 1  0.3614 (0.3614)  C>S  Handshake
      ClientHello
        Version 3.1 
        cipher suites
        Unknown value 0xc00a
        Unknown value 0xc009
        Unknown value 0xc007
        Unknown value 0xc008
        Unknown value 0xc013
        Unknown value 0xc014
        Unknown value 0xc011
        Unknown value 0xc012
        Unknown value 0xc004
        Unknown value 0xc005
        Unknown value 0xc002
        Unknown value 0xc003
        Unknown value 0xc00e
        Unknown value 0xc00f
        Unknown value 0xc00c
        Unknown value 0xc00d
        Unknown value 0x2f
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        Unknown value 0x35
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_RSA_WITH_DES_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC4_40_MD5
        TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
        Unknown value 0x32
        Unknown value 0x33
        Unknown value 0x38
        Unknown value 0x39
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_RSA_WITH_DES_CBC_SHA
        TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_DSS_WITH_DES_CBC_SHA
        TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
        compression methods
                  NULL
1 2  0.7638 (0.4023)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[32]=
          22 24 f7 6c 43 84 ba 39 6f b9 02 5c 4d 76 cf 97 
          ad b4 39 1b 82 fe c1 cf d7 5b 14 41 87 bd 6a 81 
        cipherSuite         Unknown value 0x2f
        compressionMethod                   NULL
1 3  1.1691 (0.4053)  S>C  Handshake
      Certificate
1 4  1.1691 (0.0000)  S>C  Handshake
      ServerHelloDone
1 5  1.1749 (0.0058)  C>S  Handshake
      ClientKeyExchange
1 6  1.1749 (0.0000)  C>S  ChangeCipherSpec
1 7  1.1750 (0.0000)  C>S  Handshake
1 8  1.5787 (0.4037)  S>C  ChangeCipherSpec
1 9  1.5787 (0.0000)  S>C  Handshake
1 10 1.5794 (0.0006)  C>S  application_data
1 11 2.1889 (0.6095)  S>C  application_data
1 12 2.1889 (0.0000)  S>C  application_data
1 13 2.1889 (0.0000)  S>C  application_data
1 14 2.1889 (0.0000)  S>C  application_data
1 15 2.1889 (0.0000)  S>C  application_data
1 16 2.1889 (0.0000)  S>C  application_data
1 17 2.1889 (0.0000)  S>C  application_data
1 18 2.1889 (0.0000)  S>C  application_data
1 19 2.1896 (0.0007)  C>S  Alert
1    2.1902 (0.0005)  C>S  TCP FIN
New TCP connection #2: 192.168.1.3(49987) <-> ec2-184-73-175-181.compute-1.amazonaws.com(443)
2 1  0.3662 (0.3662)  C>S  Handshake
      ClientHello
        Version 3.1 
        resume [32]=
          22 24 f7 6c 43 84 ba 39 6f b9 02 5c 4d 76 cf 97 
          ad b4 39 1b 82 fe c1 cf d7 5b 14 41 87 bd 6a 81 
        cipher suites
        Unknown value 0xc00a
        Unknown value 0xc009
        Unknown value 0xc007
        Unknown value 0xc008
        Unknown value 0xc013
        Unknown value 0xc014
        Unknown value 0xc011
        Unknown value 0xc012
        Unknown value 0xc004
        Unknown value 0xc005
        Unknown value 0xc002
        Unknown value 0xc003
        Unknown value 0xc00e
        Unknown value 0xc00f
        Unknown value 0xc00c
        Unknown value 0xc00d
        Unknown value 0x2f
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        Unknown value 0x35
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_RSA_WITH_DES_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC4_40_MD5
        TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
        Unknown value 0x32
        Unknown value 0x33
        Unknown value 0x38
        Unknown value 0x39
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_RSA_WITH_DES_CBC_SHA
        TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_DSS_WITH_DES_CBC_SHA
        TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
        compression methods
                  NULL
2 2  0.9732 (0.6070)  S>C  Handshake
      ServerHello
        Version 3.1 
        session_id[32]=
          22 24 f7 6c 43 84 ba 39 6f b9 02 5c 4d 76 cf 97 
          ad b4 39 1b 82 fe c1 cf d7 5b 14 41 87 bd 6a 81 
        cipherSuite         Unknown value 0x2f
        compressionMethod                   NULL
2 3  0.9732 (0.0000)  S>C  ChangeCipherSpec
2 4  0.9732 (0.0000)  S>C  Handshake
2 5  0.9735 (0.0003)  C>S  ChangeCipherSpec
2 6  0.9736 (0.0000)  C>S  Handshake
2 7  0.9737 (0.0001)  C>S  application_data
2 8  1.6900 (0.7162)  S>C  application_data
2 9  1.6900 (0.0000)  S>C  application_data
2 10 1.6900 (0.0000)  S>C  application_data
2 11 1.6900 (0.0000)  S>C  application_data
2 12 1.6900 (0.0000)  S>C  application_data
2 13 1.6900 (0.0000)  S>C  application_data
2 14 1.6900 (0.0000)  S>C  application_data
2 15 1.6900 (0.0000)  S>C  application_data
2 16 1.6903 (0.0002)  C>S  Alert
2    1.6909 (0.0006)  C>S  TCP FIN
New TCP connection #3: 192.168.1.3(49988) <-> ec2-184-73-175-181.compute-1.amazonaws.com(443)
3 1  0.3674 (0.3674)  C>S  Handshake
      ClientHello
        Version 3.1 
        resume [32]=
          22 24 f7 6c 43 84 ba 39 6f b9 02 5c 4d 76 cf 97 
          ad b4 39 1b 82 fe c1 cf d7 5b 14 41 87 bd 6a 81 
        cipher suites
        Unknown value 0xc00a
        Unknown value 0xc009
        Unknown value 0xc007
        Unknown value 0xc008
        Unknown value 0xc013
        Unknown value 0xc014
        Unknown value 0xc011
        Unknown value 0xc012
        Unknown value 0xc004
        Unknown value 0xc005
        Unknown value 0xc002
        Unknown value 0xc003
        Unknown value 0xc00e
        Unknown value 0xc00f
        Unknown value 0xc00c
        Unknown value 0xc00d
        Unknown value 0x2f
        TLS_RSA_WITH_RC4_128_SHA
        TLS_RSA_WITH_RC4_128_MD5
        Unknown value 0x35
        TLS_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_RSA_WITH_DES_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC4_40_MD5
        TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
        Unknown value 0x32
        Unknown value 0x33
        Unknown value 0x38
        Unknown value 0x39
        TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_RSA_WITH_DES_CBC_SHA
        TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
        TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
        TLS_DHE_DSS_WITH_DES_CBC_SHA
        TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
        compression methods
                  NULL

Reading SSL certificates from a given url

This code explains how you could read and retrieve an X.509 certificate from a given url.

import java.net.URL;
import java.security.cert.Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public static Certificate readSSLCertFromUrl(String url) throws Exception {
URL hostURL = null;
String hostname = null;
int port;
SSLSocketFactory factory = null;
SSLSocket socket = null;

try {
hostURL = new URL(url);
hostname = hostURL.getHost();

// Check whether the url has a port stated explicitly. If its not present default to 443
port = hostURL.getPort();
if (port == -1) {
port = 443;
}

// Gets the default static SSLSocketFactory that is inherited by new instances of this
// class.
// The socket factories are used when creating sockets for secure https URL connections.
factory = HttpsURLConnection.getDefaultSSLSocketFactory();

// Creates a socket and connects it to the specified remote host at the specified remote
// port. This socket is configured using the socket options established for this
// factory.
socket = (SSLSocket) factory.createSocket(hostname, port);

// Starts an SSL handshake on this connection. Common reasons include a need to use new
// encryption keys, to change cipher suites, or to initiate a new session. To force
// complete reauthentication, the current session could be invalidated before starting
// this handshake.
socket.startHandshake();

// Retrieve the server's certificate chain
Certificate[] serverCerts = socket.getSession().getPeerCertificates();

// The local certificate first followed by any certificate authorities.
if (serverCerts != null && serverCerts.length > 0) {
return serverCerts[0];
} else {
return null;
}

} finally {
// Close the socket
if (socket != null) {
socket.close();
}
}
}

Wildcard certificates with java keytool

Wildcard SSL Certificates let you secure an unlimited number of sub-domains under a single domain name.

This approach has many advantages as well as can be some pitfalls.

Being cheap, ability to secure multiple sub domains and easy to manage are some of the advantages.

At the same time, following lists few pitfalls.

Security: If one server or sub-domain is compromised, all sub-domains may be compromised.

Management: If the wildcard certificate needs to be revoked, all sub-domains will need a new certificate.

Compatibility: Wildcard certificates may not work seamlessly with older server-client configurations.

Let's see how we can create a wildcard certificate with java key tool.

Securing Tomcat

This post explains how you can enable SSL on Tomcat.

Let's first create a self-signed certificate.

[CATALINA_HOME]>keytool -genkey -alias webapp -keyalg RSA -keystore keystore.jks
The above will create a keystore with the name keystore.jks in side [CATALINA_HOME].

Also, notice that here we used webapp as the CN - so, we need to edit the file C:\WINDOWS\system32\drivers\etc\hosts and add the following entry - so we can make our certificate trusted by the browser.

127.0.0.1 webapp

Now, lets edit - [CATALINA_HOME]\conf\server.xml to make Tomcat SSL enabled.

<Service name="Catalina">

<!-- Add the following -->
<!-- 'tomcat' is the password you gave while creating keystore.jks -->
<!-- Make sure keystore.jks is inside [CATALINA_HOME] -->
<Connector port="8443"
maxHttpHeaderSize="8192"
maxThreads="150"
minSpareThreads="25"
maxSpareThreads="75"
enableLookups="false"
disableUploadTimeout="true"
acceptCount="100"
scheme="https"
secure="true"
clientAuth="false"
sslProtocol="TLS"
keystoreFile="keystore.jks"
keystorePass="tomcat"/>
</Service>
All set, hit the url, https://webapp:8443 - now broswer will give you a warning saying that your certificate is not trusted.

Install the cert in the browser to get rid of the warning.

Enabling SSL on WAMP

This step by step guide explains how you can enble SSL on WAMP.

1. Download WampServer 2.0 from here and install it to the default location [c:\wamp].

2. Now, we need to have a private/public key pair as well as a CA to sign our public key.

First, lets see how we can create a private/public key pair.

keytool -genkey -alias rpcert -keyalg RSA -keysize 1024 -dname "CN=identity-rp,L=SL,S=WS,C=LK" -keypass wso2key -keystore rpkeystore.jks -storepass wso2key

This will create a keystore [rpkeystore.jks] with public/private key pair.

My previous post explains how you can export your private key from the keystore. Just follow the steps given there and you'll end up with a file server.key, which is your private key.

Now, we need to sign our public certificate with a CA.

This - requires us to create a sample CA and following explains how to do that.

Here we use OpenSSL to build the required CA infrastructure. For Windows you can download Win32 OpenSSL v0.9.8g from here.

Once installed make sure you add C:\OpenSSL\bin [i.e [INSTALLED_LOCATION]\bin] to the PATH env variable.

openssl req -x509 -newkey rsa:1024 -keyout cakey.pem -out cacert.crt

The above will creare a public/private key pair for our sample CA.

Now, we need to create a certificate signing request to our server.

Go to the folder where you created the keystore [rpkeystore.jks] and issue the following command.

keytool -certreq -v -alias rpcert -file csr.pem -keypass wso2key -storepass wso2key -keystore rpkeystore.jks

Now copy the csr.pem to the folder where you generated keys for the CA and issue the following command from there.

openssl x509 -req -days 365 -in csr.pem -CA cacert.crt -CAkey cakey.pem -CAcreateserial -out server.crt

By now we have all the requiured files.

cacert.crt --> CA public certificate
server.crt --> Server public certificate signed by the CA
server.key --> Server private key.

Copy all the above three files to c:\wamp\bin\apache\apache2.2.8\conf [assuming you installed WAMP to the default location].

Also edit c:\WINDOWS\system32\drivers\etc\hosts file and add the following entry.

127.0.0.1 identity-rp

If you could recall, when we creating the public certificate for our server, we created it for identity-rp.

3. Edit httpd.conf [C:\wamp\bin\apache\apache2.2.8\conf]

Uncomment the following two lines.

LoadModule ssl_module modules/mod_ssl.so

Include conf/extra/httpd-ssl.conf

Find Listen 80 and change it to Listen 12081 - that is our server is running on port number 12081.

Find ServerName and set it to ServerName identity-rp:12081.

4. Edit httpd-ssl.conf [C:\wamp\bin\apache\apache2.2.8\conf\extra]

Set Listen identity-rp:12444 - we are listening to port 12444 for secure communication.

Set <VirtualHost _default_:12444>

Set DocumentRoot "C:/wamp/www/"

Set ServerName identity-rp:12444

For the entire file find "C:/Program Files/Apache Software Foundation/Apache2.2" and replace with "C:/wamp/bin/apache/apache2.2.8".

Find SSLCertificateFile and set SSLCertificateFile "C:/wamp/bin/apache/apache2.2.8/conf/server.crt"

Find SSLCertificateKeyFile and set SSLCertificateKeyFile "C:/wamp/bin/apache/apache2.2.8/conf/server.key"

Find SSLCACertificateFile and set SSLCACertificateFile "C:/wamp/bin/apache/apache2.2.8/conf/cacert.crt"

5. Edit php.ini [C:\wamp\bin\apache\apache2.2.8\bin]

Uncomment the line extension=php_openssl.dll

6. Now we are done - do a syntax check and start the apache server.

:\> cd C:\wamp\bin\apache\apache2.2.8\bin
:\> httpd -t
:\> httpd --start

7. Type https://identity-rp:12444 on your browser - you'll see a certificate error at the brower - to avoid it install CA certificate in your browser.