Return-Path: Delivered-To: apmail-jakarta-httpcomponents-dev-archive@www.apache.org Received: (qmail 23692 invoked from network); 27 Jan 2007 20:09:21 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 27 Jan 2007 20:09:21 -0000 Received: (qmail 7383 invoked by uid 500); 27 Jan 2007 20:09:27 -0000 Delivered-To: apmail-jakarta-httpcomponents-dev-archive@jakarta.apache.org Received: (qmail 7347 invoked by uid 500); 27 Jan 2007 20:09:27 -0000 Mailing-List: contact httpcomponents-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "HttpComponents Project" Delivered-To: mailing list httpcomponents-dev@jakarta.apache.org Received: (qmail 7336 invoked by uid 99); 27 Jan 2007 20:09:27 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 27 Jan 2007 12:09:27 -0800 X-ASF-Spam-Status: No, hits=2.9 required=10.0 tests=HTML_10_20,HTML_MESSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (herse.apache.org: domain of juliusdavies@gmail.com designates 66.249.82.237 as permitted sender) Received: from [66.249.82.237] (HELO wx-out-0506.google.com) (66.249.82.237) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 27 Jan 2007 12:09:12 -0800 Received: by wx-out-0506.google.com with SMTP id h31so1185337wxd for ; Sat, 27 Jan 2007 12:08:52 -0800 (PST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:mime-version:content-type; b=UICETx7dXjLbjKDmKdU0Sh0+ZubNaam7QotM2Oxl3jBAfJ1qlWUhRPqtQ9flDKIk5CaET5ryXewHpjJQ923QRncU7fAVUhyasJgYvHrstsQBYIOUmv6Lq787Jgd6o18iAkWcIMWKT34l+P8tLsvEI4Lk02VT6djxS5yQXyXqucI= Received: by 10.90.68.15 with SMTP id q15mr5040393aga.1169928531799; Sat, 27 Jan 2007 12:08:51 -0800 (PST) Received: by 10.90.67.9 with HTTP; Sat, 27 Jan 2007 12:08:51 -0800 (PST) Message-ID: <598ad5b50701271208r22ddd8e9od45d0cb1a0311ef8@mail.gmail.com> Date: Sat, 27 Jan 2007 12:08:51 -0800 From: "Julius Davies" To: "HttpComponents Project" Subject: introduce a "hook" for not-yet-commons-ssl? MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_52246_29257585.1169928531773" X-Virus-Checked: Checked by ClamAV on apache.org ------=_Part_52246_29257585.1169928531773 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, Folks, Don't worry - it's not "not-yet-commons-ssl" dependent at all! It's a generic way to allow any default user-defined socket factory. I'm pinching the technique from something I saw when using SSL and LDAP in Java: ----------------------------------------------------------------------- Example showing "ldaps://" with Java ----------------------------------------------------------------------- // Build Hashtable environment for LDAP binding. Hashtable env = new Hashtable(); env.put( Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory" ); env.put( Context.PROVIDER_URL, "ldap://ldap.mydomain.com" ); env.put( Context.SECURITY_AUTHENTICATION, "simple" ); env.put( Context.SECURITY_PRINCIPAL, windowsUser + "@mydomain.com" ); env.put( Context.SECURITY_CREDENTIALS, windowsPassword ); env.put( Context.REFERRAL, "follow" ); env.put( Context.SECURITY_PROTOCOL, "ssl" ); // Here's the important part - the "hook": env.put( "java.naming.ldap.factory.socket", "a.b.c.MySoCalledSSLFactory" ); LdapContext ctx = new InitialLdapContext( env, null ); ----------------------------------------------------------------------- I just wrote an email to "commons-dev" detailing this idea. I thought httpcomponents might also find it interesting, so here's a copy & paste of that email I just wrote to "commons-dev": ----------------------------------------------------------------------- If you are interested, here's how you provide the hook to " not-yet-commons-ssl.jar". Add a new "config property" (config file, System.getProperty(), get/set bean... however you normally do these things) to your library. The property should be something like this: "org.apache.commons.net.ssl.clientFactory" If the property is not, your library should probably just default to this: HttpsURLConnection.getDefaultSSLSocketFactory(); That's usually preferable to SSLSocketFactory.getDefault() because HttpsURLConnection's default socket factory will magically use the browser's ssl-proxy settings and client certs if Java is being run from "Webstart" or from an applet. (And, seriously, you never know where someone is going to use your library!) Anyway... back to "not-yet-commons-ssl".... Suppose the following is set: org.apache.commons.net.ssl.factory=a.b.c.SSL The contract of the "hook" is that the class specified will contain a static getDefault() method, so you can use this to get the factory: Class c = Class.forName( "a.b.c.SSL" ); Method m = c.getMethod( "getDefault", null ); SSLSocketFactory sf = (SSLSocketFactory) m.invoke( null, null ); Meanwhile, the application developer who's using your library can then do something like this to specify a particular set of TrustAnchors, Client Certificates, special validation, etc, that they know they need when using SSL in their environment. (Really handy for dealing with self-signed "dev" certs in a way that doesn't pollute every SSL socket then created anywhere in the JVM!). package a.b.c; public class SSL extends org.apache.commons.ssl.SSLClient { public SSL() throws GeneralSecurityException, IOException { super(); super.setCheckCRL( true ); super.setCheckHostname ( false ); super.setCheckExpiry( false ); TrustMaterial tm = new TrustMaterial( "/path/to/certs.pem" ); char[] password = "secret".toCharArray(); KeyMaterial km = new KeyMaterial( "/path/to/pkcs12.der", password ); super.setTrustMaterial( tm ); super.setKeyMaterial( km ); } } The nice thing about this hook: "commons-net" doesn't have to include ANY reference to "not-yet-commons-ssl". There's no compile-time dependency, and certainly no runtime dependency. The static getDefault() method is already a standard part of javax.net.ssl.SSLSocketFactory! Application developers using your library *could* specify this! org.apache.commons.net.ssl.clientFactory=javax.net.ssl.SSLSocketFactory ----------------------------------------------------------------------- Bringing this back to "o.a.c.http", this technique is all about one line in the code, and nothing else: // Line 215 of o.a.c.h.conn.ssl.SSLSocketFactory: this.socketfactory = HttpsURLConnection.getDefaultSSLSocketFactory(); That line of code would change to look for a property first before finally settling on HttpsURLConnection.getDefaultSSLSocketFactory(). All our existing "SecureSocketFactory" stuff still remains the same, because it's very handy (I would even say "critically important") to be able to create "https-abc://" and "https-xyz://" schemes that have different SSL behaviour. But this does allow an application to quickly change the default behaviour of "http.client" SSL without touching anything else. I think it could also become a good "standard technique" for all libraries that create SSL sockets. -- yours, Julius Davies 416-652-0183 http://juliusdavies.ca/ ------=_Part_52246_29257585.1169928531773--