org.apache.commons.httpclient.contrib.ssl
public class TrustSSLProtocolSocketFactory extends HttpSecureProtocol
Socket
s
that accepts self-signed certificates. Unlike EasySSLProtocolSocketFactory,
TrustSSLProtocolSocketFactory can be used in production. This is because
it forces you to pre-install the self-signed certificate you are going to
trust locally.
TrustSSLProtocolSocketFactory can parse both Java Keystore Files (*.jks)
and base64 PEM encoded public certificates (*.pem).
Example of using TrustSSLProtocolSocketFactory
1. First we must find the certificate we want to trust. In this example we'll use gmail.google.com's certificate. openssl s_client -showcerts -connect gmail.google.com:443 2. Cut & paste into a "cert.pem" any certificates you are interested in trusting in accordance with your security policies. In this example I'll actually use the current "gmail.google.com" certificate (instead of the Thawte CA certificate that signed the gmail certificate - that would be too boring) - but it expires on June 7th, 2006, so this example won't be useful for very long! Here's what my "cert.pem" file looks like: -----BEGIN CERTIFICATE----- MIIDFjCCAn+gAwIBAgIDP3PeMA0GCSqGSIb3DQEBBAUAMEwxCzAJBgNVBAYTAlpB MSUwIwYDVQQKExxUaGF3dGUgQ29uc3VsdGluZyAoUHR5KSBMdGQuMRYwFAYDVQQD Ew1UaGF3dGUgU0dDIENBMB4XDTA1MDYwNzIyMTI1N1oXDTA2MDYwNzIyMTI1N1ow ajELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1v dW50YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxGTAXBgNVBAMTEGdtYWls Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoRiWYW0hZw 9TSn3s9912syZg1CP2TaC86PU1Ao2qf3pVu7Mx10Wl8W+aKZrQlvrYjTwku4sEh+ 9uI+gWnfmCd0OyVcXr1eFOGCYiiyaPv79Wtb0m0d8GuiRSJhYkZGzGlgFViws2vR BAMCD2fdp7WGJUVGYOO+s52dgAMUHQXxAgMBAAGjgecwgeQwKAYDVR0lBCEwHwYI KwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwNgYDVR0fBC8wLTAroCmgJ4Yl aHR0cDovL2NybC50aGF3dGUuY29tL1RoYXd0ZVNHQ0NBLmNybDByBggrBgEFBQcB AQRmMGQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0ZS5jb20wPgYIKwYB BQUHMAKGMmh0dHA6Ly93d3cudGhhd3RlLmNvbS9yZXBvc2l0b3J5L1RoYXd0ZV9T R0NfQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQEEBQADgYEAktM1l1cV ebi+Uo6fCE/eLnvvY6QbNNCsU5Pi9B5E1BlEUG+AGpgzE2cSPw1N4ZZb+2AWWwjx H8/IrJ143KZZXM49ri3Z2e491Jj8qitrMauT7/hb16Jw6I02/74/do4TtHu/Eifr EZCaSOobSHGeufHjlqlC3ehC4Bx4mLexIMk= -----END CERTIFICATE----- 3. Run "openssl x509" to analyze the certificate more deeply. This helps us answer questions like "Do we really want to trust it? When does it expire? What's the value of the CN (Common Name) field?". "openssl x509" is also super cool, and will impress all your friends, coworkers, family, and that cute girl at the starbucks. :-) If you dig through "man x509" you'll find this example. Run it: openssl x509 -in cert.pem -noout -text 4. Rename "cert.pem" to "gmail.pem" so that step 5 works. 5. Setup the TrustSSLProtocolSocketFactory to trust "gmail.google.com" for URLS of the form "https-gmail://" - but don't trust anything else when using "https-gmail://": TrustSSLProtocolSocketFactory sf = new TrustSSLProtocolSocketFactory( "/path/to/gmail.pem" ); Protocol trustHttps = new Protocol("https-gmail", sf, 443); Protocol.registerProtocol("https-gmail", trustHttps); HttpClient client = new HttpClient(); GetMethod httpget = new GetMethod("https-gmail://gmail.google.com/"); client.executeMethod(httpget); 6. Notice that "https-gmail://" cannot connect to "www.wellsfargo.com" - the server's certificate isn't trusted! It would still work using regular "https://" because Java would use the "jre/lib/security/cacerts" file. httpget = new GetMethod("https-gmail://www.wellsfargo.com/"); client.executeMethod(httpget); javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found 7. Of course "https-gmail://" cannot connect to hosts where the CN field in the certificate doesn't match the hostname. The same is supposed to be true of regular "https://", but HTTPClient is a bit lenient. httpget = new GetMethod("https-gmail://gmail.com/"); client.executeMethod(httpget); javax.net.ssl.SSLException: hostname in certificate didn't match: <gmail.com> != <gmail.google.com> 8. You can use "*.jks" files instead of "*.pem" if you prefer. Use the 2nd constructor in that case to pass along the JKS password: new TrustSSLProtocolSocketFactory( "/path/to/gmail.jks", "my_password".toCharArray() );
Constructor and Description |
---|
TrustSSLProtocolSocketFactory(String pathToTrustStore) |
TrustSSLProtocolSocketFactory(String pathToTrustStore,
char[] password) |
createSocket
addAllowedName, addAllowedNames, addTrustMaterial, clearAllowedNames, createSocket, createSocket, createSocket, createSocket, createSocket, createSocket, createSocket, getAllowedNames, getAssociatedCertificateChain, getCheckCRL, getCheckExpiry, getCheckHostname, getConnectTimeout, getCurrentServerChain, getDefaultCipherSuites, getDefaultProtocol, getEnabledCiphers, getEnabledProtocols, getHostnameVerifier, getNeedClientAuth, getSoTimeout, getSSLContext, getSSLWrapperFactory, getSupportedCipherSuites, getTrustChain, getUseClientMode, getWantClientAuth, setCheckCRL, setCheckExpiry, setCheckHostname, setConnectTimeout, setDefaultProtocol, setEnabledCiphers, setEnabledProtocols, setHostnameVerifier, setKeyMaterial, setNeedClientAuth, setSoTimeout, setSSLWrapperFactory, setTrustMaterial, setUseClientMode, setWantClientAuth, useDefaultJavaCiphers, useStrongCiphers
getDefault
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
createSocket
createSocket, createSocket
public TrustSSLProtocolSocketFactory(String pathToTrustStore) throws GeneralSecurityException, IOException
pathToTrustStore
- Path to either a ".jks" Java Key Store, or a
".pem" base64 encoded certificate. If it's a
".pem" base64 certificate, the file must start
with "------BEGIN CERTIFICATE-----", and must end
with "-------END CERTIFICATE--------".GeneralSecurityException
IOException
public TrustSSLProtocolSocketFactory(String pathToTrustStore, char[] password) throws GeneralSecurityException, IOException
pathToTrustStore
- Path to either a ".jks" Java Key Store, or a
".pem" base64 encoded certificate. If it's a
".pem" base64 certificate, the file must start
with "------BEGIN CERTIFICATE-----", and must end
with "-------END CERTIFICATE--------".password
- Password to open the ".jks" file. If "truststore"
is a ".pem" file, then password can be null; if
password isn't null and we're using a ".pem" file,
then technically, this becomes the password to
open up the special in-memory keystore we create
to hold the ".pem" file, but it's not important at
all.CertificateException
KeyStoreException
IOException
NoSuchAlgorithmException
KeyManagementException
GeneralSecurityException