1561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/*
2561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Licensed to the Apache Software Foundation (ASF) under one or more
3561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  contributor license agreements.  See the NOTICE file distributed with
4561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  this work for additional information regarding copyright ownership.
5561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  The ASF licenses this file to You under the Apache License, Version 2.0
6561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  (the "License"); you may not use this file except in compliance with
7561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  the License.  You may obtain a copy of the License at
8561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
9561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
10561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
11561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Unless required by applicable law or agreed to in writing, software
12561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  distributed under the License is distributed on an "AS IS" BASIS,
13561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  See the License for the specific language governing permissions and
15561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  limitations under the License.
16561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
17561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
18561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespackage org.apache.harmony.xnet.provider.jsse;
19561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
20561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.nio.ByteBuffer;
21561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.util.Arrays;
22561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLEngine;
23561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLEngineResult;
24561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLException;
25561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport javax.net.ssl.SSLSession;
26561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
27561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.Test;
28561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.TestCase;
29561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport junit.framework.TestSuite;
30561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
31561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/**
32561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes * SSLEngine implementation test.
33561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
34561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespublic class SSLEngineImplTest extends TestCase {
35561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
36561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
37561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The cipher suites used for functionality testing.
38561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
39561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static final String[] cipher_suites = {
40561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        "RSA_WITH_RC4_128_MD5",
41561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        "RSA_WITH_DES_CBC_SHA",
42561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        "DH_anon_EXPORT_WITH_DES40_CBC_SHA"
43561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    };
44561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
45561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
46561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Test logging switch.
47561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
48561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static boolean doLog = false;
49561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
50561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
51561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Sets up the test case.
52561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
53561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    @Override
54561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void setUp() throws Exception {
55561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
56561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("");
57561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("========================");
58561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("====== Running the test: " + getName());
59561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("========================");
60561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
61561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
62561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
63561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
64561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the interaction between the engines.
65561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
66561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSelfInteraction() throws Exception {
67561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] protocols = {"SSLv3", "TLSv1"};
68561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<cipher_suites.length; i++) {
69561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            for (int j=0; j<2; j++) {
70561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
71561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("\n===== Interact over suite: "
72561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + cipher_suites[i]);
73561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
74561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngine client = getEngine();
75561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngine server = getEngine();
76561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                initEngines(client, server);
77561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
78561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doHandshake(client, server);
79561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doDataExchange(client, server);
80561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                doClose(client, server);
81561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
82561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
83561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
84561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
85561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
86561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the session negotiation process.
87561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
88561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testHandshake() throws Exception {
89561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine client = getEngine();
90561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine server = getEngine();
91561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
92561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        initEngines(client, server);
93561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
94561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // checks the impossibility of initial handshake
95561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // with the server not allowed to session creation
96561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doNoRenegotiationTest(client, server, true);
97561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
98561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client = getEngine();
99561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server = getEngine();
100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        initEngines(client, server);
101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setUseClientMode(true);
103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setUseClientMode(false);
104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // do initial handshake
106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshake(client, server);
107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // client initiates rehandshake
109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.beginHandshake();
110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshakeImpl(client, server);
111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // server initiates rehandshake
113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.beginHandshake();
114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshakeImpl(client, server);
115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // client initiates rehandshake while server invalidates
117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // used session
118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.getSession().invalidate();
119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.beginHandshake();
120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshakeImpl(client, server);
121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // server initiates rehandshake while client invalidates
123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // used session
124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.getSession().invalidate();
125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.beginHandshake();
126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshakeImpl(client, server);
127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.getSession().invalidate();
129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.getSession().invalidate();
130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshake(client, server);
131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doNoRenegotiationTest(client, server, false);
133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doNoRenegotiationTest(server, client, false);
135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doClose(client, server);
137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * setNeedClientAuth(boolean need) method testing.
141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getNeedClientAuth() method testing.
142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetGetNeedClientAuth() throws Exception {
144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setWantClientAuth(true);
147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setNeedClientAuth(false);
148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Result differs from expected",
149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getNeedClientAuth());
150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Socket did not reset its want client auth state",
151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getWantClientAuth());
152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setWantClientAuth(true);
153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setNeedClientAuth(true);
154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Result differs from expected",
155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getNeedClientAuth());
156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Socket did not reset its want client auth state",
157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getWantClientAuth());
158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * setWantClientAuth(boolean want) method testing.
162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getWantClientAuth() method testing.
163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetGetWantClientAuth() throws Exception {
165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setNeedClientAuth(true);
168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setWantClientAuth(false);
169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Result differs from expected",
170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getWantClientAuth());
171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Socket did not reset its want client auth state",
172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getNeedClientAuth());
173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setNeedClientAuth(true);
174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setWantClientAuth(true);
175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Result differs from expected",
176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getWantClientAuth());
177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Socket did not reset its want client auth state",
178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getNeedClientAuth());
179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getSupportedCipherSuites() method testing.
183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetSupportedCipherSuites() throws Exception {
185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] supported = engine.getSupportedCipherSuites();
187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull(supported);
188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        supported[0] = "NOT_SUPPORTED_CIPHER_SUITE";
189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        supported = engine.getEnabledCipherSuites();
190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<supported.length; i++) {
191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if ("NOT_SUPPORTED_CIPHER_SUITE".equals(supported[i])) {
192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Modification of the returned result "
193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "causes the modification of the internal state");
194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getEnabledCipherSuites() method testing.
200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetEnabledCipherSuites() throws Exception {
202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] enabled = engine.getEnabledCipherSuites();
204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull(enabled);
205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] supported = engine.getSupportedCipherSuites();
206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<enabled.length; i++) {
207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            found: {
208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                for (int j=0; j<supported.length; j++) {
209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (enabled[i].equals(supported[j])) {
210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        break found;
211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Enabled suite does not belong to the set "
214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "of supported cipher suites: " + enabled[i]);
215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnabledCipherSuites(supported);
218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<supported.length; i++) {
219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            enabled = new String[supported.length - i];
220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.arraycopy(supported, 0,
221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    enabled, 0, supported.length-i);
222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.setEnabledCipherSuites(enabled);
223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            String[] result = engine.getEnabledCipherSuites();
224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (result.length != enabled.length) {
225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Returned result differs from expected.");
226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            for (int k=0; k<result.length; k++) {
228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                found: {
229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    for (int n=0; n<enabled.length; n++) {
230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (result[k].equals(enabled[n])) {
231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            break found;
232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (result.length != enabled.length) {
235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        fail("Returned result does not correspond "
236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + "to expected.");
237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * setEnabledCipherSuites(String[] suites) method testing.
245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetEnabledCipherSuites() throws Exception {
247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] enabled = engine.getEnabledCipherSuites();
249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull(enabled);
250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] supported = engine.getSupportedCipherSuites();
251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<enabled.length; i++) {
252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            found: {
253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                for (int j=0; j<supported.length; j++) {
254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (enabled[i].equals(supported[j])) {
255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        break found;
256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Enabled suite does not belong to the set "
259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "of supported cipher suites: " + enabled[i]);
260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnabledCipherSuites(supported);
263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnabledCipherSuites(enabled);
264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnabledCipherSuites(supported);
265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] more_than_supported = new String[supported.length+1];
266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<supported.length+1; i++) {
267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            more_than_supported[i]
268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                = "NOT_SUPPORTED_CIPHER_SUITE";
269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.arraycopy(supported, 0,
270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    more_than_supported, 0, i);
271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.arraycopy(supported, i,
272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    more_than_supported, i+1, supported.length-i);
273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.setEnabledCipherSuites(more_than_supported);
275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Expected IllegalArgumentException was not thrown");
276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (IllegalArgumentException e) { }
277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        enabled = engine.getEnabledCipherSuites();
279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        enabled[0] = "NOT_SUPPORTED_CIPHER_SUITE";
280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        enabled = engine.getEnabledCipherSuites();
281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<enabled.length; i++) {
282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if ("NOT_SUPPORTED_CIPHER_SUITE".equals(enabled[i])) {
283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Modification of the returned result "
284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "causes the modification of the internal state");
285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getSupportedProtocols() method testing.
291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetSupportedProtocols() throws Exception {
293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] supported = engine.getSupportedProtocols();
295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull(supported);
296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(supported.length == 0);
297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        supported[0] = "NOT_SUPPORTED_PROTOCOL";
298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        supported = engine.getSupportedProtocols();
299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<supported.length; i++) {
300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if ("NOT_SUPPORTED_PROTOCOL".equals(supported[i])) {
301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Modification of the returned result "
302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "causes the modification of the internal state");
303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getEnabledProtocols() method testing.
309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetEnabledProtocols() throws Exception {
311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] enabled = engine.getEnabledProtocols();
313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertNotNull(enabled);
314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String[] supported = engine.getSupportedProtocols();
315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<enabled.length; i++) {
316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            found: {
317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                for (int j=0; j<supported.length; j++) {
318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (enabled[i].equals(supported[j])) {
319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        break found;
320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Enabled protocol does not belong to the set "
323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "of supported protocols: " + enabled[i]);
324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnabledProtocols(supported);
327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=0; i<supported.length; i++) {
328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            enabled = new String[supported.length - i];
329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.arraycopy(supported, i,
330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    enabled, 0, supported.length-i);
331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.setEnabledProtocols(enabled);
332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            String[] result = engine.getEnabledProtocols();
333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (result.length != enabled.length) {
334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Returned result differs from expected.");
335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            for (int k=0; k<result.length; k++) {
337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                found: {
338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    for (int n=0; n<enabled.length; n++) {
339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (result[k].equals(enabled[n])) {
340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            break found;
341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (result.length != enabled.length) {
344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        fail("Returned result does not correspond "
345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + "to expected.");
346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * setUseClientMode(boolean mode) method testing.
354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getUseClientMode() method testing.
355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetGetUseClientMode() throws Exception {
357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setUseClientMode(false);
360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Result differs from expected",
361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getUseClientMode());
362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setUseClientMode(true);
363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Result differs from expected",
364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getUseClientMode());
365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.beginHandshake();
367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.setUseClientMode(false);
369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalArgumentException was not thrown");
370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalArgumentException e) { }
371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.wrap(ByteBuffer.allocate(0), ByteBuffer.allocate(
373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getSession().getPacketBufferSize()));
374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.setUseClientMode(false);
376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalArgumentException was not thrown");
377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalArgumentException e) { }
378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     }
379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * setEnableSessionCreation(boolean flag) method testing.
382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getEnableSessionCreation() method testing.
383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testSetGetEnableSessionCreation() throws Exception {
385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnableSessionCreation(false);
388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse("Result differs from expected",
389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getEnableSessionCreation());
390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setEnableSessionCreation(true);
391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Result differs from expected",
392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getEnableSessionCreation());
393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * getSession() method testing.
397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testGetSession() throws Exception {
399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLSession session = engine.getSession();
402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if ((session == null)
403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                || (!session.getCipherSuite()
404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    .endsWith("_NULL_WITH_NULL_NULL"))) {
405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Returned session is null "
406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + "or not TLS_NULL_WITH_NULL_NULL");
407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * beginHandshake() method testing
412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     *
413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testBeginHandshake() throws Exception {
415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect initial handshake status",
417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getHandshakeStatus(),
418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.beginHandshake();
421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected IllegalStateException was not thrown");
422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (IllegalStateException e) { }
423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine = getEngine();
425561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setUseClientMode(false);
426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.beginHandshake();
427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect initial handshake status",
428561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getHandshakeStatus(),
429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_UNWRAP);
430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine = getEngine();
432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.setUseClientMode(true);
433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.beginHandshake();
434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect initial handshake status",
435561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                engine.getHandshakeStatus(),
436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_WRAP);
437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * closeOutbound() method testing.
441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testCloseOutbound() throws Exception {
443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(engine.isOutboundDone());
445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.closeOutbound();
446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result = engine.wrap(ByteBuffer.allocate(0),
447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ByteBuffer.allocate(20000));
448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect status", result.getStatus(),
449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED);
450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect status", result.getHandshakeStatus(),
451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should throw SSLException "engine already closed"
454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.beginHandshake();
455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected exception was not thrown.");
456561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (SSLException e) { }
457561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(engine.isOutboundDone());
458561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
459561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
460561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
461561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * closeInbound() method testing.
462561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
463561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testCloseInbound() throws Exception {
464561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine engine = getEngine();
465561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(engine.isInboundDone());
466561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        engine.closeInbound();
467561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result = engine.wrap(ByteBuffer.allocate(0),
468561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ByteBuffer.allocate(20000));
469561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect status", result.getStatus(),
470561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED);
471561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Incorrect status", result.getHandshakeStatus(),
472561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
473561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
474561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should throw SSLException "engine already closed"
475561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            engine.beginHandshake();
476561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected exception was not thrown.");
477561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (SSLException e) { }
478561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(engine.isInboundDone());
479561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
480561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
481561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
482561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * closeInbound() method testing.
483561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests error processing in the case of unexpected closeInbound.
484561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
485561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testCloseInbound2() throws Exception {
486561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine client = getEngine();
487561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine server = getEngine();
488561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        initEngines(client, server);
489561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
490561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int packetBufferSize =
491561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client.getSession().getPacketBufferSize();
492561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int applicationBufferSize =
493561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            server.getSession().getApplicationBufferSize();
494561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
495561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer buffer = ByteBuffer.allocate(packetBufferSize);
496561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data_buffer = ByteBuffer.allocate(applicationBufferSize);
497561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
498561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setUseClientMode(true);
499561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setUseClientMode(false);
500561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
501561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshake(client, server);
502561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
503561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
504561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nError processing test:");
505561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
506561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
507561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should cause SSLException, prepare fatal alert "internal error",
508561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // and set HandshakeStatus to NEED_WRAP
509561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // (to send alert to another side)
510561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            server.closeInbound();
511561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected exception was not thrown.");
512561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (Exception e) {
513561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
514561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Server threw exception: "
515561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + e.getMessage());
516561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
517561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // e.printStackTrace();
518561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // should do nothing
519561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            server.closeInbound();
520561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status:",
521561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NEED_WRAP,
522561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.getHandshakeStatus());
523561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
524561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
525561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Wrapping of the alert message");
526561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
527561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLEngineResult result = null;
528561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = server.wrap(ByteBuffer.allocate(0), buffer));
529561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
530561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.CLOSED,
531561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
532561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
533561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
534561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getHandshakeStatus());
535561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals(
536561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the consumed data differs from expected",
537561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                0, result.bytesConsumed());
538561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue(
539561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the produced data differs from expected",
540561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.bytesProduced() > 0);
541561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // tune buffer to be read
542561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            buffer.flip();
543561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
544561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // should rethrow the SSLException "internal error"
545561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                print(client.unwrap(buffer, app_data_buffer));
546561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Expected exception was not thrown.");
547561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Exception ex) {
548561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
549561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("Client rethrew received alert: "
550561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + ex.getMessage());
551561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
552561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // NOT_HANDSHAKING..
553561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertEquals("Unexpected status of operation:",
554561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
555561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.getHandshakeStatus());
556561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                client.closeOutbound();
557561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // NEED_WRAP.. should it be so? it contradicts to the TLS spec:
558561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // "Upon transmission or receipt of an fatal alert message, both
559561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // parties immediately close the connection. Servers and clients
560561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // are required to forget any session-identifiers, keys, and
561561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // secrets associated with a failed connection."
562561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // So in this case we expect NOT_HANDSHAKING
563561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertEquals("Unexpected status of operation:",
564561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
565561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.getHandshakeStatus());
566561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertTrue("Outbound should be closed.",
567561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.isOutboundDone());
568561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertTrue("Inbound should be closed.",
569561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.isInboundDone());
570561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
571561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
572561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
573561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
574561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
575561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * closeInbound() method testing.
576561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests error processing
577561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
578561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void testErrorProcessing() throws Exception {
579561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine client = getEngine();
580561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine server = getEngine();
581561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        initEngines(client, server);
582561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
583561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int packetBufferSize =
584561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client.getSession().getPacketBufferSize();
585561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int applicationBufferSize =
586561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            server.getSession().getApplicationBufferSize();
587561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
588561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer buffer = ByteBuffer.allocate(packetBufferSize);
589561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data_buffer = ByteBuffer.allocate(applicationBufferSize);
590561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
591561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setUseClientMode(true);
592561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setUseClientMode(false);
593561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
594561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshake(client, server);
595561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
596561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
597561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nError processing test:");
598561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
599561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
600561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(server.unwrap(ByteBuffer.allocate(40), app_data_buffer));
601561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("Expected exception was not thrown.");
602561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (Exception e) {
603561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
604561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("\nServer threw exception: "
605561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        +e.getMessage());
606561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
607561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
608561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NEED_WRAP,
609561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.getHandshakeStatus());
610561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
611561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLEngineResult result = null;
612561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertFalse("Outbound should not be closed.",
613561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.isOutboundDone());
614561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Inbound should be closed.",
615561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.isInboundDone());
616561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
617561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
618561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println(
619561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        "\nServer tries to unwrap the data after error");
620561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
621561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result =
622561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.unwrap(ByteBuffer.allocate(40), app_data_buffer));
623561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
624561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.CLOSED,
625561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
626561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
627561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NEED_WRAP,
628561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getHandshakeStatus());
629561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals(
630561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the consumed data differs from expected",
631561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                0, result.bytesConsumed());
632561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals(
633561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the produced data differs from expected",
634561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                0, result.bytesProduced());
635561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
636561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
637561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("\nServer wraps the fatal alert");
638561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
639561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = server.wrap(ByteBuffer.allocate(0), buffer));
640561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
641561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.CLOSED,
642561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
643561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
644561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
645561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getHandshakeStatus());
646561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals(
647561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the consumed data differs from expected",
648561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                0, result.bytesConsumed());
649561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue(
650561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the produced data differs from expected",
651561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.bytesProduced() > 0);
652561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
653561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Outbound should be closed.",
654561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.isOutboundDone());
655561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Inbound should be closed.",
656561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    server.isInboundDone());
657561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
658561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            buffer.flip();
659561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            try {
660561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
661561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("\nClient unwraps the fatal alert");
662561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
663561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                print(client.unwrap(buffer, app_data_buffer));
664561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Expected exception was not thrown.");
665561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } catch (Exception ex) {
666561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
667561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("\nClient rethrew the exception: "
668561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + ex.getMessage());
669561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
670561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // NOT_HANDSHAKING..
671561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertEquals("Unexpected status of operation:",
672561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
673561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.getHandshakeStatus());
674561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                client.closeOutbound();
675561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // NEED_WRAP.. should it be so? it contradicts to the TLS spec:
676561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // "Upon transmission or receipt of an fatal alert message, both
677561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // parties immediately close the connection. Servers and clients
678561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // are required to forget any session-identifiers, keys, and
679561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // secrets associated with a failed connection."
680561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // So in this case we expect NOT_HANDSHAKING
681561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertEquals("Unexpected status of operation:",
682561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
683561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.getHandshakeStatus());
684561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertTrue("Outbound should be closed.",
685561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.isOutboundDone());
686561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertTrue("Inbound should be closed.",
687561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        client.isInboundDone());
688561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
689561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
690561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
691561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
692561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
693561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // --------------------------------------------------------------------
694561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // ------------------------ Staff methods -----------------------------
695561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    // --------------------------------------------------------------------
696561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
697561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
698561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs the handshake over the specified engines
699561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
700561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void doHandshake(SSLEngine client,
701561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLEngine server) throws Exception {
702561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
703561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\n--- doHandshake:");
704561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Server: "+server.getSession().getClass());
705561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Client: "+client.getSession().getClass());
706561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
707561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
708561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.beginHandshake();
709561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.beginHandshake();
710561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
711561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        doHandshakeImpl(client, server);
712561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
713561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
714561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
715561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs the handshake over the specified engines.
716561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Note that method passes app data between the engines during
717561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * the handshake process.
718561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
719561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void doHandshakeImpl(SSLEngine client,
720561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLEngine server) throws Exception {
721561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
722561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\n--- doHandshakeImpl:");
723561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Client's hsh status: "
724561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + client.getHandshakeStatus());
725561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Client's session: "+client.getSession());
726561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Server's hsh status: "
727561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + server.getHandshakeStatus());
728561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("Server's session: "+server.getSession());
729561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
730561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
731561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int packetBufferSize =
732561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            client.getSession().getPacketBufferSize();
733561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int applicationBufferSize =
734561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            server.getSession().getApplicationBufferSize();
735561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
736561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // buffer will contain handshake messages
737561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer clients_buffer = ByteBuffer.allocate(packetBufferSize+1000);
738561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer servers_buffer = ByteBuffer.allocate(packetBufferSize+1000);
739561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // buffers will contain application data messages
740561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data = ByteBuffer.allocate(packetBufferSize);
741561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data_plain = ByteBuffer.allocate(applicationBufferSize);
742561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
743561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine[] engines = new SSLEngine[] {client, server};
744561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer[] buffers =
745561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            new ByteBuffer[] {clients_buffer, servers_buffer};
746561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
747561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // choose which peer will start handshake negotiation
748561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // (initial handshake is initiated by client, but rehandshake
749561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // can be initiated by any peer)
750561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int step = (client.getHandshakeStatus()
751561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) ? 0 : 1;
752561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
753561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngine current_engine = engines[step];
754561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer buffer;
755561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result = null;
756561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult.HandshakeStatus status;
757561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
758561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        while ((client.getHandshakeStatus()
759561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
760561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                || (server.getHandshakeStatus()
761561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)) {
762561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
763561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.print("\n"
764561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + ((current_engine == client) ? "CLIENT " : "SERVER "));
765561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
766561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            status = current_engine.getHandshakeStatus();
767561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (status == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
768561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // so another peer produced
769561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // the handshaking data which has to be unwrapped
770561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
771561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.print("(NOT_HANDSHAKING) ");
772561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
773561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                status = SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
774561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
775561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (status == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
776561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
777561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("NEED_WRAP");
778561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
779561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // will wrap handshake data into its special buffer
780561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                buffer = buffers[step];
781561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (buffer.remaining() == 0) {
782561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // handshake data was fully read by another peer,
783561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // so we need clear the buffer before reusing it
784561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    buffer.clear();
785561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
786561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // wrap the next handshake message
787561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                print(result = current_engine.wrap(app_data, buffer));
788561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // if there are no any messages to send, switch the engine
789561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (current_engine.getHandshakeStatus()
790561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        != SSLEngineResult.HandshakeStatus.NEED_WRAP) {
791561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // switch the current engine
792561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    step ^= 1;
793561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    current_engine = engines[step];
794561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // and prepare the buffer for reading
795561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    buffer.flip();
796561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
797561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else if (status == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
798561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
799561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println("NEED_UNWRAP");
800561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
801561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
802561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // If there are no unread handshake messages produced by the
803561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // current engine, try to wrap the application data and unwrap
804561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // it by another engine. It will test app data flow during
805561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // the rehandshake.
806561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (!buffers[step].hasRemaining()) {
807561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (doLog) {
808561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println(
809561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                "\nTry to WRAP the application data");
810561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
811561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    print(result = current_engine.wrap(
812561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                ByteBuffer.wrap(new byte[] {0}), app_data));
813561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // The output in app_data will be produced only if it
814561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // is rehandshaking stage
815561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // (i.e. initial handshake has been done)
816561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (result.bytesProduced() > 0) {
817561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // if the app data message has been produced,
818561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        // unwrap it by another peer
819561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        if (doLog) {
820561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            System.out.print("\n" + ((current_engine != client)
821561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                                     ? "CLIENT " : "SERVER "));
822561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            System.out.println(
823561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                "UNWRAPs app data sent during handshake");
824561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        }
825561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        app_data.flip();
826561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        print(result = engines[(step+1)%2].unwrap(
827561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                    app_data, app_data_plain));
828561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        app_data.clear();
829561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        app_data_plain.clear();
830561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
831561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
832561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
833561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                buffer = buffers[step^1];
834561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
835561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // check if there is handshake data to be unwrapped
836561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (buffer.remaining() == 0) {
837561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (doLog) {
838561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println(
839561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                "There is no handshake data to be unwrapped.");
840561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
841561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // switch the current engine
842561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    step ^= 1;
843561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    current_engine = engines[step];
844561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if ((current_engine.getHandshakeStatus()
845561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                == SSLEngineResult.HandshakeStatus.NEED_UNWRAP)
846561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            && (buffers[step^1].remaining() == 0)) {
847561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println(
848561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                "Both engines are in NEED_UNWRAP state");
849561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        fail("Both engines are in NEED_UNWRAP state");
850561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
851561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    continue;
852561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
853561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
854561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                print(result = current_engine.unwrap(buffer, app_data));
855561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (current_engine.getHandshakeStatus()
856561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        == SSLEngineResult.HandshakeStatus.NEED_TASK) {
857561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (doLog) {
858561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println("NEED_TASK");
859561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
860561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    current_engine.getDelegatedTask().run();
861561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (doLog) {
862561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println("status after the task: "
863561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                +current_engine.getHandshakeStatus());
864561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
865561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
866561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
867561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Unexpected HandshakeStatus: "+status);
868561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
869561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
870561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.OK,
871561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
872561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
873561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
874561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
875561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
876561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs the session renegotiation process when one
877561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * of the peers is not allowed to create the session.
878561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
879561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void doNoRenegotiationTest(SSLEngine allowed,
880561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            SSLEngine not_allowed, boolean is_initial) throws Exception {
881561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
882561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println(
883561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    "\n--- doNoRenegotiationTest: is_initial: "+is_initial);
884561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
885561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
886561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        not_allowed.setEnableSessionCreation(false);
887561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        not_allowed.getSession().invalidate();
888561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
889561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int packetBufferSize =
890561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            allowed.getSession().getPacketBufferSize();
891561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        int applicationBufferSize =
892561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            not_allowed.getSession().getApplicationBufferSize();
893561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
894561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // buffer will contain handshake messages
895561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer buffer = ByteBuffer.allocate(packetBufferSize+1000);
896561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // buffers will contain application data messages
897561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data = ByteBuffer.allocate(packetBufferSize);
898561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data_plain = ByteBuffer.allocate(applicationBufferSize);
899561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
900561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result = null;
901561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
902561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        allowed.beginHandshake();
903561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        //not_allowed.beginHandshake();
904561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
905561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
906561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println(
907561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "\nAllowed peer wraps the initial session negotiation message");
908561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
909561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // wrap the initial session negotiation message
910561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        while (allowed.getHandshakeStatus().equals(
911561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
912561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = allowed.wrap(app_data_plain, buffer));
913561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Engine did not produce any data",
914561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.bytesProduced() > 0);
915561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
916561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare the buffer for reading
917561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.flip();
918561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
919561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nNot allowed unwraps the message");
920561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
921561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
922561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // unwrap the message. expecting whether SSLException or NEED_WRAP
923561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = not_allowed.unwrap(buffer, app_data_plain));
924561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (SSLException e) {
925561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (is_initial) {
926561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                return; // ok, exception was thrown
927561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            } else {
928561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Unexpected SSLException was thrown "+e);
929561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
930561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
931561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // if it is not an initial handshake phase it is posible
932561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // SSLException to be thrown.
933561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
934561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            while (!not_allowed.getHandshakeStatus().equals(
935561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
936561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                assertTrue("Engine did not consume any data",
937561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        result.bytesConsumed() > 0);
938561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (not_allowed.getHandshakeStatus().equals(
939561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            SSLEngineResult.HandshakeStatus.NEED_TASK)) {
940561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    not_allowed.getDelegatedTask().run();
941561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    if (doLog) {
942561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        System.out.println("Status after the task: "
943561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                + not_allowed.getHandshakeStatus());
944561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
945561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    continue;
946561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else if (not_allowed.getHandshakeStatus().equals(
947561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
948561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    print(result = not_allowed.unwrap(buffer, app_data_plain));
949561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
950561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    fail("Unexpected status of operation: "
951561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            + not_allowed.getHandshakeStatus());
952561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
953561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
954561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // prepare for writting
955561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            buffer.clear();
956561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
957561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println(
958561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    "\nWrapping the message. Expecting no_renegotiation alert");
959561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
960561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            // wrapping the message. expecting no_renegotiation alert
961561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = not_allowed.wrap(app_data_plain, buffer));
962561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (SSLException e) {
963561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (!is_initial) {
964561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Unexpected SSLException was thrown."+e.getMessage());
965561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
966561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
967561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Throwed exception during the unwrapping "
968561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "of handshake initiation message:");
969561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                e.printStackTrace();
970561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Handshake Status: "
971561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + not_allowed.getHandshakeStatus());
972561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
973561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (not_allowed.getHandshakeStatus().equals(
974561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
975561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // needs to wrap fatal alert message
976561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                if (doLog) {
977561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    System.out.println(
978561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                            "\nnot_allowed wraps fatal alert message");
979561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
980561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // prepare for writting
981561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                buffer.clear();
982561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                print(result = not_allowed.wrap(app_data_plain, buffer));
983561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
984561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
985561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check whether alert message has been sent
986561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue("Engine did not produce any data",
987561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.bytesProduced() > 0);
988561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // check whether not_allowed engine stoped handshake operation
989561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation: not_allowed "
990561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                + "to session creation peer did not stop its handshake process",
991561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
992561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                not_allowed.getHandshakeStatus());
993561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare for reading
994561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.flip();
995561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        try {
996561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = allowed.unwrap(buffer, app_data_plain));
997561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue("Engine did not consume any data",
998561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.bytesConsumed() > 0);
999561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Responce from the peer not allowed to create "
1000561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + "the session did not cause the stopping of "
1001561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + "the session negotiation process",
1002561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1003561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getHandshakeStatus());
1004561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } catch (SSLException e) {
1005561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (!is_initial) {
1006561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                fail("Unexpected SSLException was thrown."+e.getMessage());
1007561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1008561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
1009561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Throwed exception during the unwrapping "
1010561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + "of responce from allowed peer:");
1011561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                e.printStackTrace();
1012561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("Handshake Status: "
1013561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        + not_allowed.getHandshakeStatus());
1014561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1015561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1016561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1017561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1018561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
1019561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Tests the data exchange process between two engines
1020561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1021561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void doDataExchange(SSLEngine client,
1022561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                                SSLEngine server) throws Exception {
1023561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1024561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\n--- doDataExchange:");
1025561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1026561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer co = ByteBuffer.allocate(
1027561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                client.getSession().getPacketBufferSize());
1028561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer si = ByteBuffer.allocate(
1029561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                server.getSession().getPacketBufferSize());
1030561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result;
1031561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1032561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String data_2b_sent = "data to be sent";
1033561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer data = ByteBuffer.wrap(data_2b_sent.getBytes());
1034561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1035561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1036561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nTry to wrap the data into small buffer");
1037561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1038561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.wrap(data, ByteBuffer.allocate(35)));
1039561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1040561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.BUFFER_OVERFLOW,
1041561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1042561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1043561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1044561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nWrapping the data of length "
1045561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + data.remaining());
1046561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1047561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.wrap(data, co));
1048561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1049561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.OK,
1050561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1051561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1052561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // tune the buffer to read from it
1053561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        co.limit(co.position());
1054561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        co.rewind();
1055561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1056561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1057561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nTry to unwrap the data into small buffer");
1058561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1059561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.unwrap(co, ByteBuffer.allocate(0)));
1060561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1061561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.BUFFER_OVERFLOW,
1062561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1063561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1064561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nUnwrapping the data into buffer");
1065561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1066561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.unwrap(co, si));
1067561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1068561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.OK,
1069561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1070561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1071561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the received data differs from expected",
1072561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "data to be sent".length(), result.bytesProduced());
1073561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1074561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // take the data from the buffer
1075561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        byte[] resulting_data = new byte[result.bytesProduced()];
1076561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        si.rewind();
1077561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        si.get(resulting_data);
1078561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        si.clear();
1079561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(Arrays.equals(data_2b_sent.getBytes(), resulting_data));
1080561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1081561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        co.clear();
1082561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        for (int i=1; i<10; i++) {
1083561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            byte[] buff = new byte[i];
1084561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            data = ByteBuffer.wrap(buff);
1085561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
1086561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("\nWrap the data");
1087561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1088561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = client.wrap(data, co));
1089561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
1090561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.OK,
1091561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
1092561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            if (doLog) {
1093561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                System.out.println("\nUnwrap the data");
1094561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1095561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            co.rewind();
1096561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            print(result = server.unwrap(co, si));
1097561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals("Unexpected status of operation:",
1098561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    SSLEngineResult.Status.OK,
1099561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    result.getStatus());
1100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertEquals(
1101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                "The length of the received data differs from expected",
1102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                i, result.bytesProduced());
1103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            resulting_data = new byte[i];
1104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            si.rewind();
1105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            si.get(resulting_data);
1106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            si.clear();
1107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            assertTrue(Arrays.equals(buff, resulting_data));
1108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            co.clear();
1109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            si.clear();
1110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
1114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Performs the closure process over the two communicationg engines.
1115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * The handshake process should be performed before the call of this
1116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * method.
1117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void doClose(SSLEngine client, SSLEngine server) throws Exception {
1119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\n--- doClose: ");
1121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer buffer = ByteBuffer.allocate(
1123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // +100 because we put the data into the buffer multiple times
1124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                server.getSession().getPacketBufferSize()+100);
1125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ByteBuffer app_data_buffer = ByteBuffer.allocate(
1126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                client.getSession().getApplicationBufferSize());
1127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        SSLEngineResult result;
1128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // first: send 0 just for fun
1129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer sends pending outboud data:");
1131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.wrap(ByteBuffer.wrap(new byte[] {0}), buffer));
1133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.OK,
1135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // second: initiate a close
1140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer initiates a closure:");
1142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.closeOutbound();
1144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // should do nothing:
1145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.closeOutbound();
1146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_WRAP,
1149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                server.getHandshakeStatus());
1150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // will cause SSLException because closure alert was not received yet:
1152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // server.closeInbound();
1153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // wrap closure alert (previosly sent 0 should not be lost)
1155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.wrap(ByteBuffer.allocate(0), buffer));
1156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_UNWRAP,
1161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer sends pending outboud data again:");
1165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // will do nothing because closure alert has been sent
1167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // and outbound has been closed
1168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.wrap(ByteBuffer.wrap(new byte[] {0}), buffer));
1169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_UNWRAP,
1174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare the buffer for reading
1183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.flip();
1184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println(
1187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    "\nClient receives pending servers' outbound data");
1188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.unwrap(buffer, app_data_buffer));
1190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.OK,
1192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            1, result.bytesProduced());
1199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        app_data_buffer.clear();
1201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nClient receives close notify");
1204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.unwrap(buffer, app_data_buffer));
1206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_WRAP,
1211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(
1213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            result.bytesConsumed() > 0);
1215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the received data differs from expected",
1217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare the buffer for writing
1220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        app_data_buffer.clear();
1221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // it's needless, but should work (don't cause exceptions):
1223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.closeInbound();
1224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.closeOutbound();
1225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nClient tries to read data again");
1228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // CLOSED, 0 consumed, 0 produced
1230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.unwrap(buffer, app_data_buffer));
1231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NEED_WRAP,
1236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the received data differs from expected",
1242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare the buffer for writing
1245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.clear();
1246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nClient sends responding close notify");
1249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.wrap(ByteBuffer.wrap(new byte[] {0}), buffer));
1251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(
1261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            result.bytesProduced() > 0);
1263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println(
1265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    "\nClient tries to send data after closure alert");
1266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // this data will not be sent (should do nothing - 0 cons, 0 prod)
1268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = client.wrap(ByteBuffer.wrap(new byte[] {0}), buffer));
1269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // prepare the buffers for reading
1283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        app_data_buffer.clear();
1284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.flip();
1285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer receives close notify");
1288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.unwrap(buffer, app_data_buffer));
1290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(
1297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            result.bytesConsumed() > 0);
1299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer tries to read after closure");
1305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // will be ignored
1307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.unwrap(buffer, app_data_buffer));
1308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // it's needless, but should work:
1322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.closeInbound();
1323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        // will be ignored
1324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("\nServer tries to write after closure");
1327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        buffer.clear();
1329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        print(result = server.wrap(ByteBuffer.allocate(0), buffer));
1330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.Status.CLOSED,
1332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getStatus());
1333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals("Unexpected status of operation:",
1334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                result.getHandshakeStatus());
1336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the consumed data differs from expected",
1338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesConsumed());
1339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertEquals(
1340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            "The length of the produced data differs from expected",
1341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            0, result.bytesProduced());
1342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private static void print(SSLEngineResult result) {
1345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        if (doLog) {
1346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            System.out.println("result:\n"+result);
1347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Returns the engine to be tested.
1352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private SSLEngine getEngine() throws Exception {
1354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return JSSETestData.getContext().createSSLEngine("localhost", 2345);
1355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /**
1358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * Initializes the engines.
1359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
1360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private void initEngines(SSLEngine client, SSLEngine server) {
1361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        String prefix = "TLS_";
1362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setEnabledProtocols(new String[] {"TLSv1"});
1364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setEnabledProtocols(new String[] {"TLSv1"});
1365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setEnabledCipherSuites(
1366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                new String[] {prefix+cipher_suites[0]});
1367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setEnabledCipherSuites(
1368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                new String[] {prefix+cipher_suites[0]});
1369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        client.setUseClientMode(true);
1371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        server.setUseClientMode(false);
1372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public static Test suite() {
1375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        return new TestSuite(SSLEngineImplTest.class);
1376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
1377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}
1379