org.apache.commons.httpclient.contrib.ssl

## Class TrustSSLProtocolSocketFactory

- java.lang.Object
- - javax.net.SocketFactory
  - - javax.net.ssl.SSLSocketFactory
    - - org.apache.commons.ssl.SSLClient
      - - org.apache.commons.ssl.HttpSecureProtocol
        - - org.apache.commons.httpclient.contrib.ssl.TrustSSLProtocolSocketFactory

All Implemented Interfaces:
  org.apache.commons.httpclient.protocol.ProtocolSocketFactory, org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory

    public class TrustSSLProtocolSocketFactory
    extends HttpSecureProtocol

TrustSSLProtocolSocketFactory allows you exercise full control over the HTTPS server certificates you are going to trust. Instead of relying on the Certificate Authorities already present in "jre/lib/security/cacerts", TrustSSLProtocolSocketFactory only trusts the public certificates you provide to its constructor.

TrustSSLProtocolSocketFactory can be used to create SSL `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() );

Since:
  17-Feb-2006
Author:
  Credit Union Central of British Columbia, www.cucbc.com, juliusdavies@cucbc.com

  DISCLAIMER: HttpClient developers DO NOT actively support this component. The component is provided as a reference material, which may be inappropriate for use without additional customization.

### Constructor Summary

Constructors
Constructor and Description
`TrustSSLProtocolSocketFactory(java.lang.String pathToTrustStore)`
`TrustSSLProtocolSocketFactory(java.lang.String pathToTrustStore, char[] password)`

### Method Summary

### Methods inherited from class org.apache.commons.ssl.HttpSecureProtocol

`createSocket`

### Methods inherited from class org.apache.commons.ssl.SSLClient

`addTrustMaterial, createSocket, createSocket, createSocket, createSocket, createSocket, createSocket, createSocket, getAssociatedCertificateChain, getCheckCRL, getCheckExpiry, getCheckHostname, getConnectTimeout, getCurrentServerChain, getDefaultCipherSuites, getDefaultProtocol, getEnabledCiphers, getEnabledProtocols, getHostnameVerifier, getNeedClientAuth, getSoTimeout, getSSLContext, getSSLWrapperFactory, getSupportedCipherSuites, getTrustChain, getUseClientMode, getWantClientAuth, isSecure, setCheckCRL, setCheckExpiry, setCheckHostname, setConnectTimeout, setDefaultProtocol, setDnsOverride, setEnabledCiphers, setEnabledProtocols, setHostnameVerifier, setIsSecure, setKeyMaterial, setNeedClientAuth, setSoTimeout, setSSLWrapperFactory, setTrustMaterial, setUseClientMode, setWantClientAuth, useDefaultJavaCiphers, useStrongCiphers`

### Methods inherited from class javax.net.ssl.SSLSocketFactory

`getDefault`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Methods inherited from interface org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory

`createSocket`

### Methods inherited from interface org.apache.commons.httpclient.protocol.ProtocolSocketFactory

`createSocket, createSocket`

### Constructor Detail

#### TrustSSLProtocolSocketFactory

    public TrustSSLProtocolSocketFactory(java.lang.String pathToTrustStore)
                                  throws java.security.GeneralSecurityException,
                                         java.io.IOException

Parameters:
  `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--------".
Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### TrustSSLProtocolSocketFactory

    public TrustSSLProtocolSocketFactory(java.lang.String pathToTrustStore,
                                 char[] password)
                                  throws java.security.GeneralSecurityException,
                                         java.io.IOException

Parameters:
  `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.
Throws:
  `java.security.cert.CertificateException`
  `java.security.KeyStoreException`
  `java.io.IOException`
  `java.security.NoSuchAlgorithmException`
  `java.security.KeyManagementException`
  `java.security.GeneralSecurityException`