1 17 18 package org.apache.avalon.cornerstone.blocks.sockets; 19 20 import java.io.IOException ; 21 import java.net.InetAddress ; 22 import java.net.Socket ; 23 import javax.net.ssl.SSLSession; 24 import javax.net.ssl.SSLSocket; 25 import javax.net.ssl.SSLSocketFactory; 26 import org.apache.avalon.cornerstone.services.sockets.SocketFactory; 27 import org.apache.avalon.framework.activity.Initializable; 28 import org.apache.avalon.framework.configuration.Configurable; 29 import org.apache.avalon.framework.configuration.Configuration; 30 import org.apache.avalon.framework.configuration.ConfigurationException; 31 import org.apache.avalon.framework.context.Contextualizable; 32 33 76 public class TLSSocketFactory 77 extends AbstractTLSSocketFactory 78 implements SocketFactory, Contextualizable, Configurable, Initializable 79 { 80 private SSLSocketFactory m_factory; 81 private boolean m_verifyServerIdentity; 82 83 89 public void configure( final Configuration configuration ) 90 throws ConfigurationException 91 { 92 super.configure( configuration ); 93 m_verifyServerIdentity = configuration.getChild( "verify-server-identity" ).getValueAsBoolean( false ); 94 } 95 96 protected void visitBuilder( SSLFactoryBuilder builder ) 97 { 98 m_factory = builder.buildSocketFactory(); 99 } 100 101 105 private Socket initSocket( final Socket socket ) 106 throws IOException 107 { 108 socket.setSoTimeout( m_socketTimeOut ); 109 return socket; 110 } 111 112 122 private SSLSocket sslWrap( Socket bareSocket, InetAddress address, 123 int port ) 124 throws IOException 125 { 126 final String hostName = address.getHostName(); 127 final SSLSocket sslSocket = (SSLSocket) 128 m_factory.createSocket( bareSocket, hostName, port, true ); 129 sslSocket.startHandshake(); 130 final SSLSession session = sslSocket.getSession(); 131 final String DN = 132 session.getPeerCertificateChain()[ 0 ].getSubjectDN().getName(); 133 final String CN = getCN( DN ); 134 if( !hostName.equals( CN ) ) 135 { 136 final String message = "Host name mismatch, expected '" + 137 hostName + "' recevied DN is " + DN; 138 throw new IOException ( message ); 139 } 140 if( getLogger().isDebugEnabled() ) 141 { 142 final String message = "DN of the server " + DN; 143 getLogger().debug( message ); 144 final String message2 = "Session id " + 145 bytesToString( session.getId() ); 146 getLogger().debug( message2 ); 147 } 148 return sslSocket; 149 } 150 151 private StringBuffer bytesToString( byte[] data ) 152 { 153 final StringBuffer result = new StringBuffer ( data.length * 3 ); 154 String sep = ""; 155 for( int i = 0; i < data.length; i++ ) 156 { 157 final byte signedValue = data[ i ]; 158 final int unsignedByteValue = 159 ( signedValue >= 0 ) ? signedValue : 256 + signedValue; 160 result.append( sep ) 161 .append( Integer.toHexString( unsignedByteValue ) ); 162 sep = ":"; 163 } 164 return result; 165 } 166 167 175 private String getCN( String DN ) 176 { 177 final int startOfCN = DN.indexOf( "CN=" ); 178 if( startOfCN < 0 ) 179 { 180 return null; 181 } 182 final int startOfHostName = startOfCN + "CN=".length(); 183 final int endOfHostName = DN.indexOf( ',', startOfHostName ); 184 if( endOfHostName > 0 ) 185 { 186 return DN.substring( startOfHostName, endOfHostName ); 187 } 188 else 189 { 190 return null; 191 } 192 } 193 194 202 public Socket createSocket( InetAddress address, int port ) throws IOException 203 { 204 if( m_verifyServerIdentity ) 208 { 209 return sslWrap( initSocket( new Socket ( address, port ) ), 210 address, port ); 211 } 212 else 213 { 214 return initSocket( m_factory.createSocket( address, port ) ); 215 } 216 } 217 218 229 public Socket createSocket( final InetAddress address, 230 final int port, 231 final InetAddress localAddress, 232 final int localPort ) 233 throws IOException 234 { 235 if( m_verifyServerIdentity ) 239 { 240 return sslWrap( initSocket( new Socket ( address, port, 241 localAddress, 242 localPort ) ), 243 address, port ); 244 } 245 else 246 { 247 return initSocket( m_factory.createSocket( address, port ) ); 248 } 249 } 250 251 } 252 | Popular Tags |