Path: blob/master/test/jdk/javax/net/ssl/SSLEngine/ConnectionTest.java
41152 views
/*1* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 449574226* @summary Add non-blocking SSL/TLS functionality, usable with any27* I/O abstraction28* @ignore the dependent implementation details are changed29* @author Brad Wetmore30*31* @run main/othervm ConnectionTest32*/3334/*35* This is a bit hacky, meant to test various conditions. The main36* thing I wanted to do with this was to do buffer reads/writes37* when buffers were not empty. (buffer.position() = 10)38* The code could certainly be tightened up a lot.39*/40import javax.net.ssl.*;41import javax.net.ssl.SSLEngineResult.*;42import java.io.*;43import java.security.*;44import java.nio.*;4546public class ConnectionTest {4748private SSLContext sslc;49private SSLEngine ssle1;50private SSLEngine ssle2;5152private static String pathToStores = "../etc";53private static String keyStoreFile = "keystore";54private static String trustStoreFile = "truststore";55private static String passwd = "passphrase";5657private static String keyFilename =58System.getProperty("test.src", "./") + "/" + pathToStores +59"/" + keyStoreFile;60private static String trustFilename =61System.getProperty("test.src", "./") + "/" + pathToStores +62"/" + trustStoreFile;6364private ByteBuffer appIn1, appOut1;65private ByteBuffer appIn2, appOut2;66private ByteBuffer oneToTwo, twoToOne;67private ByteBuffer emptyBuffer;6869private ByteBuffer oneToTwoShifter, twoToOneShifter;7071private String hostname = "hostname";72private int portNumber = 77;7374public ConnectionTest()75throws Exception {7677sslc = getSSLContext();78ssle1 = sslc.createSSLEngine(hostname, portNumber);79ssle2 = sslc.createSSLEngine();8081ssle1.setEnabledCipherSuites(new String [] {82"SSL_RSA_WITH_RC4_128_MD5"});8384ssle2.setEnabledCipherSuites(new String [] {85"SSL_RSA_WITH_RC4_128_MD5"});8687createBuffers();88}8990private SSLContext getSSLContext() throws Exception {91KeyStore ks = KeyStore.getInstance("JKS");92KeyStore ts = KeyStore.getInstance("JKS");93char[] passphrase = "passphrase".toCharArray();9495ks.load(new FileInputStream(keyFilename), passphrase);96ts.load(new FileInputStream(trustFilename), passphrase);9798KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");99kmf.init(ks, passphrase);100101TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");102tmf.init(ts);103104SSLContext sslCtx = SSLContext.getInstance("TLS");105106sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);107108return sslCtx;109}110111private void createBuffers() {112// Size the buffers as appropriate.113SSLSession session = ssle1.getSession();114int appBufferMax = session.getApplicationBufferSize();115int netBufferMax = session.getPacketBufferSize();116117appIn1 = ByteBuffer.allocateDirect(appBufferMax + 10);118appIn2 = ByteBuffer.allocateDirect(appBufferMax + 10);119120appIn1.position(10);121appIn2.position(10);122123oneToTwo = ByteBuffer.allocateDirect(netBufferMax + 10);124twoToOne = ByteBuffer.allocateDirect(netBufferMax + 10);125126oneToTwo.position(10);127twoToOne.position(10);128oneToTwoShifter = oneToTwo.slice();129twoToOneShifter = twoToOne.slice();130131appOut1 = ByteBuffer.wrap("Hi Engine2, I'm SSLEngine1".getBytes());132appOut2 = ByteBuffer.wrap("Hello Engine1, I'm SSLEngine2".getBytes());133134emptyBuffer = ByteBuffer.allocate(10);135emptyBuffer.limit(5);136emptyBuffer.position(emptyBuffer.limit());137138System.out.println("AppOut1 = " + appOut1);139System.out.println("AppOut2 = " + appOut2);140System.out.println();141}142143private void checkResult(SSLEngineResult result, Status status,144HandshakeStatus hsStatus, int consumed, int produced,145boolean done) throws Exception {146147if ((status != null) && (result.getStatus() != status)) {148throw new Exception("Unexpected Status: need = " + status +149" got = " + result.getStatus());150}151152if ((hsStatus != null) && (result.getHandshakeStatus() != hsStatus)) {153throw new Exception("Unexpected hsStatus: need = " + hsStatus +154" got = " + result.getHandshakeStatus());155}156157if ((consumed != -1) && (consumed != result.bytesConsumed())) {158throw new Exception("Unexpected consumed: need = " + consumed +159" got = " + result.bytesConsumed());160}161162if ((produced != -1) && (produced != result.bytesProduced())) {163throw new Exception("Unexpected produced: need = " + produced +164" got = " + result.bytesProduced());165}166167if (done && (hsStatus == HandshakeStatus.FINISHED)) {168throw new Exception(169"Handshake already reported finished");170}171172}173174private boolean isHandshaking(SSLEngine e) {175return (e.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING);176}177178private void test() throws Exception {179ssle1.setUseClientMode(true);180ssle2.setUseClientMode(false);181ssle2.setNeedClientAuth(true);182183System.out.println("Testing for early unwrap/wrap");184SSLEngineResult result1 = ssle1.unwrap(twoToOne, appIn1);185SSLEngineResult result2 = ssle2.wrap(appOut2, oneToTwo);186187/*188* These should not consume/produce data, because they189* are client and server, respectively, and don't190* start handshaking this way.191*/192checkResult(result1, Status.OK, HandshakeStatus.NEED_WRAP,1930, 0, false);194checkResult(result2, Status.OK, HandshakeStatus.NEED_UNWRAP,1950, 0, false);196197System.out.println("Doing Initial Handshake");198199boolean done1 = false;200boolean done2 = false;201202/*203* Do initial handshaking204*/205while (isHandshaking(ssle1) ||206isHandshaking(ssle2)) {207208System.out.println("================");209210result1 = ssle1.wrap(emptyBuffer, oneToTwo);211checkResult(result1, null, null, 0, -1, done1);212result2 = ssle2.wrap(emptyBuffer, twoToOne);213checkResult(result2, null, null, 0, -1, done2);214215if (result1.getHandshakeStatus() == HandshakeStatus.FINISHED) {216done1 = true;217}218219if (result2.getHandshakeStatus() == HandshakeStatus.FINISHED) {220done2 = true;221}222223System.out.println("wrap1 = " + result1);224System.out.println("wrap2 = " + result2);225226if (result1.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {227Runnable runnable;228while ((runnable = ssle1.getDelegatedTask()) != null) {229runnable.run();230}231}232233if (result2.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {234Runnable runnable;235while ((runnable = ssle2.getDelegatedTask()) != null) {236runnable.run();237}238}239240oneToTwo.flip();241twoToOne.flip();242243oneToTwo.position(10);244twoToOne.position(10);245246System.out.println("----");247248result1 = ssle1.unwrap(twoToOne, appIn1);249checkResult(result1, null, null, -1, 0, done1);250result2 = ssle2.unwrap(oneToTwo, appIn2);251checkResult(result2, null, null, -1, 0, done2);252253if (result1.getHandshakeStatus() == HandshakeStatus.FINISHED) {254done1 = true;255}256257if (result2.getHandshakeStatus() == HandshakeStatus.FINISHED) {258done2 = true;259}260261if (result1.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {262Runnable runnable;263while ((runnable = ssle1.getDelegatedTask()) != null) {264runnable.run();265}266}267268if (result2.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {269Runnable runnable;270while ((runnable = ssle2.getDelegatedTask()) != null) {271runnable.run();272}273}274275System.out.println("unwrap1 = " + result1);276System.out.println("unwrap2 = " + result2);277278oneToTwoShifter.position(oneToTwo.position() - 10);279oneToTwoShifter.limit(oneToTwo.limit() - 10);280twoToOneShifter.position(twoToOne.position() - 10);281twoToOneShifter.limit(twoToOne.limit() - 10);282oneToTwoShifter.compact();283twoToOneShifter.compact();284oneToTwo.position(oneToTwoShifter.position() + 10);285oneToTwo.limit(oneToTwoShifter.limit() + 10);286twoToOne.position(twoToOneShifter.position() + 10);287twoToOne.limit(twoToOneShifter.limit() + 10);288}289290System.out.println("\nDONE HANDSHAKING");291System.out.println("================");292293if (!done1 || !done2) {294throw new Exception("Both should be true:\n" +295" done1 = " + done1 + " done2 = " + done2);296}297298String host = ssle1.getPeerHost();299int port = ssle1.getPeerPort();300if (!host.equals(hostname) || (port != portNumber)) {301throw new Exception("unexpected host/port " + host + ":" + port);302}303304host = ssle2.getPeerHost();305port = ssle2.getPeerPort();306if ((host != null) || (port != -1)) {307throw new Exception("unexpected host/port " + host + ":" + port);308}309310SSLSession ssls1 = ssle1.getSession();311312host = ssls1.getPeerHost();313port = ssls1.getPeerPort();314if (!host.equals(hostname) || (port != portNumber)) {315throw new Exception("unexpected host/port " + host + ":" + port);316}317318SSLSession ssls2 = ssle2.getSession();319320host = ssls2.getPeerHost();321port = ssls2.getPeerPort();322if ((host != null) || (port != -1)) {323throw new Exception("unexpected host/port " + host + ":" + port);324}325326/*327* Should be able to write/read a small buffer like this.328*/329int appOut1Len = appOut1.remaining();330int appOut2Len = appOut2.remaining();331int net1Len;332int net2Len;333334result1 = ssle1.wrap(appOut1, oneToTwo);335checkResult(result1, Status.OK, HandshakeStatus.NOT_HANDSHAKING,336appOut1Len, -1, false);337result2 = ssle2.wrap(appOut2, twoToOne);338checkResult(result2, Status.OK, HandshakeStatus.NOT_HANDSHAKING,339appOut2Len, -1, false);340net1Len = result1.bytesProduced();341net2Len = result2.bytesProduced();342343System.out.println("wrap1 = " + result1);344System.out.println("wrap2 = " + result2);345346oneToTwo.flip();347twoToOne.flip();348349oneToTwo.position(10);350twoToOne.position(10);351352System.out.println("----");353354result1 = ssle1.unwrap(twoToOne, appIn1);355checkResult(result1, Status.OK, HandshakeStatus.NOT_HANDSHAKING,356net2Len, appOut2Len, false);357result2 = ssle2.unwrap(oneToTwo, appIn2);358checkResult(result2, Status.OK, HandshakeStatus.NOT_HANDSHAKING,359net1Len, appOut1Len, false);360361System.out.println("unwrap1 = " + result1);362System.out.println("unwrap2 = " + result2);363364oneToTwoShifter.position(oneToTwo.position() - 10);365oneToTwoShifter.limit(oneToTwo.limit() - 10);366twoToOneShifter.position(twoToOne.position() - 10);367twoToOneShifter.limit(twoToOne.limit() - 10);368oneToTwoShifter.compact();369twoToOneShifter.compact();370oneToTwo.position(oneToTwoShifter.position() + 10);371oneToTwo.limit(oneToTwoShifter.limit() + 10);372twoToOne.position(twoToOneShifter.position() + 10);373twoToOne.limit(twoToOneShifter.limit() + 10);374375ssls2.invalidate();376ssle2.beginHandshake();377378System.out.println("\nRENEGOTIATING");379System.out.println("=============");380381done1 = false;382done2 = false;383384appIn1.clear();385appIn2.clear();386387/*388* Do a quick test to see if this can do a switch389* into client mode, at this point, you shouldn't be able390* to switch back.391*/392try {393System.out.println("Try to change client mode");394ssle2.setUseClientMode(true);395throw new Exception("Should have thrown IllegalArgumentException");396} catch (IllegalArgumentException e) {397System.out.println("Caught correct IllegalArgumentException");398}399400while (isHandshaking(ssle1) ||401isHandshaking(ssle2)) {402403System.out.println("================");404405result1 = ssle1.wrap(emptyBuffer, oneToTwo);406checkResult(result1, null, null, 0, -1, done1);407result2 = ssle2.wrap(emptyBuffer, twoToOne);408checkResult(result2, null, null, 0, -1, done2);409410if (result1.getHandshakeStatus() == HandshakeStatus.FINISHED) {411done1 = true;412}413414if (result2.getHandshakeStatus() == HandshakeStatus.FINISHED) {415done2 = true;416}417418System.out.println("wrap1 = " + result1);419System.out.println("wrap2 = " + result2);420421if (result1.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {422Runnable runnable;423while ((runnable = ssle1.getDelegatedTask()) != null) {424runnable.run();425}426}427428if (result2.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {429Runnable runnable;430while ((runnable = ssle2.getDelegatedTask()) != null) {431runnable.run();432}433}434435oneToTwo.flip();436twoToOne.flip();437438oneToTwo.position(10);439twoToOne.position(10);440441System.out.println("----");442443result1 = ssle1.unwrap(twoToOne, appIn1);444checkResult(result1, null, null, -1, 0, done1);445result2 = ssle2.unwrap(oneToTwo, appIn2);446checkResult(result2, null, null, -1, 0, done2);447448if (result1.getHandshakeStatus() == HandshakeStatus.FINISHED) {449done1 = true;450}451452if (result2.getHandshakeStatus() == HandshakeStatus.FINISHED) {453done2 = true;454}455456System.out.println("unwrap1 = " + result1);457System.out.println("unwrap2 = " + result2);458459if (result1.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {460Runnable runnable;461while ((runnable = ssle1.getDelegatedTask()) != null) {462runnable.run();463}464}465466if (result2.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {467Runnable runnable;468while ((runnable = ssle2.getDelegatedTask()) != null) {469runnable.run();470}471}472473oneToTwoShifter.position(oneToTwo.position() - 10);474oneToTwoShifter.limit(oneToTwo.limit() - 10);475twoToOneShifter.position(twoToOne.position() - 10);476twoToOneShifter.limit(twoToOne.limit() - 10);477oneToTwoShifter.compact();478twoToOneShifter.compact();479oneToTwo.position(oneToTwoShifter.position() + 10);480oneToTwo.limit(oneToTwoShifter.limit() + 10);481twoToOne.position(twoToOneShifter.position() + 10);482twoToOne.limit(twoToOneShifter.limit() + 10);483}484485host = ssle1.getPeerHost();486port = ssle1.getPeerPort();487if (!host.equals(hostname) || (port != portNumber)) {488throw new Exception("unexpected host/port " + host + ":" + port);489}490491host = ssle2.getPeerHost();492port = ssle2.getPeerPort();493if ((host != null) || (port != -1)) {494throw new Exception("unexpected host/port " + host + ":" + port);495}496497SSLSession ssls3 = ssle2.getSession();498499host = ssls1.getPeerHost();500port = ssls1.getPeerPort();501if (!host.equals(hostname) || (port != portNumber)) {502throw new Exception("unexpected host/port " + host + ":" + port);503}504505SSLSession ssls4 = ssle2.getSession();506507host = ssls2.getPeerHost();508port = ssls2.getPeerPort();509if ((host != null) || (port != -1)) {510throw new Exception("unexpected host/port " + host + ":" + port);511}512513System.out.println("\nDoing close");514System.out.println("===========");515516ssle1.closeOutbound();517ssle2.closeOutbound();518519oneToTwo.flip();520twoToOne.flip();521oneToTwo.position(10);522twoToOne.position(10);523524appIn1.clear();525appIn2.clear();526527System.out.println("LAST UNWRAP");528result1 = ssle1.unwrap(twoToOne, appIn1);529checkResult(result1, Status.BUFFER_UNDERFLOW,530HandshakeStatus.NEED_WRAP, 0, 0, false);531result2 = ssle2.unwrap(oneToTwo, appIn2);532checkResult(result2, Status.BUFFER_UNDERFLOW,533HandshakeStatus.NEED_WRAP, 0, 0, false);534535System.out.println("unwrap1 = " + result1);536System.out.println("unwrap2 = " + result2);537538oneToTwoShifter.position(oneToTwo.position() - 10);539oneToTwoShifter.limit(oneToTwo.limit() - 10);540twoToOneShifter.position(twoToOne.position() - 10);541twoToOneShifter.limit(twoToOne.limit() - 10);542oneToTwoShifter.compact();543twoToOneShifter.compact();544oneToTwo.position(oneToTwoShifter.position() + 10);545oneToTwo.limit(oneToTwoShifter.limit() + 10);546twoToOne.position(twoToOneShifter.position() + 10);547twoToOne.limit(twoToOneShifter.limit() + 10);548549System.out.println("LAST WRAP");550result1 = ssle1.wrap(appOut1, oneToTwo);551checkResult(result1, Status.CLOSED, HandshakeStatus.NEED_UNWRAP,5520, -1, false);553result2 = ssle2.wrap(appOut2, twoToOne);554checkResult(result2, Status.CLOSED, HandshakeStatus.NEED_UNWRAP,5550, -1, false);556557System.out.println("wrap1 = " + result1);558System.out.println("wrap2 = " + result2);559560net1Len = result1.bytesProduced();561net2Len = result2.bytesProduced();562563oneToTwo.flip();564twoToOne.flip();565566oneToTwo.position(10);567twoToOne.position(10);568569result1 = ssle1.unwrap(twoToOne, appIn1);570checkResult(result1, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,571net1Len, 0, false);572result2 = ssle2.unwrap(oneToTwo, appIn2);573checkResult(result2, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,574net2Len, 0, false);575576System.out.println("unwrap1 = " + result1);577System.out.println("unwrap2 = " + result2);578579oneToTwoShifter.position(oneToTwo.position() - 10);580oneToTwoShifter.limit(oneToTwo.limit() - 10);581twoToOneShifter.position(twoToOne.position() - 10);582twoToOneShifter.limit(twoToOne.limit() - 10);583oneToTwoShifter.compact();584twoToOneShifter.compact();585oneToTwo.position(oneToTwoShifter.position() + 10);586oneToTwo.limit(oneToTwoShifter.limit() + 10);587twoToOne.position(twoToOneShifter.position() + 10);588twoToOne.limit(twoToOneShifter.limit() + 10);589590System.out.println("EXTRA WRAP");591result1 = ssle1.wrap(appOut1, oneToTwo);592checkResult(result1, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,5930, 0, false);594result2 = ssle2.wrap(appOut2, twoToOne);595checkResult(result2, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,5960, 0, false);597598System.out.println("wrap1 = " + result1);599System.out.println("wrap2 = " + result2);600601oneToTwo.flip();602twoToOne.flip();603oneToTwo.position(10);604twoToOne.position(10);605606System.out.println("EXTRA UNWRAP");607result1 = ssle1.unwrap(twoToOne, appIn1);608checkResult(result1, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,6090, 0, false);610result2 = ssle2.unwrap(oneToTwo, appIn2);611checkResult(result2, Status.CLOSED, HandshakeStatus.NOT_HANDSHAKING,6120, 0, false);613614System.out.println("unwrap1 = " + result1);615System.out.println("unwrap2 = " + result2);616617checkSession(ssls1, ssls2, ssls3, ssls4);618System.out.println(ssle1);619System.out.println(ssle2);620}621622private static void checkSession(SSLSession ssls1, SSLSession ssls2,623SSLSession ssls3, SSLSession ssls4) throws Exception {624System.out.println("\nSession Info for SSLEngine1");625System.out.println(ssls1);626System.out.println(ssls1.getCreationTime());627String peer1 = ssls1.getPeerHost();628System.out.println(peer1);629String protocol1 = ssls1.getProtocol();630System.out.println(protocol1);631java.security.cert.Certificate cert1 = ssls1.getPeerCertificates()[0];632System.out.println(cert1);633String ciphersuite1 = ssls1.getCipherSuite();634System.out.println(ciphersuite1);635System.out.println();636637System.out.println("\nSession Info for SSLEngine2");638System.out.println(ssls2);639System.out.println(ssls2.getCreationTime());640String peer2 = ssls2.getPeerHost();641System.out.println(peer2);642String protocol2 = ssls2.getProtocol();643System.out.println(protocol2);644java.security.cert.Certificate cert2 = ssls2.getPeerCertificates()[0];645System.out.println(cert2);646String ciphersuite2 = ssls2.getCipherSuite();647System.out.println(ciphersuite2);648System.out.println();649650if (peer1.equals(peer2)) {651throw new Exception("peer hostnames not equal");652}653654if (!protocol1.equals(protocol2)) {655throw new Exception("protocols not equal");656}657658if (!cert1.equals(cert2)) {659throw new Exception("certs not equal");660}661662if (!ciphersuite1.equals(ciphersuite2)) {663throw new Exception("ciphersuites not equal");664}665666System.out.println("\nSession Info for SSLEngine3");667System.out.println(ssls3);668System.out.println("\nSession Info for SSLEngine4");669System.out.println(ssls4);670671if (ssls3.equals(ssls1) || ssls4.equals(ssls2)) {672throw new Exception("sessions should not be equals");673}674}675676public static void main(String args[]) throws Exception {677// reset the security property to make sure that the algorithms678// and keys used in this test are not disabled.679Security.setProperty("jdk.tls.disabledAlgorithms", "");680681ConnectionTest ct = new ConnectionTest();682ct.test();683}684}685686687