1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.xnet.provider.jsse; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.BufferUnderflowException; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ReadOnlyBufferException; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLEngine; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLEngineResult; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLException; 280c131a2ca38465b7d1df4eaee63ac73ce4d5986dBrian Carlstromimport javax.net.ssl.SSLHandshakeException; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport javax.net.ssl.SSLSession; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implementation of SSLEngine. 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine class documentation for more information. 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class SSLEngineImpl extends SSLEngine { 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if peer mode was set 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean peer_mode_was_set = false; 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if handshake has been started 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean handshake_started = false; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if inbound operations finished 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isInboundDone = false; 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if outbound operations finished 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isOutboundDone = false; 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if close_notify alert had been sent to another peer 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean close_notify_was_sent = false; 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if close_notify alert had been received from another peer 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean close_notify_was_received = false; 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if engine was closed (it means that 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all the works on it are done, except (probably) some finalizing work) 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean engine_was_closed = false; 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // indicates if engine was shutted down (it means that 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // all cleaning work had been done and the engine is not operable) 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean engine_was_shutteddown = false; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // record protocol to be used 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected SSLRecordProtocol recordProtocol; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // input stream for record protocol 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLBufferedInput recProtIS; 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // handshake protocol to be used 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private HandshakeProtocol handshakeProtocol; 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // alert protocol to be used 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AlertProtocol alertProtocol; 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // place where application data will be stored 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLEngineAppData appData; 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // outcoming application data stream 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLEngineDataStream dataStream = new SSLEngineDataStream(); 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // active session object 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLSessionImpl session; 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // peer configuration parameters 726812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLParametersImpl sslParameters; 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // in case of emergency situations when data could not be 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // placed in destination buffers it will be stored in this 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // fields 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] remaining_wrapped_data = null; 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private byte[] remaining_hsh_data = null; 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // logger 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Logger.Stream logger = Logger.getStream("engine"); 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 836812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLEngineImpl(SSLParametersImpl sslParameters) { 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.sslParameters = sslParameters; 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 876812a2e8bb43d9a875633a9ba255d9882c63e327Brian Carlstrom protected SSLEngineImpl(String host, int port, SSLParametersImpl sslParameters) { 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(host, port); 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.sslParameters = sslParameters; 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Starts the handshake. 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SSLException 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#beginHandshake() method documentation 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for more information 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 98f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void beginHandshake() throws SSLException { 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (engine_was_closed) { 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SSLException("Engine has already been closed."); 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!peer_mode_was_set) { 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException("Client/Server mode was not set"); 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshake_started) { 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshake_started = true; 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (getUseClientMode()) { 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol = new ClientHandshakeImpl(this); 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol = new ServerHandshakeImpl(this); 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project appData = new SSLEngineAppData(); 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol = new AlertProtocol(); 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recProtIS = new SSLBufferedInput(); 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recordProtocol = new SSLRecordProtocol(handshakeProtocol, 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol, recProtIS, appData); 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol.start(); 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes inbound operations of this engine 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SSLException 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#closeInbound() method documentation 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for more information 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 128f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void closeInbound() throws SSLException { 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (logger != null) { 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.println("closeInbound() "+isInboundDone); 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isInboundDone) { 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isInboundDone = true; 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshake_started) { 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!close_notify_was_received) { 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session.invalidate(); 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.alert(AlertProtocol.FATAL, 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AlertProtocol.INTERNAL_ERROR); 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SSLException("Inbound is closed before close_notify " 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + "alert has been received."); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engine is closing before initial handshake has been made 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Closes outbound operations of this engine 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#closeOutbound() method documentation 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for more information 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 159f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void closeOutbound() { 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (logger != null) { 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.println("closeOutbound() "+isOutboundDone); 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isOutboundDone) { 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isOutboundDone = true; 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshake_started) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // initial handshake had been started 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.alert(AlertProtocol.WARNING, 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AlertProtocol.CLOSE_NOTIFY); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project close_notify_was_sent = true; 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // engine is closing before initial handshake has been made 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns handshake's delegated tasks to be run 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the delegated task to be executed. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getDelegatedTask() method documentation 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * for more information 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 186f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Runnable getDelegatedTask() { 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return handshakeProtocol.getTask(); 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns names of supported cipher suites. 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return array of strings containing the names of supported cipher suites 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getSupportedCipherSuites() method 195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 197f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedCipherSuites() { 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return CipherSuite.getSupportedCipherSuiteNames(); 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // --------------- SSLParameters based methods --------------------- 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getEnabledCipherSuites() method 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 209f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledCipherSuites() { 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnabledCipherSuites(); 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setEnabledCipherSuites(String[]) method 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 219f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnabledCipherSuites(String[] suites) { 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnabledCipherSuites(suites); 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getSupportedProtocols() method 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getSupportedProtocols() { 231f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson return ProtocolVersion.supportedProtocols.clone(); 232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getEnabledProtocols() method 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 239f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] getEnabledProtocols() { 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnabledProtocols(); 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setEnabledProtocols(String[]) method 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 249f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnabledProtocols(String[] protocols) { 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnabledProtocols(protocols); 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setUseClientMode(boolean) method 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setUseClientMode(boolean mode) { 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshake_started) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException( 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Could not change the mode after the initial handshake has begun."); 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setUseClientMode(mode); 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project peer_mode_was_set = true; 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getUseClientMode() method 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 274f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getUseClientMode() { 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getUseClientMode(); 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setNeedClientAuth(boolean) method 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 284f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setNeedClientAuth(boolean need) { 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setNeedClientAuth(need); 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getNeedClientAuth() method 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 294f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getNeedClientAuth() { 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getNeedClientAuth(); 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setWantClientAuth(boolean) method 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 304f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setWantClientAuth(boolean want) { 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setWantClientAuth(want); 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getWantClientAuth() method 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 314f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getWantClientAuth() { 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getWantClientAuth(); 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#setEnableSessionCreation(boolean) method 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 324f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void setEnableSessionCreation(boolean flag) { 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sslParameters.setEnableSessionCreation(flag); 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getEnableSessionCreation() method 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 334f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getEnableSessionCreation() { 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return sslParameters.getEnableSessionCreation(); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ----------------------------------------------------------------- 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getHandshakeStatus() method 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 346f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLEngineResult.HandshakeStatus getHandshakeStatus() { 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshake_started || engine_was_shutteddown) { 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // initial handshake has not been started yet 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING; 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (alertProtocol.hasAlert()) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // need to send an alert 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLEngineResult.HandshakeStatus.NEED_WRAP; 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (close_notify_was_sent && !close_notify_was_received) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // waiting for "close_notify" response 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SSLEngineResult.HandshakeStatus.NEED_UNWRAP; 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return handshakeProtocol.getStatus(); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#getSession() method 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 368f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLSession getSession() { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return session; 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson return SSLSessionImpl.NULL_SESSION; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#isInboundDone() method 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 381f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isInboundDone() { 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isInboundDone || engine_was_closed; 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This method works according to the specification of implemented class. 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#isOutboundDone() method 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 391f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isOutboundDone() { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isOutboundDone; 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Decodes one complete SSL/TLS record provided in the source buffer. 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If decoded record contained application data, this data will 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * be placed in the destination buffers. 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For more information about TLS record fragmentation see 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2. 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param src source buffer containing SSL/TLS record. 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dsts destination buffers to place received application data. 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#unwrap(ByteBuffer,ByteBuffer[],int,int) 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method documentation for more information 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 407f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int offset, int length) throws SSLException { 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (engine_was_shutteddown) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(SSLEngineResult.Status.CLOSED, 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0); 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((src == null) || (dsts == null)) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException( 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Some of the input parameters are null"); 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshake_started) { 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project beginHandshake(); 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus(); 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If is is initial handshake or connection closure stage, 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check if this call was made in spite of handshake status 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((session == null || engine_was_closed) && ( 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus.equals( 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NEED_WRAP) || 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus.equals( 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NEED_TASK))) { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getEngineStatus(), handshakeStatus, 0, 0); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (src.remaining() < recordProtocol.getMinRecordSize()) { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_UNDERFLOW, 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getHandshakeStatus(), 0, 0); 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project src.mark(); 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check the destination buffers and count their capacity 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int capacity = 0; 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i=offset; i<offset+length; i++) { 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (dsts[i] == null) { 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException( 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Some of the input parameters are null"); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (dsts[i].isReadOnly()) { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ReadOnlyBufferException(); 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project capacity += dsts[i].remaining(); 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (capacity < recordProtocol.getDataSize(src.remaining())) { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_OVERFLOW, 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getHandshakeStatus(), 0, 0); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recProtIS.setSourceBuffer(src); 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // unwrap the record contained in source buffer, pass it 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to appropriate client protocol (alert, handshake, or app) 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // and retrieve the type of unwrapped data 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int type = recordProtocol.unwrap(); 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // process the data and return the result 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch (type) { 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case ContentType.HANDSHAKE: 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case ContentType.CHANGE_CIPHER_SPEC: 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeProtocol.getStatus().equals( 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.FINISHED)) { 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session = recordProtocol.getSession(); 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case ContentType.APPLICATION_DATA: 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case ContentType.ALERT: 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (alertProtocol.isFatalAlert()) { 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session.invalidate(); 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String description = "Fatal alert received " 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + alertProtocol.getAlertDescription(); 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SSLException(description); 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (logger != null) { 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.println("Warning allert has been received: " 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + alertProtocol.getAlertDescription()); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project switch(alertProtocol.getDescriptionCode()) { 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case AlertProtocol.CLOSE_NOTIFY: 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project close_notify_was_received = true; 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!close_notify_was_sent) { 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project closeOutbound(); 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project closeInbound(); 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project closeInbound(); 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project case AlertProtocol.NO_RENEGOTIATION: 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session == null) { 506f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // message received during the initial 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // handshake 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AlertException( 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AlertProtocol.HANDSHAKE_FAILURE, 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project new SSLHandshakeException( 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Received no_renegotiation " 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + "during the initial handshake")); 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // just stop the handshake 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol.stop(); 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project default: 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(getEngineStatus(), getHandshakeStatus(), 525f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes recProtIS.consumed(), 526f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes // place the app. data (if any) into the dest. buffers 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // and get the number of produced bytes: 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project appData.placeTo(dsts, offset, length)); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BufferUnderflowException e) { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // there was not enought data ource buffer to make complete packet 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project src.reset(); 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(SSLEngineResult.Status.BUFFER_UNDERFLOW, 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getHandshakeStatus(), 0, 0); 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (AlertException e) { 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // fatal alert occured 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode()); 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project src.reset(); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session.invalidate(); 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // shutdown work will be made after the alert will be sent 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to another peer (by wrap method) 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e.getReason(); 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (SSLException e) { 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e; 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.alert(AlertProtocol.FATAL, 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AlertProtocol.INTERNAL_ERROR); 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // shutdown work will be made after the alert will be sent 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to another peer (by wrap method) 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new SSLException(e.getMessage()); 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Encodes the application data into SSL/TLS record. If handshake status 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the engine differs from NOT_HANDSHAKING the operation can work 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * without consuming of the source data. 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * For more information about TLS record fragmentation see 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TLS v 1 specification (http://www.ietf.org/rfc/rfc2246.txt) p 6.2. 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param srcs the source buffers with application data to be encoded 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * into SSL/TLS record. 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param offset the offset in the destination buffers array pointing to 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the first buffer with the source data. 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param len specifies the maximum number of buffers to be procesed. 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dst the destination buffer where encoded data will be placed. 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see javax.net.ssl.SSLEngine#wrap(ByteBuffer[],int,int,ByteBuffer) method 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * documentation for more information 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 572f921579f87fa63204b4a4bef39ed27e7835aec45Jesse Wilson @Override 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public SSLEngineResult wrap(ByteBuffer[] srcs, int offset, 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int len, ByteBuffer dst) throws SSLException { 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (engine_was_shutteddown) { 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(SSLEngineResult.Status.CLOSED, 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 0, 0); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((srcs == null) || (dst == null)) { 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalStateException( 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project "Some of the input parameters are null"); 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (dst.isReadOnly()) { 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new ReadOnlyBufferException(); 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshake_started) { 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project beginHandshake(); 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus handshakeStatus = getHandshakeStatus(); 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If it is an initial handshake or connection closure stage, 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check if this call was made in spite of handshake status 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((session == null || engine_was_closed) && ( 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus.equals( 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NEED_UNWRAP) || 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus.equals( 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NEED_TASK))) { 599adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getEngineStatus(), handshakeStatus, 0, 0); 601adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int capacity = dst.remaining(); 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int produced = 0; 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (alertProtocol.hasAlert()) { 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // we have an alert to be sent 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (capacity < recordProtocol.getRecordSize(2)) { 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_OVERFLOW, 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, 0, 0); 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] alert_data = alertProtocol.wrap(); 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // place the alert record into destination 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dst.put(alert_data); 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (alertProtocol.isFatalAlert()) { 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session.invalidate(); 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // fatal alert has been sent, so shut down the engine 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.CLOSED, 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 0, alert_data.length); 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.setProcessed(); 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check if the works on this engine have been done 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (close_notify_was_sent && close_notify_was_received) { 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project shutdown(); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(SSLEngineResult.Status.CLOSED, 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 0, alert_data.length); 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getEngineStatus(), 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getHandshakeStatus(), 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 0, alert_data.length); 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 643adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (capacity < recordProtocol.getMinRecordSize()) { 644adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (logger != null) { 645adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.println("Capacity of the destination(" 646adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project +capacity+") < MIN_PACKET_SIZE(" 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project +recordProtocol.getMinRecordSize()+")"); 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult(SSLEngineResult.Status.BUFFER_OVERFLOW, 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, 0, 0); 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!handshakeStatus.equals( 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.NEED_WRAP)) { 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // so we wraps application data 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dataStream.setSourceBuffers(srcs, offset, len); 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((capacity < SSLRecordProtocol.MAX_SSL_PACKET_SIZE) && 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project (capacity < recordProtocol.getRecordSize( 660adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dataStream.available()))) { 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (logger != null) { 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project logger.println("The destination buffer(" 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project +capacity+") can not take the resulting packet(" 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project + recordProtocol.getRecordSize( 665adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dataStream.available())+")"); 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_OVERFLOW, 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, 0, 0); 670adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (remaining_wrapped_data == null) { 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remaining_wrapped_data = 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recordProtocol.wrap(ContentType.APPLICATION_DATA, 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dataStream); 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (capacity < remaining_wrapped_data.length) { 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // It should newer happen because we checked the destination 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // buffer size, but there is a possibility 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (if dest buffer was filled outside) 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // so we just remember the data into remaining_wrapped_data 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // and will enclose it during the the next call 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_OVERFLOW, 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, dataStream.consumed(), 0); 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dst.put(remaining_wrapped_data); 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project produced = remaining_wrapped_data.length; 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remaining_wrapped_data = null; 689f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return new SSLEngineResult(getEngineStatus(), 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, dataStream.consumed(), produced); 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (remaining_hsh_data == null) { 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remaining_hsh_data = handshakeProtocol.wrap(); 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (capacity < remaining_hsh_data.length) { 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // It should newer happen because we checked the destination 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // buffer size, but there is a possibility 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (if dest buffer was filled outside) 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // so we just remember the data into remaining_hsh_data 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // and will enclose it during the the next call 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.Status.BUFFER_OVERFLOW, 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus, 0, 0); 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dst.put(remaining_hsh_data); 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project produced = remaining_hsh_data.length; 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project remaining_hsh_data = null; 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeStatus = handshakeProtocol.getStatus(); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshakeStatus.equals( 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SSLEngineResult.HandshakeStatus.FINISHED)) { 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session = recordProtocol.getSession(); 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new SSLEngineResult( 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getEngineStatus(), getHandshakeStatus(), 0, produced); 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (AlertException e) { 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // fatal alert occured 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.alert(AlertProtocol.FATAL, e.getDescriptionCode()); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (session != null) { 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project session.invalidate(); 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // shutdown work will be made after the alert will be sent 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // to another peer (by wrap method) 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw e.getReason(); 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Shutdownes the engine and makes all cleanup work. 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void shutdown() { 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_closed = true; 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project engine_was_shutteddown = true; 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isOutboundDone = true; 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isInboundDone = true; 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (handshake_started) { 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol.shutdown(); 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project alertProtocol = null; 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol.shutdown(); 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project handshakeProtocol = null; 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recordProtocol.shutdown(); 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project recordProtocol = null; 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private SSLEngineResult.Status getEngineStatus() { 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (engine_was_closed) 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ? SSLEngineResult.Status.CLOSED 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project : SSLEngineResult.Status.OK; 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 755