0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: package org.apache.harmony.xnet.provider.jsse;
0019:
0020: import java.nio.ByteBuffer;
0021: import java.util.Arrays;
0022: import javax.net.ssl.SSLEngine;
0023: import javax.net.ssl.SSLEngineResult;
0024: import javax.net.ssl.SSLException;
0025: import javax.net.ssl.SSLSession;
0026:
0027: import junit.framework.Test;
0028: import junit.framework.TestCase;
0029: import junit.framework.TestSuite;
0030:
0031: /**
0032: * SSLEngine implementation test.
0033: */
0034: public class SSLEngineImplTest extends TestCase {
0035:
0036: /**
0037: * The cipher suites used for functionality testing.
0038: */
0039: private static final String[] cipher_suites = {
0040: "RSA_WITH_RC4_128_MD5", "RSA_WITH_DES_CBC_SHA",
0041: "DH_anon_EXPORT_WITH_DES40_CBC_SHA" };
0042:
0043: /**
0044: * Test logging switch.
0045: */
0046: private static boolean doLog = false;
0047:
0048: /**
0049: * Sets up the test case.
0050: */
0051: public void setUp() throws Exception {
0052: if (doLog) {
0053: System.out.println("");
0054: System.out.println("========================");
0055: System.out.println("====== Running the test: " + getName());
0056: System.out.println("========================");
0057: }
0058: }
0059:
0060: /**
0061: * Tests the interaction between the engines.
0062: */
0063: public void testSelfInteraction() throws Exception {
0064: String[] protocols = { "SSLv3", "TLSv1" };
0065: for (int i = 0; i < cipher_suites.length; i++) {
0066: for (int j = 0; j < 2; j++) {
0067: if (doLog) {
0068: System.out.println("\n===== Interact over suite: "
0069: + cipher_suites[i]);
0070: }
0071: SSLEngine client = getEngine();
0072: SSLEngine server = getEngine();
0073: initEngines(client, server);
0074:
0075: doHandshake(client, server);
0076: doDataExchange(client, server);
0077: doClose(client, server);
0078: }
0079: }
0080: }
0081:
0082: /**
0083: * Tests the session negotiation process.
0084: */
0085: public void testHandshake() throws Exception {
0086: SSLEngine client = getEngine();
0087: SSLEngine server = getEngine();
0088:
0089: initEngines(client, server);
0090:
0091: // checks the impossibility of initial handshake
0092: // with the server not allowed to session creation
0093: doNoRenegotiationTest(client, server, true);
0094:
0095: client = getEngine();
0096: server = getEngine();
0097: initEngines(client, server);
0098:
0099: client.setUseClientMode(true);
0100: server.setUseClientMode(false);
0101:
0102: // do initial handshake
0103: doHandshake(client, server);
0104:
0105: // client initiates rehandshake
0106: client.beginHandshake();
0107: doHandshakeImpl(client, server);
0108:
0109: // server initiates rehandshake
0110: server.beginHandshake();
0111: doHandshakeImpl(client, server);
0112:
0113: // client initiates rehandshake while server invalidates
0114: // used session
0115: server.getSession().invalidate();
0116: client.beginHandshake();
0117: doHandshakeImpl(client, server);
0118:
0119: // server initiates rehandshake while client invalidates
0120: // used session
0121: client.getSession().invalidate();
0122: server.beginHandshake();
0123: doHandshakeImpl(client, server);
0124:
0125: client.getSession().invalidate();
0126: server.getSession().invalidate();
0127: doHandshake(client, server);
0128:
0129: doNoRenegotiationTest(client, server, false);
0130:
0131: doNoRenegotiationTest(server, client, false);
0132:
0133: doClose(client, server);
0134: }
0135:
0136: /**
0137: * setNeedClientAuth(boolean need) method testing.
0138: * getNeedClientAuth() method testing.
0139: */
0140: public void testSetGetNeedClientAuth() throws Exception {
0141: SSLEngine engine = getEngine();
0142:
0143: engine.setWantClientAuth(true);
0144: engine.setNeedClientAuth(false);
0145: assertFalse("Result differs from expected", engine
0146: .getNeedClientAuth());
0147: assertFalse("Socket did not reset its want client auth state",
0148: engine.getWantClientAuth());
0149: engine.setWantClientAuth(true);
0150: engine.setNeedClientAuth(true);
0151: assertTrue("Result differs from expected", engine
0152: .getNeedClientAuth());
0153: assertFalse("Socket did not reset its want client auth state",
0154: engine.getWantClientAuth());
0155: }
0156:
0157: /**
0158: * setWantClientAuth(boolean want) method testing.
0159: * getWantClientAuth() method testing.
0160: */
0161: public void testSetGetWantClientAuth() throws Exception {
0162: SSLEngine engine = getEngine();
0163:
0164: engine.setNeedClientAuth(true);
0165: engine.setWantClientAuth(false);
0166: assertFalse("Result differs from expected", engine
0167: .getWantClientAuth());
0168: assertFalse("Socket did not reset its want client auth state",
0169: engine.getNeedClientAuth());
0170: engine.setNeedClientAuth(true);
0171: engine.setWantClientAuth(true);
0172: assertTrue("Result differs from expected", engine
0173: .getWantClientAuth());
0174: assertFalse("Socket did not reset its want client auth state",
0175: engine.getNeedClientAuth());
0176: }
0177:
0178: /**
0179: * getSupportedCipherSuites() method testing.
0180: */
0181: public void testGetSupportedCipherSuites() throws Exception {
0182: SSLEngine engine = getEngine();
0183: String[] supported = engine.getSupportedCipherSuites();
0184: assertNotNull(supported);
0185: supported[0] = "NOT_SUPPORTED_CIPHER_SUITE";
0186: supported = engine.getEnabledCipherSuites();
0187: for (int i = 0; i < supported.length; i++) {
0188: if ("NOT_SUPPORTED_CIPHER_SUITE".equals(supported[i])) {
0189: fail("Modification of the returned result "
0190: + "causes the modification of the internal state");
0191: }
0192: }
0193: }
0194:
0195: /**
0196: * getEnabledCipherSuites() method testing.
0197: */
0198: public void testGetEnabledCipherSuites() throws Exception {
0199: SSLEngine engine = getEngine();
0200: String[] enabled = engine.getEnabledCipherSuites();
0201: assertNotNull(enabled);
0202: String[] supported = engine.getSupportedCipherSuites();
0203: for (int i = 0; i < enabled.length; i++) {
0204: found: {
0205: for (int j = 0; j < supported.length; j++) {
0206: if (enabled[i].equals(supported[j])) {
0207: break found;
0208: }
0209: }
0210: fail("Enabled suite does not belong to the set "
0211: + "of supported cipher suites: " + enabled[i]);
0212: }
0213: }
0214: engine.setEnabledCipherSuites(supported);
0215: for (int i = 0; i < supported.length; i++) {
0216: enabled = new String[supported.length - i];
0217: System.arraycopy(supported, 0, enabled, 0, supported.length
0218: - i);
0219: engine.setEnabledCipherSuites(enabled);
0220: String[] result = engine.getEnabledCipherSuites();
0221: if (result.length != enabled.length) {
0222: fail("Returned result differs from expected.");
0223: }
0224: for (int k = 0; k < result.length; k++) {
0225: found: {
0226: for (int n = 0; n < enabled.length; n++) {
0227: if (result[k].equals(enabled[n])) {
0228: break found;
0229: }
0230: }
0231: if (result.length != enabled.length) {
0232: fail("Returned result does not correspond "
0233: + "to expected.");
0234: }
0235: }
0236: }
0237: }
0238: }
0239:
0240: /**
0241: * setEnabledCipherSuites(String[] suites) method testing.
0242: */
0243: public void testSetEnabledCipherSuites() throws Exception {
0244: SSLEngine engine = getEngine();
0245: String[] enabled = engine.getEnabledCipherSuites();
0246: assertNotNull(enabled);
0247: String[] supported = engine.getSupportedCipherSuites();
0248: for (int i = 0; i < enabled.length; i++) {
0249: found: {
0250: for (int j = 0; j < supported.length; j++) {
0251: if (enabled[i].equals(supported[j])) {
0252: break found;
0253: }
0254: }
0255: fail("Enabled suite does not belong to the set "
0256: + "of supported cipher suites: " + enabled[i]);
0257: }
0258: }
0259: engine.setEnabledCipherSuites(supported);
0260: engine.setEnabledCipherSuites(enabled);
0261: engine.setEnabledCipherSuites(supported);
0262: String[] more_than_supported = new String[supported.length + 1];
0263: for (int i = 0; i < supported.length + 1; i++) {
0264: more_than_supported[i] = "NOT_SUPPORTED_CIPHER_SUITE";
0265: System.arraycopy(supported, 0, more_than_supported, 0, i);
0266: System.arraycopy(supported, i, more_than_supported, i + 1,
0267: supported.length - i);
0268: try {
0269: engine.setEnabledCipherSuites(more_than_supported);
0270: fail("Expected IllegalArgumentException was not thrown");
0271: } catch (IllegalArgumentException e) {
0272: }
0273: }
0274: enabled = engine.getEnabledCipherSuites();
0275: enabled[0] = "NOT_SUPPORTED_CIPHER_SUITE";
0276: enabled = engine.getEnabledCipherSuites();
0277: for (int i = 0; i < enabled.length; i++) {
0278: if ("NOT_SUPPORTED_CIPHER_SUITE".equals(enabled[i])) {
0279: fail("Modification of the returned result "
0280: + "causes the modification of the internal state");
0281: }
0282: }
0283: }
0284:
0285: /**
0286: * getSupportedProtocols() method testing.
0287: */
0288: public void testGetSupportedProtocols() throws Exception {
0289: SSLEngine engine = getEngine();
0290: String[] supported = engine.getSupportedProtocols();
0291: assertNotNull(supported);
0292: assertFalse(supported.length == 0);
0293: supported[0] = "NOT_SUPPORTED_PROTOCOL";
0294: supported = engine.getSupportedProtocols();
0295: for (int i = 0; i < supported.length; i++) {
0296: if ("NOT_SUPPORTED_PROTOCOL".equals(supported[i])) {
0297: fail("Modification of the returned result "
0298: + "causes the modification of the internal state");
0299: }
0300: }
0301: }
0302:
0303: /**
0304: * getEnabledProtocols() method testing.
0305: */
0306: public void testGetEnabledProtocols() throws Exception {
0307: SSLEngine engine = getEngine();
0308: String[] enabled = engine.getEnabledProtocols();
0309: assertNotNull(enabled);
0310: String[] supported = engine.getSupportedProtocols();
0311: for (int i = 0; i < enabled.length; i++) {
0312: found: {
0313: for (int j = 0; j < supported.length; j++) {
0314: if (enabled[i].equals(supported[j])) {
0315: break found;
0316: }
0317: }
0318: fail("Enabled protocol does not belong to the set "
0319: + "of supported protocols: " + enabled[i]);
0320: }
0321: }
0322: engine.setEnabledProtocols(supported);
0323: for (int i = 0; i < supported.length; i++) {
0324: enabled = new String[supported.length - i];
0325: System.arraycopy(supported, i, enabled, 0, supported.length
0326: - i);
0327: engine.setEnabledProtocols(enabled);
0328: String[] result = engine.getEnabledProtocols();
0329: if (result.length != enabled.length) {
0330: fail("Returned result differs from expected.");
0331: }
0332: for (int k = 0; k < result.length; k++) {
0333: found: {
0334: for (int n = 0; n < enabled.length; n++) {
0335: if (result[k].equals(enabled[n])) {
0336: break found;
0337: }
0338: }
0339: if (result.length != enabled.length) {
0340: fail("Returned result does not correspond "
0341: + "to expected.");
0342: }
0343: }
0344: }
0345: }
0346: }
0347:
0348: /**
0349: * setUseClientMode(boolean mode) method testing.
0350: * getUseClientMode() method testing.
0351: */
0352: public void testSetGetUseClientMode() throws Exception {
0353: SSLEngine engine = getEngine();
0354:
0355: engine.setUseClientMode(false);
0356: assertFalse("Result differs from expected", engine
0357: .getUseClientMode());
0358: engine.setUseClientMode(true);
0359: assertTrue("Result differs from expected", engine
0360: .getUseClientMode());
0361:
0362: engine.beginHandshake();
0363: try {
0364: engine.setUseClientMode(false);
0365: fail("Expected IllegalArgumentException was not thrown");
0366: } catch (IllegalArgumentException e) {
0367: }
0368:
0369: engine.wrap(ByteBuffer.allocate(0), ByteBuffer.allocate(engine
0370: .getSession().getPacketBufferSize()));
0371: try {
0372: engine.setUseClientMode(false);
0373: fail("Expected IllegalArgumentException was not thrown");
0374: } catch (IllegalArgumentException e) {
0375: }
0376: }
0377:
0378: /**
0379: * setEnableSessionCreation(boolean flag) method testing.
0380: * getEnableSessionCreation() method testing.
0381: */
0382: public void testSetGetEnableSessionCreation() throws Exception {
0383: SSLEngine engine = getEngine();
0384:
0385: engine.setEnableSessionCreation(false);
0386: assertFalse("Result differs from expected", engine
0387: .getEnableSessionCreation());
0388: engine.setEnableSessionCreation(true);
0389: assertTrue("Result differs from expected", engine
0390: .getEnableSessionCreation());
0391: }
0392:
0393: /**
0394: * getSession() method testing.
0395: */
0396: public void testGetSession() throws Exception {
0397: SSLEngine engine = getEngine();
0398:
0399: SSLSession session = engine.getSession();
0400: if ((session == null)
0401: || (!session.getCipherSuite().endsWith(
0402: "_NULL_WITH_NULL_NULL"))) {
0403: fail("Returned session is null "
0404: + "or not TLS_NULL_WITH_NULL_NULL");
0405: }
0406: }
0407:
0408: /**
0409: * beginHandshake() method testing
0410: *
0411: */
0412: public void testBeginHandshake() throws Exception {
0413: SSLEngine engine = getEngine();
0414: assertEquals("Incorrect initial handshake status", engine
0415: .getHandshakeStatus(),
0416: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
0417: try {
0418: engine.beginHandshake();
0419: fail("Expected IllegalStateException was not thrown");
0420: } catch (IllegalStateException e) {
0421: }
0422:
0423: engine = getEngine();
0424: engine.setUseClientMode(false);
0425: engine.beginHandshake();
0426: assertEquals("Incorrect initial handshake status", engine
0427: .getHandshakeStatus(),
0428: SSLEngineResult.HandshakeStatus.NEED_UNWRAP);
0429:
0430: engine = getEngine();
0431: engine.setUseClientMode(true);
0432: engine.beginHandshake();
0433: assertEquals("Incorrect initial handshake status", engine
0434: .getHandshakeStatus(),
0435: SSLEngineResult.HandshakeStatus.NEED_WRAP);
0436: }
0437:
0438: /**
0439: * closeOutbound() method testing.
0440: */
0441: public void testCloseOutbound() throws Exception {
0442: SSLEngine engine = getEngine();
0443: assertFalse(engine.isOutboundDone());
0444: engine.closeOutbound();
0445: SSLEngineResult result = engine.wrap(ByteBuffer.allocate(0),
0446: ByteBuffer.allocate(20000));
0447: assertEquals("Incorrect status", result.getStatus(),
0448: SSLEngineResult.Status.CLOSED);
0449: assertEquals("Incorrect status", result.getHandshakeStatus(),
0450: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
0451: try {
0452: // should throw SSLException "engine already closed"
0453: engine.beginHandshake();
0454: fail("Expected exception was not thrown.");
0455: } catch (SSLException e) {
0456: }
0457: assertTrue(engine.isOutboundDone());
0458: }
0459:
0460: /**
0461: * closeInbound() method testing.
0462: */
0463: public void testCloseInbound() throws Exception {
0464: SSLEngine engine = getEngine();
0465: assertFalse(engine.isInboundDone());
0466: engine.closeInbound();
0467: SSLEngineResult result = engine.wrap(ByteBuffer.allocate(0),
0468: ByteBuffer.allocate(20000));
0469: assertEquals("Incorrect status", result.getStatus(),
0470: SSLEngineResult.Status.CLOSED);
0471: assertEquals("Incorrect status", result.getHandshakeStatus(),
0472: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING);
0473: try {
0474: // should throw SSLException "engine already closed"
0475: engine.beginHandshake();
0476: fail("Expected exception was not thrown.");
0477: } catch (SSLException e) {
0478: }
0479: assertTrue(engine.isInboundDone());
0480: }
0481:
0482: /**
0483: * closeInbound() method testing.
0484: * Tests error processing in the case of unexpected closeInbound.
0485: */
0486: public void testCloseInbound2() throws Exception {
0487: SSLEngine client = getEngine();
0488: SSLEngine server = getEngine();
0489: initEngines(client, server);
0490:
0491: int packetBufferSize = client.getSession()
0492: .getPacketBufferSize();
0493: int applicationBufferSize = server.getSession()
0494: .getApplicationBufferSize();
0495:
0496: ByteBuffer buffer = ByteBuffer.allocate(packetBufferSize);
0497: ByteBuffer app_data_buffer = ByteBuffer
0498: .allocate(applicationBufferSize);
0499:
0500: client.setUseClientMode(true);
0501: server.setUseClientMode(false);
0502:
0503: doHandshake(client, server);
0504:
0505: if (doLog) {
0506: System.out.println("\nError processing test:");
0507: }
0508: try {
0509: // should cause SSLException, prepare fatal alert "internal error",
0510: // and set HandshakeStatus to NEED_WRAP
0511: // (to send alert to another side)
0512: server.closeInbound();
0513: fail("Expected exception was not thrown.");
0514: } catch (Exception e) {
0515: if (doLog) {
0516: System.out.println("Server threw exception: "
0517: + e.getMessage());
0518: }
0519: // e.printStackTrace();
0520: // should do nothing
0521: server.closeInbound();
0522: assertEquals("Unexpected status:",
0523: SSLEngineResult.HandshakeStatus.NEED_WRAP, server
0524: .getHandshakeStatus());
0525:
0526: if (doLog) {
0527: System.out.println("Wrapping of the alert message");
0528: }
0529: SSLEngineResult result = null;
0530: print(result = server.wrap(ByteBuffer.allocate(0), buffer));
0531: assertEquals("Unexpected status of operation:",
0532: SSLEngineResult.Status.CLOSED, result.getStatus());
0533: assertEquals("Unexpected status of operation:",
0534: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0535: result.getHandshakeStatus());
0536: assertEquals(
0537: "The length of the consumed data differs from expected",
0538: 0, result.bytesConsumed());
0539: assertTrue(
0540: "The length of the produced data differs from expected",
0541: result.bytesProduced() > 0);
0542: // tune buffer to be read
0543: buffer.flip();
0544: try {
0545: // should rethrow the SSLException "internal error"
0546: print(client.unwrap(buffer, app_data_buffer));
0547: fail("Expected exception was not thrown.");
0548: } catch (Exception ex) {
0549: if (doLog) {
0550: System.out
0551: .println("Client rethrew received alert: "
0552: + ex.getMessage());
0553: }
0554: // NOT_HANDSHAKING..
0555: assertEquals(
0556: "Unexpected status of operation:",
0557: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0558: client.getHandshakeStatus());
0559: client.closeOutbound();
0560: // NEED_WRAP.. should it be so? it contradicts to the TLS spec:
0561: // "Upon transmission or receipt of an fatal alert message, both
0562: // parties immediately close the connection. Servers and clients
0563: // are required to forget any session-identifiers, keys, and
0564: // secrets associated with a failed connection."
0565: // So in this case we expect NOT_HANDSHAKING
0566: assertEquals(
0567: "Unexpected status of operation:",
0568: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0569: client.getHandshakeStatus());
0570: assertTrue("Outbound should be closed.", client
0571: .isOutboundDone());
0572: assertTrue("Inbound should be closed.", client
0573: .isInboundDone());
0574: }
0575: }
0576: }
0577:
0578: /**
0579: * closeInbound() method testing.
0580: * Tests error processing
0581: */
0582: public void testErrorProcessing() throws Exception {
0583: SSLEngine client = getEngine();
0584: SSLEngine server = getEngine();
0585: initEngines(client, server);
0586:
0587: int packetBufferSize = client.getSession()
0588: .getPacketBufferSize();
0589: int applicationBufferSize = server.getSession()
0590: .getApplicationBufferSize();
0591:
0592: ByteBuffer buffer = ByteBuffer.allocate(packetBufferSize);
0593: ByteBuffer app_data_buffer = ByteBuffer
0594: .allocate(applicationBufferSize);
0595:
0596: client.setUseClientMode(true);
0597: server.setUseClientMode(false);
0598:
0599: doHandshake(client, server);
0600:
0601: if (doLog) {
0602: System.out.println("\nError processing test:");
0603: }
0604: try {
0605: print(server.unwrap(ByteBuffer.allocate(40),
0606: app_data_buffer));
0607: fail("Expected exception was not thrown.");
0608: } catch (Exception e) {
0609: if (doLog) {
0610: System.out.println("\nServer threw exception: "
0611: + e.getMessage());
0612: }
0613: assertEquals("Unexpected status of operation:",
0614: SSLEngineResult.HandshakeStatus.NEED_WRAP, server
0615: .getHandshakeStatus());
0616:
0617: SSLEngineResult result = null;
0618: assertFalse("Outbound should not be closed.", server
0619: .isOutboundDone());
0620: assertTrue("Inbound should be closed.", server
0621: .isInboundDone());
0622:
0623: if (doLog) {
0624: System.out
0625: .println("\nServer tries to unwrap the data after error");
0626: }
0627: print(result = server.unwrap(ByteBuffer.allocate(40),
0628: app_data_buffer));
0629: assertEquals("Unexpected status of operation:",
0630: SSLEngineResult.Status.CLOSED, result.getStatus());
0631: assertEquals("Unexpected status of operation:",
0632: SSLEngineResult.HandshakeStatus.NEED_WRAP, result
0633: .getHandshakeStatus());
0634: assertEquals(
0635: "The length of the consumed data differs from expected",
0636: 0, result.bytesConsumed());
0637: assertEquals(
0638: "The length of the produced data differs from expected",
0639: 0, result.bytesProduced());
0640:
0641: if (doLog) {
0642: System.out.println("\nServer wraps the fatal alert");
0643: }
0644: print(result = server.wrap(ByteBuffer.allocate(0), buffer));
0645: assertEquals("Unexpected status of operation:",
0646: SSLEngineResult.Status.CLOSED, result.getStatus());
0647: assertEquals("Unexpected status of operation:",
0648: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0649: result.getHandshakeStatus());
0650: assertEquals(
0651: "The length of the consumed data differs from expected",
0652: 0, result.bytesConsumed());
0653: assertTrue(
0654: "The length of the produced data differs from expected",
0655: result.bytesProduced() > 0);
0656:
0657: assertTrue("Outbound should be closed.", server
0658: .isOutboundDone());
0659: assertTrue("Inbound should be closed.", server
0660: .isInboundDone());
0661:
0662: buffer.flip();
0663: try {
0664: if (doLog) {
0665: System.out
0666: .println("\nClient unwraps the fatal alert");
0667: }
0668: print(client.unwrap(buffer, app_data_buffer));
0669: fail("Expected exception was not thrown.");
0670: } catch (Exception ex) {
0671: if (doLog) {
0672: System.out
0673: .println("\nClient rethrew the exception: "
0674: + ex.getMessage());
0675: }
0676: // NOT_HANDSHAKING..
0677: assertEquals(
0678: "Unexpected status of operation:",
0679: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0680: client.getHandshakeStatus());
0681: client.closeOutbound();
0682: // NEED_WRAP.. should it be so? it contradicts to the TLS spec:
0683: // "Upon transmission or receipt of an fatal alert message, both
0684: // parties immediately close the connection. Servers and clients
0685: // are required to forget any session-identifiers, keys, and
0686: // secrets associated with a failed connection."
0687: // So in this case we expect NOT_HANDSHAKING
0688: assertEquals(
0689: "Unexpected status of operation:",
0690: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
0691: client.getHandshakeStatus());
0692: assertTrue("Outbound should be closed.", client
0693: .isOutboundDone());
0694: assertTrue("Inbound should be closed.", client
0695: .isInboundDone());
0696: }
0697: }
0698: }
0699:
0700: // --------------------------------------------------------------------
0701: // ------------------------ Staff methods -----------------------------
0702: // --------------------------------------------------------------------
0703:
0704: /*
0705: * Performs the handshake over the specified engines
0706: */
0707: private void doHandshake(SSLEngine client, SSLEngine server)
0708: throws Exception {
0709: if (doLog) {
0710: System.out.println("\n--- doHandshake:");
0711: System.out.println("Server: "
0712: + server.getSession().getClass());
0713: System.out.println("Client: "
0714: + client.getSession().getClass());
0715: }
0716:
0717: client.beginHandshake();
0718: server.beginHandshake();
0719:
0720: doHandshakeImpl(client, server);
0721: }
0722:
0723: /*
0724: * Performs the handshake over the specified engines.
0725: * Note that method passes app data between the engines during
0726: * the handshake process.
0727: */
0728: private void doHandshakeImpl(SSLEngine client, SSLEngine server)
0729: throws Exception {
0730: if (doLog) {
0731: System.out.println("\n--- doHandshakeImpl:");
0732: System.out.println("Client's hsh status: "
0733: + client.getHandshakeStatus());
0734: System.out.println("Client's session: "
0735: + client.getSession());
0736: System.out.println("Server's hsh status: "
0737: + server.getHandshakeStatus());
0738: System.out.println("Server's session: "
0739: + server.getSession());
0740: }
0741:
0742: int packetBufferSize = client.getSession()
0743: .getPacketBufferSize();
0744: int applicationBufferSize = server.getSession()
0745: .getApplicationBufferSize();
0746:
0747: // buffer will contain handshake messages
0748: ByteBuffer clients_buffer = ByteBuffer
0749: .allocate(packetBufferSize + 1000);
0750: ByteBuffer servers_buffer = ByteBuffer
0751: .allocate(packetBufferSize + 1000);
0752: // buffers will contain application data messages
0753: ByteBuffer app_data = ByteBuffer.allocate(packetBufferSize);
0754: ByteBuffer app_data_plain = ByteBuffer
0755: .allocate(applicationBufferSize);
0756:
0757: SSLEngine[] engines = new SSLEngine[] { client, server };
0758: ByteBuffer[] buffers = new ByteBuffer[] { clients_buffer,
0759: servers_buffer };
0760:
0761: // choose which peer will start handshake negotiation
0762: // (initial handshake is initiated by client, but rehandshake
0763: // can be initiated by any peer)
0764: int step = (client.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) ? 0
0765: : 1;
0766:
0767: SSLEngine current_engine = engines[step];
0768: ByteBuffer buffer;
0769: SSLEngineResult result = null;
0770: SSLEngineResult.HandshakeStatus status;
0771:
0772: while ((client.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)
0773: || (server.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING)) {
0774: if (doLog) {
0775: System.out.print("\n"
0776: + ((current_engine == client) ? "CLIENT "
0777: : "SERVER "));
0778: }
0779: status = current_engine.getHandshakeStatus();
0780: if (status == SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
0781: // so another peer produced
0782: // the handshaking data which has to be unwrapped
0783: if (doLog) {
0784: System.out.print("(NOT_HANDSHAKING) ");
0785: }
0786: status = SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
0787: }
0788: if (status == SSLEngineResult.HandshakeStatus.NEED_WRAP) {
0789: if (doLog) {
0790: System.out.println("NEED_WRAP");
0791: }
0792: // will wrap handshake data into its special buffer
0793: buffer = buffers[step];
0794: if (buffer.remaining() == 0) {
0795: // handshake data was fully read by another peer,
0796: // so we need clear the buffer before reusing it
0797: buffer.clear();
0798: }
0799: // wrap the next handshake message
0800: print(result = current_engine.wrap(app_data, buffer));
0801: // if there are no any messages to send, switch the engine
0802: if (current_engine.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NEED_WRAP) {
0803: // switch the current engine
0804: step ^= 1;
0805: current_engine = engines[step];
0806: // and prepare the buffer for reading
0807: buffer.flip();
0808: }
0809: } else if (status == SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
0810: if (doLog) {
0811: System.out.println("NEED_UNWRAP");
0812: }
0813:
0814: // If there are no unread handshake messages produced by the
0815: // current engine, try to wrap the application data and unwrap
0816: // it by another engine. It will test app data flow during
0817: // the rehandshake.
0818: if (!buffers[step].hasRemaining()) {
0819: if (doLog) {
0820: System.out
0821: .println("\nTry to WRAP the application data");
0822: }
0823: print(result = current_engine.wrap(ByteBuffer
0824: .wrap(new byte[] { 0 }), app_data));
0825: // The output in app_data will be produced only if it
0826: // is rehandshaking stage
0827: // (i.e. initial handshake has been done)
0828: if (result.bytesProduced() > 0) {
0829: // if the app data message has been produced,
0830: // unwrap it by another peer
0831: if (doLog) {
0832: System.out
0833: .print("\n"
0834: + ((current_engine != client) ? "CLIENT "
0835: : "SERVER "));
0836: System.out
0837: .println("UNWRAPs app data sent during handshake");
0838: }
0839: app_data.flip();
0840: print(result = engines[(step + 1) % 2].unwrap(
0841: app_data, app_data_plain));
0842: app_data.clear();
0843: app_data_plain.clear();
0844: }
0845: }
0846:
0847: buffer = buffers[step ^ 1];
0848:
0849: // check if there is handshake data to be unwrapped
0850: if (buffer.remaining() == 0) {
0851: if (doLog) {
0852: System.out
0853: .println("There is no handshake data to be unwrapped.");
0854: }
0855: // switch the current engine
0856: step ^= 1;
0857: current_engine = engines[step];
0858: if ((current_engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP)
0859: && (buffers[step ^ 1].remaining() == 0)) {
0860: System.out
0861: .println("Both engines are in NEED_UNWRAP state");
0862: fail("Both engines are in NEED_UNWRAP state");
0863: }
0864: continue;
0865: }
0866:
0867: print(result = current_engine.unwrap(buffer, app_data));
0868: if (current_engine.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_TASK) {
0869: if (doLog) {
0870: System.out.println("NEED_TASK");
0871: }
0872: current_engine.getDelegatedTask().run();
0873: if (doLog) {
0874: System.out.println("status after the task: "
0875: + current_engine.getHandshakeStatus());
0876: }
0877: }
0878: } else {
0879: fail("Unexpected HandshakeStatus: " + status);
0880: }
0881: assertEquals("Unexpected status of operation:",
0882: SSLEngineResult.Status.OK, result.getStatus());
0883: }
0884: }
0885:
0886: /*
0887: * Performs the session renegotiation process when one
0888: * of the peers is not allowed to create the session.
0889: */
0890: private void doNoRenegotiationTest(SSLEngine allowed,
0891: SSLEngine not_allowed, boolean is_initial) throws Exception {
0892: if (doLog) {
0893: System.out
0894: .println("\n--- doNoRenegotiationTest: is_initial: "
0895: + is_initial);
0896: }
0897:
0898: not_allowed.setEnableSessionCreation(false);
0899: not_allowed.getSession().invalidate();
0900:
0901: int packetBufferSize = allowed.getSession()
0902: .getPacketBufferSize();
0903: int applicationBufferSize = not_allowed.getSession()
0904: .getApplicationBufferSize();
0905:
0906: // buffer will contain handshake messages
0907: ByteBuffer buffer = ByteBuffer
0908: .allocate(packetBufferSize + 1000);
0909: // buffers will contain application data messages
0910: ByteBuffer app_data = ByteBuffer.allocate(packetBufferSize);
0911: ByteBuffer app_data_plain = ByteBuffer
0912: .allocate(applicationBufferSize);
0913:
0914: SSLEngineResult result = null;
0915:
0916: allowed.beginHandshake();
0917: //not_allowed.beginHandshake();
0918:
0919: if (doLog) {
0920: System.out
0921: .println("\nAllowed peer wraps the initial session negotiation message");
0922: }
0923: // wrap the initial session negotiation message
0924: while (allowed.getHandshakeStatus().equals(
0925: SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
0926: print(result = allowed.wrap(app_data_plain, buffer));
0927: assertTrue("Engine did not produce any data", result
0928: .bytesProduced() > 0);
0929: }
0930: // prepare the buffer for reading
0931: buffer.flip();
0932: if (doLog) {
0933: System.out.println("\nNot allowed unwraps the message");
0934: }
0935: try {
0936: // unwrap the message. expecting whether SSLException or NEED_WRAP
0937: print(result = not_allowed.unwrap(buffer, app_data_plain));
0938: } catch (SSLException e) {
0939: if (is_initial) {
0940: return; // ok, exception was thrown
0941: } else {
0942: fail("Unexpected SSLException was thrown " + e);
0943: }
0944: }
0945: // if it is not an initial handshake phase it is posible
0946: // SSLException to be thrown.
0947: try {
0948: while (!not_allowed.getHandshakeStatus().equals(
0949: SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
0950: assertTrue("Engine did not consume any data", result
0951: .bytesConsumed() > 0);
0952: if (not_allowed.getHandshakeStatus().equals(
0953: SSLEngineResult.HandshakeStatus.NEED_TASK)) {
0954: not_allowed.getDelegatedTask().run();
0955: if (doLog) {
0956: System.out.println("Status after the task: "
0957: + not_allowed.getHandshakeStatus());
0958: }
0959: continue;
0960: } else if (not_allowed.getHandshakeStatus().equals(
0961: SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
0962: print(result = not_allowed.unwrap(buffer,
0963: app_data_plain));
0964: } else {
0965: fail("Unexpected status of operation: "
0966: + not_allowed.getHandshakeStatus());
0967: }
0968: }
0969: // prepare for writting
0970: buffer.clear();
0971: if (doLog) {
0972: System.out
0973: .println("\nWrapping the message. Expecting no_renegotiation alert");
0974: }
0975: // wrapping the message. expecting no_renegotiation alert
0976: print(result = not_allowed.wrap(app_data_plain, buffer));
0977: } catch (SSLException e) {
0978: if (!is_initial) {
0979: fail("Unexpected SSLException was thrown."
0980: + e.getMessage());
0981: }
0982: if (doLog) {
0983: System.out
0984: .println("Throwed exception during the unwrapping "
0985: + "of handshake initiation message:");
0986: e.printStackTrace();
0987: System.out.println("Handshake Status: "
0988: + not_allowed.getHandshakeStatus());
0989: }
0990: if (not_allowed.getHandshakeStatus().equals(
0991: SSLEngineResult.HandshakeStatus.NEED_WRAP)) {
0992: // needs to wrap fatal alert message
0993: if (doLog) {
0994: System.out
0995: .println("\nnot_allowed wraps fatal alert message");
0996: }
0997: // prepare for writting
0998: buffer.clear();
0999: print(result = not_allowed.wrap(app_data_plain, buffer));
1000: }
1001: }
1002: // check whether alert message has been sent
1003: assertTrue("Engine did not produce any data", result
1004: .bytesProduced() > 0);
1005: // check whether not_allowed engine stoped handshake operation
1006: assertEquals(
1007: "Unexpected status of operation: not_allowed "
1008: + "to session creation peer did not stop its handshake process",
1009: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1010: not_allowed.getHandshakeStatus());
1011: // prepare for reading
1012: buffer.flip();
1013: try {
1014: print(result = allowed.unwrap(buffer, app_data_plain));
1015: assertTrue("Engine did not consume any data", result
1016: .bytesConsumed() > 0);
1017: assertEquals(
1018: "Responce from the peer not allowed to create "
1019: + "the session did not cause the stopping of "
1020: + "the session negotiation process",
1021: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING,
1022: result.getHandshakeStatus());
1023: } catch (SSLException e) {
1024: if (!is_initial) {
1025: fail("Unexpected SSLException was thrown."
1026: + e.getMessage());
1027: }
1028: if (doLog) {
1029: System.out
1030: .println("Throwed exception during the unwrapping "
1031: + "of responce from allowed peer:");
1032: e.printStackTrace();
1033: System.out.println("Handshake Status: "
1034: + not_allowed.getHandshakeStatus());
1035: }
1036: }
1037: }
1038:
1039: /*
1040: * Tests the data exchange process between two engines
1041: */
1042: private void doDataExchange(SSLEngine client, SSLEngine server)
1043: throws Exception {
1044: if (doLog) {
1045: System.out.println("\n--- doDataExchange:");
1046: }
1047: ByteBuffer co = ByteBuffer.allocate(client.getSession()
1048: .getPacketBufferSize());
1049: ByteBuffer si = ByteBuffer.allocate(server.getSession()
1050: .getPacketBufferSize());
1051: SSLEngineResult result;
1052:
1053: String data_2b_sent = "data to be sent";
1054: ByteBuffer data = ByteBuffer.wrap(data_2b_sent.getBytes());
1055:
1056: if (doLog) {
1057: System.out
1058: .println("\nTry to wrap the data into small buffer");
1059: }
1060: print(result = client.wrap(data, ByteBuffer.allocate(35)));
1061: assertEquals("Unexpected status of operation:",
1062: SSLEngineResult.Status.BUFFER_OVERFLOW, result
1063: .getStatus());
1064:
1065: if (doLog) {
1066: System.out.println("\nWrapping the data of length "
1067: + data.remaining());
1068: }
1069: print(result = client.wrap(data, co));
1070: assertEquals("Unexpected status of operation:",
1071: SSLEngineResult.Status.OK, result.getStatus());
1072:
1073: // tune the buffer to read from it
1074: co.limit(co.position());
1075: co.rewind();
1076:
1077: if (doLog) {
1078: System.out
1079: .println("\nTry to unwrap the data into small buffer");
1080: }
1081: print(result = server.unwrap(co, ByteBuffer.allocate(0)));
1082: assertEquals("Unexpected status of operation:",
1083: SSLEngineResult.Status.BUFFER_OVERFLOW, result
1084: .getStatus());
1085: if (doLog) {
1086: System.out.println("\nUnwrapping the data into buffer");
1087: }
1088: print(result = server.unwrap(co, si));
1089: assertEquals("Unexpected status of operation:",
1090: SSLEngineResult.Status.OK, result.getStatus());
1091: assertEquals(
1092: "The length of the received data differs from expected",
1093: "data to be sent".length(), result.bytesProduced());
1094:
1095: // take the data from the buffer
1096: byte[] resulting_data = new byte[result.bytesProduced()];
1097: si.rewind();
1098: si.get(resulting_data);
1099: si.clear();
1100: assertTrue(Arrays.equals(data_2b_sent.getBytes(),
1101: resulting_data));
1102:
1103: co.clear();
1104: for (int i = 1; i < 10; i++) {
1105: byte[] buff = new byte[i];
1106: data = ByteBuffer.wrap(buff);
1107: if (doLog) {
1108: System.out.println("\nWrap the data");
1109: }
1110: print(result = client.wrap(data, co));
1111: assertEquals("Unexpected status of operation:",
1112: SSLEngineResult.Status.OK, result.getStatus());
1113: if (doLog) {
1114: System.out.println("\nUnwrap the data");
1115: }
1116: co.rewind();
1117: print(result = server.unwrap(co, si));
1118: assertEquals("Unexpected status of operation:",
1119: SSLEngineResult.Status.OK, result.getStatus());
1120: assertEquals(
1121: "The length of the received data differs from expected",
1122: i, result.bytesProduced());
1123: resulting_data = new byte[i];
1124: si.rewind();
1125: si.get(resulting_data);
1126: si.clear();
1127: assertTrue(Arrays.equals(buff, resulting_data));
1128: co.clear();
1129: si.clear();
1130: }
1131: }
1132:
1133: /*
1134: * Performs the closure process over the two communicationg engines.
1135: * The handshake process should be performed before the call of this
1136: * method.
1137: */
1138: private void doClose(SSLEngine client, SSLEngine server)
1139: throws Exception {
1140: if (doLog) {
1141: System.out.println("\n--- doClose: ");
1142: }
1143: ByteBuffer buffer = ByteBuffer.allocate(
1144: // +100 because we put the data into the buffer multiple times
1145: server.getSession().getPacketBufferSize() + 100);
1146: ByteBuffer app_data_buffer = ByteBuffer.allocate(client
1147: .getSession().getApplicationBufferSize());
1148: SSLEngineResult result;
1149: // first: send 0 just for fun
1150: if (doLog) {
1151: System.out.println("\nServer sends pending outboud data:");
1152: }
1153: print(result = server.wrap(ByteBuffer.wrap(new byte[] { 0 }),
1154: buffer));
1155: assertEquals("Unexpected status of operation:",
1156: SSLEngineResult.Status.OK, result.getStatus());
1157: assertEquals("Unexpected status of operation:",
1158: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1159: .getHandshakeStatus());
1160: // second: initiate a close
1161: if (doLog) {
1162: System.out.println("\nServer initiates a closure:");
1163: }
1164: server.closeOutbound();
1165: // should do nothing:
1166: server.closeOutbound();
1167:
1168: assertEquals("Unexpected status of operation:",
1169: SSLEngineResult.HandshakeStatus.NEED_WRAP, server
1170: .getHandshakeStatus());
1171:
1172: // will cause SSLException because closure alert was not received yet:
1173: // server.closeInbound();
1174:
1175: // wrap closure alert (previosly sent 0 should not be lost)
1176: print(result = server.wrap(ByteBuffer.allocate(0), buffer));
1177: assertEquals("Unexpected status of operation:",
1178: SSLEngineResult.Status.CLOSED, result.getStatus());
1179: assertEquals("Unexpected status of operation:",
1180: SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result
1181: .getHandshakeStatus());
1182:
1183: if (doLog) {
1184: System.out
1185: .println("\nServer sends pending outboud data again:");
1186: }
1187: // will do nothing because closure alert has been sent
1188: // and outbound has been closed
1189: print(result = server.wrap(ByteBuffer.wrap(new byte[] { 0 }),
1190: buffer));
1191: assertEquals("Unexpected status of operation:",
1192: SSLEngineResult.Status.CLOSED, result.getStatus());
1193: assertEquals("Unexpected status of operation:",
1194: SSLEngineResult.HandshakeStatus.NEED_UNWRAP, result
1195: .getHandshakeStatus());
1196: assertEquals(
1197: "The length of the consumed data differs from expected",
1198: 0, result.bytesConsumed());
1199: assertEquals(
1200: "The length of the produced data differs from expected",
1201: 0, result.bytesProduced());
1202:
1203: // prepare the buffer for reading
1204: buffer.flip();
1205:
1206: if (doLog) {
1207: System.out
1208: .println("\nClient receives pending servers' outbound data");
1209: }
1210: print(result = client.unwrap(buffer, app_data_buffer));
1211: assertEquals("Unexpected status of operation:",
1212: SSLEngineResult.Status.OK, result.getStatus());
1213: assertEquals("Unexpected status of operation:",
1214: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1215: .getHandshakeStatus());
1216: assertEquals(
1217: "The length of the produced data differs from expected",
1218: 1, result.bytesProduced());
1219:
1220: app_data_buffer.clear();
1221:
1222: if (doLog) {
1223: System.out.println("\nClient receives close notify");
1224: }
1225: print(result = client.unwrap(buffer, app_data_buffer));
1226: assertEquals("Unexpected status of operation:",
1227: SSLEngineResult.Status.CLOSED, result.getStatus());
1228: assertEquals("Unexpected status of operation:",
1229: SSLEngineResult.HandshakeStatus.NEED_WRAP, result
1230: .getHandshakeStatus());
1231: assertTrue(
1232: "The length of the consumed data differs from expected",
1233: result.bytesConsumed() > 0);
1234: assertEquals(
1235: "The length of the received data differs from expected",
1236: 0, result.bytesProduced());
1237:
1238: // prepare the buffer for writing
1239: app_data_buffer.clear();
1240:
1241: // it's needless, but should work (don't cause exceptions):
1242: client.closeInbound();
1243: client.closeOutbound();
1244:
1245: if (doLog) {
1246: System.out.println("\nClient tries to read data again");
1247: }
1248: // CLOSED, 0 consumed, 0 produced
1249: print(result = client.unwrap(buffer, app_data_buffer));
1250: assertEquals("Unexpected status of operation:",
1251: SSLEngineResult.Status.CLOSED, result.getStatus());
1252: assertEquals("Unexpected status of operation:",
1253: SSLEngineResult.HandshakeStatus.NEED_WRAP, result
1254: .getHandshakeStatus());
1255: assertEquals(
1256: "The length of the consumed data differs from expected",
1257: 0, result.bytesConsumed());
1258: assertEquals(
1259: "The length of the received data differs from expected",
1260: 0, result.bytesProduced());
1261:
1262: // prepare the buffer for writing
1263: buffer.clear();
1264:
1265: if (doLog) {
1266: System.out
1267: .println("\nClient sends responding close notify");
1268: }
1269: print(result = client.wrap(ByteBuffer.wrap(new byte[] { 0 }),
1270: buffer));
1271: assertEquals("Unexpected status of operation:",
1272: SSLEngineResult.Status.CLOSED, result.getStatus());
1273: assertEquals("Unexpected status of operation:",
1274: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1275: .getHandshakeStatus());
1276: assertEquals(
1277: "The length of the consumed data differs from expected",
1278: 0, result.bytesConsumed());
1279: assertTrue(
1280: "The length of the produced data differs from expected",
1281: result.bytesProduced() > 0);
1282: if (doLog) {
1283: System.out
1284: .println("\nClient tries to send data after closure alert");
1285: }
1286: // this data will not be sent (should do nothing - 0 cons, 0 prod)
1287: print(result = client.wrap(ByteBuffer.wrap(new byte[] { 0 }),
1288: buffer));
1289: assertEquals("Unexpected status of operation:",
1290: SSLEngineResult.Status.CLOSED, result.getStatus());
1291: assertEquals("Unexpected status of operation:",
1292: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1293: .getHandshakeStatus());
1294: assertEquals(
1295: "The length of the consumed data differs from expected",
1296: 0, result.bytesConsumed());
1297: assertEquals(
1298: "The length of the produced data differs from expected",
1299: 0, result.bytesProduced());
1300:
1301: // prepare the buffers for reading
1302: app_data_buffer.clear();
1303: buffer.flip();
1304:
1305: if (doLog) {
1306: System.out.println("\nServer receives close notify");
1307: }
1308: print(result = server.unwrap(buffer, app_data_buffer));
1309: assertEquals("Unexpected status of operation:",
1310: SSLEngineResult.Status.CLOSED, result.getStatus());
1311: assertEquals("Unexpected status of operation:",
1312: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1313: .getHandshakeStatus());
1314: assertTrue(
1315: "The length of the consumed data differs from expected",
1316: result.bytesConsumed() > 0);
1317: assertEquals(
1318: "The length of the produced data differs from expected",
1319: 0, result.bytesProduced());
1320:
1321: if (doLog) {
1322: System.out.println("\nServer tries to read after closure");
1323: }
1324: // will be ignored
1325: print(result = server.unwrap(buffer, app_data_buffer));
1326: assertEquals("Unexpected status of operation:",
1327: SSLEngineResult.Status.CLOSED, result.getStatus());
1328: assertEquals("Unexpected status of operation:",
1329: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1330: .getHandshakeStatus());
1331: assertEquals(
1332: "The length of the consumed data differs from expected",
1333: 0, result.bytesConsumed());
1334: assertEquals(
1335: "The length of the produced data differs from expected",
1336: 0, result.bytesProduced());
1337:
1338: // it's needless, but should work:
1339: client.closeInbound();
1340: // will be ignored
1341:
1342: if (doLog) {
1343: System.out.println("\nServer tries to write after closure");
1344: }
1345: buffer.clear();
1346: print(result = server.wrap(ByteBuffer.allocate(0), buffer));
1347: assertEquals("Unexpected status of operation:",
1348: SSLEngineResult.Status.CLOSED, result.getStatus());
1349: assertEquals("Unexpected status of operation:",
1350: SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING, result
1351: .getHandshakeStatus());
1352: assertEquals(
1353: "The length of the consumed data differs from expected",
1354: 0, result.bytesConsumed());
1355: assertEquals(
1356: "The length of the produced data differs from expected",
1357: 0, result.bytesProduced());
1358: }
1359:
1360: private static void print(SSLEngineResult result) {
1361: if (doLog) {
1362: System.out.println("result:\n" + result);
1363: }
1364: }
1365:
1366: /**
1367: * Returns the engine to be tested.
1368: */
1369: private SSLEngine getEngine() throws Exception {
1370: return JSSETestData.getContext().createSSLEngine("localhost",
1371: 2345);
1372: }
1373:
1374: /**
1375: * Initializes the engines.
1376: */
1377: private void initEngines(SSLEngine client, SSLEngine server) {
1378: String prefix = "TLS_";
1379:
1380: client.setEnabledProtocols(new String[] { "TLSv1" });
1381: server.setEnabledProtocols(new String[] { "TLSv1" });
1382: client.setEnabledCipherSuites(new String[] { prefix
1383: + cipher_suites[0] });
1384: server.setEnabledCipherSuites(new String[] { prefix
1385: + cipher_suites[0] });
1386:
1387: client.setUseClientMode(true);
1388: server.setUseClientMode(false);
1389: }
1390:
1391: public static Test suite() {
1392: return new TestSuite(SSLEngineImplTest.class);
1393: }
1394:
1395: public static void main(String[] args) throws Exception {
1396: junit.textui.TestRunner.run(suite());
1397: }
1398: }
|