17329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom/* 27329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Licensed to the Apache Software Foundation (ASF) under one or more 37329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * contributor license agreements. See the NOTICE file distributed with 47329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * this work for additional information regarding copyright ownership. 57329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * The ASF licenses this file to You under the Apache License, Version 2.0 67329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * (the "License"); you may not use this file except in compliance with 77329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * the License. You may obtain a copy of the License at 87329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * 97329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * 117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * See the License for the specific language governing permissions and 157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * limitations under the License. 167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrompackage org.apache.harmony.xnet.provider.jsse; 197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.io.IOException; 217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.io.InputStream; 227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.io.OutputStream; 237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.net.InetAddress; 247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.net.SocketAddress; 257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.net.SocketException; 267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.net.UnknownHostException; 277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport java.util.ArrayList; 287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.HandshakeCompletedEvent; 297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.HandshakeCompletedListener; 307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.SSLEngineResult; 317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.SSLException; 327329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.SSLSession; 337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstromimport javax.net.ssl.SSLSocket; 347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom/** 367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * SSLSocket implementation. 377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket class documentation for more information. 387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrompublic class SSLSocketImpl extends SSLSocket { 407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // indicates if handshake has been started 427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private boolean handshake_started = false; 437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 446d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra // used when we're wrapping a socket 456d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra private final String wrappedHost; 466d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra private final int wrappedPort; 476d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra 487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // record protocol to be used 497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected SSLRecordProtocol recordProtocol; 507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // handshake protocol to be used 517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private HandshakeProtocol handshakeProtocol; 527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // alert protocol to be used 537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private AlertProtocol alertProtocol; 547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // application data input stream, this stream is presented by 55608263018762d64a07276b7c8f58102455ccecc8Elliott Hughes // ssl socket as an input stream. Additionally this object is a 567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // place where application data will be stored by record protocol 577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private SSLSocketInputStream appDataIS; 58608263018762d64a07276b7c8f58102455ccecc8Elliott Hughes // outgoing application data stream 597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private SSLSocketOutputStream appDataOS; 607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // active session object 617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private SSLSessionImpl session; 627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private boolean socket_was_closed = false; 647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // the sslParameters object encapsulates all the info 667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // about supported and enabled cipher suites and protocols, 677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // as well as the information about client/server mode of 687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // ssl socket, whether it require/want client authentication or not, 697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // and controls whether new SSL sessions may be established by this 707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // socket or not. 716812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLParametersImpl sslParameters; 727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // super's streams to be wrapped: 737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected InputStream input; 747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected OutputStream output; 757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // handshake complete listeners 767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private ArrayList<HandshakeCompletedListener> listeners; 777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // logger 787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private Logger.Stream logger = Logger.getStream("socket"); 797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // ----------------- Constructors and initializers -------------------- 817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Constructor 846812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom * @param sslParameters: SSLParametersImpl 857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#SSLSocket() method documentation 867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * for more information. 877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 886812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLSocketImpl(SSLParametersImpl sslParameters) { 897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom this.sslParameters = sslParameters; 906d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedHost = null; 916d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedPort = -1; 927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // init should be called after creation! 937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Constructor 977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param host: String 987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param port: int 996812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom * @param sslParameters: SSLParametersImpl 1007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws IOException 1017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws UnknownHostException 1027365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson * @see javax.net.ssl.SSLSocket#SSLSocket(String,int) 1037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information. 1047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1056812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLSocketImpl(String host, int port, SSLParametersImpl sslParameters) 1067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throws IOException, UnknownHostException { 1077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super(host, port); 1086d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedHost = host; 1096d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedPort = port; 1107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom this.sslParameters = sslParameters; 1117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 1127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 1157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Constructor 1167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param host: String 1177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param port: int 1187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param localHost: InetAddress 1197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param localPort: int 1206812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom * @param sslParameters: SSLParametersImpl 1217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws IOException 1227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws UnknownHostException 1237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#SSLSocket(String,int,InetAddress,int) 1247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information. 1257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected SSLSocketImpl(String host, int port, 1277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom InetAddress localHost, int localPort, 1286812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom SSLParametersImpl sslParameters) throws IOException, 1297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom UnknownHostException { 1307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super(host, port, localHost, localPort); 1316d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedHost = host; 1326d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedPort = port; 1337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom this.sslParameters = sslParameters; 1347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 1357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 1387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Constructor 1397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param host: InetAddress 1407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param port: int 1416812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom * @param sslParameters: SSLParametersImpl 1427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @return 1437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws IOException 1447365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int) 1457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information. 1467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected SSLSocketImpl(InetAddress host, int port, 1486812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom SSLParametersImpl sslParameters) throws IOException { 1497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super(host, port); 1507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom this.sslParameters = sslParameters; 1516d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedHost = null; 1526d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedPort = -1; 1537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 1547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 1577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Constructor 1587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param address: InetAddress 1597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param port: int 1607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param localAddress: InetAddress 1617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @param localPort: int 1626812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom * @param sslParameters: SSLParametersImpl 1637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @return 1647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws IOException 1657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#SSLSocket(InetAddress,int,InetAddress,int) 1667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information. 1677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected SSLSocketImpl(InetAddress address, int port, 1697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom InetAddress localAddress, int localPort, 1706812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom SSLParametersImpl sslParameters) throws IOException { 1717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super(address, port, localAddress, localPort); 1727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom this.sslParameters = sslParameters; 1736d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedHost = null; 1746d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra this.wrappedPort = -1; 1757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 1767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 1797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Initialize the SSL socket. 1807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected void init() throws IOException { 1827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (appDataIS != null) { 1837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // already initialized 1847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 1857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom initTransportLayer(); 1877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS = new SSLSocketInputStream(this); 1887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataOS = new SSLSocketOutputStream(this); 1897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 1927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Initialize the transport data streams. 1937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 1947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected void initTransportLayer() throws IOException { 1957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom input = super.getInputStream(); 1967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output = super.getOutputStream(); 1977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 1987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 1997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Closes the transport data streams. 2017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected void closeTransportLayer() throws IOException { 2037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super.close(); 2047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (input != null) { 2057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom input.close(); 2067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.close(); 2077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2106d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra String getWrappedHostName() { 2116d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return wrappedHost; 2126d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2136d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra 2146d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra int getWrappedPort() { 2156d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return wrappedPort; 2166d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2176d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra 2186d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra String getPeerHostName() { 2196d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra if (wrappedHost != null) { 2206d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return wrappedHost; 2216d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2226d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra InetAddress inetAddress = super.getInetAddress(); 2236d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra if (inetAddress != null) { 2246d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return inetAddress.getHostName(); 2256d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2266d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return null; 2276d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2286d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra 2296d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra int getPeerPort() { 2306d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra return (wrappedPort == -1) ? super.getPort() : wrappedPort; 2316d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra } 2326d2a17ab04ab0967e3bff7fe6280066ef66d1d76Geremy Condra 2337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // --------------- SSLParameters based methods --------------------- 2347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getSupportedCipherSuites() 2387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public String[] getSupportedCipherSuites() { 2427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return CipherSuite.getSupportedCipherSuiteNames(); 2437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getEnabledCipherSuites() 2487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public String[] getEnabledCipherSuites() { 2527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getEnabledCipherSuites(); 2537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setEnabledCipherSuites(String[]) 2587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setEnabledCipherSuites(String[] suites) { 2627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setEnabledCipherSuites(suites); 2637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getSupportedProtocols() 2687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public String[] getSupportedProtocols() { 2727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return ProtocolVersion.supportedProtocols.clone(); 2737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getEnabledProtocols() 2787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public String[] getEnabledProtocols() { 2827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getEnabledProtocols(); 2837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setEnabledProtocols(String[]) 2887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 2907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 2917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setEnabledProtocols(String[] protocols) { 2927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setEnabledProtocols(protocols); 2937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 2947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 2957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 2967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 2977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setUseClientMode(boolean) 2987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 2997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setUseClientMode(boolean mode) { 3027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (handshake_started) { 3037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IllegalArgumentException( 3047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Could not change the mode after the initial handshake has begun."); 3057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setUseClientMode(mode); 3077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getUseClientMode() 3127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public boolean getUseClientMode() { 3167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getUseClientMode(); 3177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setNeedClientAuth(boolean) 3227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setNeedClientAuth(boolean need) { 3267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setNeedClientAuth(need); 3277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getNeedClientAuth() 3327329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public boolean getNeedClientAuth() { 3367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getNeedClientAuth(); 3377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setWantClientAuth(boolean) 3427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setWantClientAuth(boolean want) { 3467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setWantClientAuth(want); 3477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getWantClientAuth() 3527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public boolean getWantClientAuth() { 3567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getWantClientAuth(); 3577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#setEnableSessionCreation(boolean) 3627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setEnableSessionCreation(boolean flag) { 3667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom sslParameters.setEnableSessionCreation(flag); 3677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getEnableSessionCreation() 3727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public boolean getEnableSessionCreation() { 3767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return sslParameters.getEnableSessionCreation(); 3777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // ----------------------------------------------------------------- 3807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 3817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 3827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 3837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getSession() 3847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 3857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 3867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 3877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public SSLSession getSession() { 3887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!handshake_started) { 3897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 3907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom startHandshake(); 3917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (IOException e) { 3927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // return an invalid session with 3937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // invalid cipher suite of "SSL_NULL_WITH_NULL_NULL" 3947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return SSLSessionImpl.NULL_SESSION; 3957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return session; 3987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 3997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 4017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 4027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#addHandshakeCompletedListener(HandshakeCompletedListener) 4037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 4047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 4057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 4067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void addHandshakeCompletedListener( 4077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom HandshakeCompletedListener listener) { 4087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (listener == null) { 4097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IllegalArgumentException("Provided listener is null"); 4107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (listeners == null) { 4127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom listeners = new ArrayList<HandshakeCompletedListener>(); 4137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom listeners.add(listener); 4157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 4187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 4197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#removeHandshakeCompletedListener(HandshakeCompletedListener) 4207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 4217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 4227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 4237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void removeHandshakeCompletedListener( 4247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom HandshakeCompletedListener listener) { 4257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (listener == null) { 4267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IllegalArgumentException("Provided listener is null"); 4277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (listeners == null) { 4297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IllegalArgumentException( 4307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Provided listener is not registered"); 4317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4327329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!listeners.remove(listener)) { 4337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IllegalArgumentException( 4347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Provided listener is not registered"); 4357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 4397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Performs the handshake process over the SSL/TLS connection 4407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * as described in rfc 2246, TLS v1 specification 4417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * http://www.ietf.org/rfc/rfc2246.txt. If the initial handshake 4427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * has been already done, this method initiates rehandshake. 4437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 4447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#startHandshake() 4457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 4467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 4477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 4487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void startHandshake() throws IOException { 4497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (appDataIS == null) { 4507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IOException("Socket is not connected."); 4517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 4537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IOException("Socket has already been closed."); 4547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!handshake_started) { 4577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshake_started = true; 4587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (sslParameters.getUseClientMode()) { 4597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 4607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocketImpl: CLIENT"); 4617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshakeProtocol = new ClientHandshakeImpl(this); 4637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } else { 4647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 4657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocketImpl: SERVER"); 4667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshakeProtocol = new ServerHandshakeImpl(this); 4687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol = new AlertProtocol(); 4717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom recordProtocol = new SSLRecordProtocol(handshakeProtocol, 4727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol, new SSLStreamedInput(input), 4737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS.dataPoint); 4747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 4777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocketImpl.startHandshake"); 4787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshakeProtocol.start(); 4817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom doHandshake(); 4837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 4857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocketImpl.startHandshake: END"); 4867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 4897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 4907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 4917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getInputStream() 4927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 4937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 4947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 4957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public InputStream getInputStream() throws IOException { 4967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 4977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IOException("Socket has already been closed."); 4987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 4997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return appDataIS; 5007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 5047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#getOutputStream() 5057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 5067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public OutputStream getOutputStream() throws IOException { 5097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 5107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IOException("Socket has already been closed."); 5117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return appDataOS; 5137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 5177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see java.net.Socket#connect(SocketAddress) 5187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 5197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void connect(SocketAddress endpoint) throws IOException { 5227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super.connect(endpoint); 5237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 5247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5257365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson 5267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 5287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see java.net.Socket#connect(SocketAddress,int) 5297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 5307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5327365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson public void connect(SocketAddress endpoint, int timeout) 5337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throws IOException { 5347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom super.connect(endpoint, timeout); 5357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom init(); 5367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5377365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson 5387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method works according to the specification of implemented class. 5407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @see javax.net.ssl.SSLSocket#close() 5417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * method documentation for more information 5427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void close() throws IOException { 5457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 5467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocket.close "+socket_was_closed); 5477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!socket_was_closed) { 5497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (handshake_started) { 5507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.alert(AlertProtocol.WARNING, 5517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom AlertProtocol.CLOSE_NOTIFY); 5527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 5537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(alertProtocol.wrap()); 5547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (IOException ex) { } 5557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 5567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom shutdown(); 5587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom closeTransportLayer(); 5597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom socket_was_closed = true; 5607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method is not supported for SSLSocket implementation. 5657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void sendUrgentData(int data) throws IOException { 5687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new SocketException( 5697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Method sendUrgentData() is not supported."); 5707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method is not supported for SSLSocket implementation. 5747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 5757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom @Override 5767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom public void setOOBInline(boolean on) throws SocketException { 5777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new SocketException( 5787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Methods sendUrgentData, setOOBInline are not supported."); 5797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // ----------------------------------------------------------------- 5827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private void shutdown() { 5847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (handshake_started) { 5857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.shutdown(); 5867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol = null; 5877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshakeProtocol.shutdown(); 5887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom handshakeProtocol = null; 5897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom recordProtocol.shutdown(); 5907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom recordProtocol = null; 5917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom socket_was_closed = true; 5937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 5947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 5957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 5967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * This method is called by SSLSocketInputStream class 597ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes * when client application tries to read application data from 5987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * the stream, but there is no data in its underlying buffer. 5997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * @throws IOException 6007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 6017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom protected void needAppData() throws IOException { 6027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!handshake_started) { 6037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom startHandshake(); 6047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom int type; 6067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 6077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocket.needAppData.."); 6087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 6107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom while(appDataIS.available() == 0) { 6117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // read and unwrap the record contained in the transport 6127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // input stream (SSLStreamedInput), pass it 6137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // to appropriate client protocol (alert, handshake, or app) 6147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // and retrieve the type of unwrapped data 6157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom switch (type = recordProtocol.unwrap()) { 6167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.HANDSHAKE: 6177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!handshakeProtocol.getStatus().equals( 6187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus 6197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom .NOT_HANDSHAKING)) { 6207365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson // handshake protocol got addressed to it message 6217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // and did not ignore it, so it's a rehandshake 6227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom doHandshake(); 6237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 6257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.ALERT: 6267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom processAlert(); 6277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 6287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 6297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 6317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.APPLICATION_DATA: 6327329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 6337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println( 6347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "SSLSocket.needAppData: got the data"); 6357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 6377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom default: 6387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 6397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, 6407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom new SSLException("Unexpected message of type " 6417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom + type + " has been got")); 6427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (alertProtocol.hasAlert()) { 644ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes // warning alert occurred during wrap or unwrap 6457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // (note: fatal alert causes AlertException 6467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // to be thrown) 6477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(alertProtocol.wrap()); 6487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 6497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 6517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS.setEnd(); 6527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 6537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (AlertException e) { 6567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 6577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(e.getDescriptionCode(), e.getReason()); 6587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (EndOfSourceException e) { 6597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // end of socket's input stream has been reached 6607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS.setEnd(); 6617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 6637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocket.needAppData: app data len: " 6647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom + appDataIS.available()); 6657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 6687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /** 669ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes * This method is called by SSLSocketOutputStream when a client application 670ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes * tries to send the data over ssl protocol. 6717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 672608263018762d64a07276b7c8f58102455ccecc8Elliott Hughes protected void writeAppData(byte[] data, int offset, int len) throws IOException { 6737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!handshake_started) { 6747329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom startHandshake(); 6757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 6777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocket.writeAppData: " + 6787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom len + " " + SSLRecordProtocol.MAX_DATA_LENGTH); 6797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom //logger.println(new String(data, offset, len)); 6807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 6827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (len < SSLRecordProtocol.MAX_DATA_LENGTH) { 6837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(recordProtocol.wrap(ContentType.APPLICATION_DATA, 6847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom data, offset, len)); 6857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } else { 6867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom while (len >= SSLRecordProtocol.MAX_DATA_LENGTH) { 6877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(recordProtocol.wrap( 6887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom ContentType.APPLICATION_DATA, data, offset, 6897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLRecordProtocol.MAX_DATA_LENGTH)); 6907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom offset += SSLRecordProtocol.MAX_DATA_LENGTH; 6917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom len -= SSLRecordProtocol.MAX_DATA_LENGTH; 6927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (len > 0) { 6947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write( 6957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom recordProtocol.wrap(ContentType.APPLICATION_DATA, 6967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom data, offset, len)); 6977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 6997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (AlertException e) { 7007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 7017329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(e.getDescriptionCode(), e.getReason()); 7027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 7057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /* 706608263018762d64a07276b7c8f58102455ccecc8Elliott Hughes * Performs handshake process over this connection. The handshake 707d6e53e42867824f97c9fb9c427cc188897ea9315Brian Carlstrom * process is directed by the handshake status code provided by 7087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * handshake protocol. If this status is NEED_WRAP, method retrieves 7097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * handshake message from handshake protocol and sends it to another peer. 7107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * If this status is NEED_UNWRAP, method receives and processes handshake 7117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * message from another peer. Each of this stages (wrap/unwrap) change 7127365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson * the state of handshake protocol and this process is performed 713608263018762d64a07276b7c8f58102455ccecc8Elliott Hughes * until handshake status is FINISHED. After handshake process is finished 7147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * handshake completed event are sent to the registered listeners. 7157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * For more information about the handshake process see 7167329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * TLS v1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 7.3. 7177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 7187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private void doHandshake() throws IOException { 7197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus status; 7207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom int type; 7217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 7227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom while (!(status = handshakeProtocol.getStatus()).equals( 7237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus.FINISHED)) { 7247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 7257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom String s = (status.equals( 7267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus.NEED_WRAP)) 7277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom ? "NEED_WRAP" 7287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom : (status.equals( 7297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) 7307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom ? "NEED_UNWRAP" 7317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom : "STATUS: OTHER!"; 7327329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("SSLSocketImpl: HS status: "+s+" "+status); 7337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (status.equals(SSLEngineResult.HandshakeStatus.NEED_WRAP)) { 7357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(handshakeProtocol.wrap()); 7367329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } else if (status.equals( 7377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) { 7387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // read and unwrap the record contained in the transport 7397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // input stream (SSLStreamedInput), pass it 7407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // to appropriate client protocol (alert, handshake, or app) 7417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // and retrieve the type of unwrapped data 7427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom switch (type = recordProtocol.unwrap()) { 7437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.HANDSHAKE: 7447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.CHANGE_CIPHER_SPEC: 7457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 7467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.APPLICATION_DATA: 7477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // So it's rehandshake and 7487329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // if app data buffer will be overloaded 7497329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // it will throw alert exception. 7507329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // Probably we should count the number of 7517329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // not handshaking data and make additional 7527329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // constraints (do not expect buffer overflow). 7537329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 7547329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case ContentType.ALERT: 7557329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom processAlert(); 7567329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (socket_was_closed) { 7577329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 7587329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7597329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom break; 7607329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom default: 7617329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 7627329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(AlertProtocol.UNEXPECTED_MESSAGE, 7637329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom new SSLException( 7647329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Unexpected message of type " 7657329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom + type + " has been got")); 7667329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7677329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } else { 7687329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 7697329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(AlertProtocol.INTERNAL_ERROR, 7707329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom new SSLException( 7717329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom "Handshake passed unexpected status: "+status)); 7727329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7737329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (alertProtocol.hasAlert()) { 774ff8234c90ecab9f1db368924bf92a5b16460f9b5Elliott Hughes // warning alert occurred during wrap or unwrap 7757329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // (note: fatal alert causes AlertException 7767329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // to be thrown) 7777329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(alertProtocol.wrap()); 7787329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 7797329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7807329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7817329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (EndOfSourceException e) { 7827329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS.setEnd(); 7837329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new IOException("Connection was closed"); 7847329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (AlertException e) { 7857329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // will throw exception 7867329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom reportFatalAlert(e.getDescriptionCode(), e.getReason()); 7877329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7887329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom 7897329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom session = recordProtocol.getSession(); 7907329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (listeners != null) { 7917329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // notify the listeners 7927329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom HandshakeCompletedEvent event = 7937329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom new HandshakeCompletedEvent(this, session); 7947329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom int size = listeners.size(); 7957329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom for (int i=0; i<size; i++) { 7967329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom listeners.get(i) 7977329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom .handshakeCompleted(event); 7987329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 7997329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8007329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8017365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson 8027329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /* 8037329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Process received alert message 8047329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 8057329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom private void processAlert() throws IOException { 8067329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (!alertProtocol.hasAlert()) { 8077329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 8087329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8097329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (alertProtocol.isFatalAlert()) { 8107329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 8117329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom String description = "Fatal alert received " 8127329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom + alertProtocol.getAlertDescription(); 8137329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom shutdown(); 8147329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw new SSLException(description); 8157329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8167365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson 8177329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom if (logger != null) { 8187329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom logger.println("Warning alert received: " 8197329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom + alertProtocol.getAlertDescription()); 8207329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8217329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom switch(alertProtocol.getDescriptionCode()) { 8227329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom case AlertProtocol.CLOSE_NOTIFY: 8237329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 8247329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom appDataIS.setEnd(); 8257329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom close(); 8267329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom return; 8277329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom default: 8287329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 8297329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // TODO: process other warning messages 8307329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8317329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8327365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson 8337329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom /* 8347329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom * Sends fatal alert message and throws exception 8357329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom */ 8367365de1056414750d0a7d1fdd26025fd247f0d04Jesse Wilson private void reportFatalAlert(byte description_code, 8377329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom SSLException reason) throws IOException { 8387329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.alert(AlertProtocol.FATAL, description_code); 8397329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom try { 8407329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom // the output stream can be closed 8417329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom output.write(alertProtocol.wrap()); 8427329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } catch (IOException ex) { } 8437329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom alertProtocol.setProcessed(); 8447329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom shutdown(); 8457329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom throw reason; 8467329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom } 8477329fa972d9c20777444e5e1b13169d700de6567Brian Carlstrom} 848