Path: blob/master/test/jdk/javax/net/ssl/DTLS/DTLSSequenceNumberTest.java
41152 views
/*1* Copyright (c) 2015, 2017, 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 804375826* @summary Testing DTLS records sequence number property support in application27* data exchange.28* @key randomness29* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon30* @modules java.security.jgss31* jdk.security.auth32* java.security.jgss/sun.security.jgss.krb533* java.security.jgss/sun.security.krb5:+open34* java.security.jgss/sun.security.krb5.internal:+open35* java.security.jgss/sun.security.krb5.internal.ccache36* java.security.jgss/sun.security.krb5.internal.crypto37* java.security.jgss/sun.security.krb5.internal.ktab38* java.base/sun.security.util39* @build jdk.test.lib.RandomFactory40* @run main/othervm -Dtest.security.protocol=DTLS41* -Dtest.mode=norm DTLSSequenceNumberTest42* @run main/othervm -Dtest.security.protocol=DTLS43* -Dtest.mode=norm_sni DTLSSequenceNumberTest44* @run main/othervm -Dtest.security.protocol=DTLS45* -Dtest.mode=krb DTLSSequenceNumberTest46*/4748import java.nio.ByteBuffer;49import java.util.TreeMap;50import javax.net.ssl.SSLContext;51import javax.net.ssl.SSLEngine;52import javax.net.ssl.SSLEngineResult;53import javax.net.ssl.SSLException;54import java.util.Random;55import jdk.test.lib.RandomFactory;5657/**58* Testing DTLS records sequence number property support in application data59* exchange.60*/61public class DTLSSequenceNumberTest extends SSLEngineTestCase {6263private final String BIG_MESSAGE = "Very very big message. One two three"64+ " four five six seven eight nine ten eleven twelve thirteen"65+ " fourteen fifteen sixteen seventeen eighteen nineteen twenty.";66private final byte[] BIG_MESSAGE_BYTES = BIG_MESSAGE.getBytes();67private final int PIECES_NUMBER = 15;6869public static void main(String[] args) {70DTLSSequenceNumberTest test = new DTLSSequenceNumberTest();71setUpAndStartKDCIfNeeded();72test.runTests();73}7475@Override76protected void testOneCipher(String cipher) throws SSLException {77SSLContext context = getContext();78int maxPacketSize = getMaxPacketSize();79boolean useSNI = !TEST_MODE.equals("norm");80SSLEngine clientEngine = getClientSSLEngine(context, useSNI);81SSLEngine serverEngine = getServerSSLEngine(context, useSNI);82clientEngine.setEnabledCipherSuites(new String[]{cipher});83serverEngine.setEnabledCipherSuites(new String[]{cipher});84serverEngine.setNeedClientAuth(!cipher.contains("anon"));85doHandshake(clientEngine, serverEngine, maxPacketSize,86HandshakeMode.INITIAL_HANDSHAKE);87checkSeqNumPropertyWithAppDataSend(clientEngine, serverEngine);88checkSeqNumPropertyWithAppDataSend(serverEngine, clientEngine);89}9091private void checkSeqNumPropertyWithAppDataSend(SSLEngine sendEngine,92SSLEngine recvEngine) throws SSLException {93String sender, reciever;94if (sendEngine.getUseClientMode() && !recvEngine.getUseClientMode()) {95sender = "Client";96reciever = "Server";97} else if (recvEngine.getUseClientMode() && !sendEngine.getUseClientMode()) {98sender = "Server";99reciever = "Client";100} else {101throw new Error("Both engines are in the same mode");102}103System.out.println("================================================="104+ "===========");105System.out.println("Checking DTLS sequence number support"106+ " by sending data from " + sender + " to " + reciever);107ByteBuffer[] sentMessages = new ByteBuffer[PIECES_NUMBER];108ByteBuffer[] netBuffers = new ByteBuffer[PIECES_NUMBER];109TreeMap<Long, ByteBuffer> recvMap = new TreeMap<>(Long::compareUnsigned);110int symbolsInAMessage;111int symbolsInTheLastMessage;112int[] recievingSequence = new int[PIECES_NUMBER];113for (int i = 0; i < PIECES_NUMBER; i++) {114recievingSequence[i] = i;115}116shuffleArray(recievingSequence);117if (BIG_MESSAGE.length() % PIECES_NUMBER == 0) {118symbolsInAMessage = BIG_MESSAGE.length() / PIECES_NUMBER;119symbolsInTheLastMessage = symbolsInAMessage;120} else {121symbolsInAMessage = BIG_MESSAGE.length() / (PIECES_NUMBER - 1);122symbolsInTheLastMessage = BIG_MESSAGE.length() % (PIECES_NUMBER - 1);123}124for (int i = 0; i < PIECES_NUMBER - 1; i++) {125sentMessages[i] = ByteBuffer.wrap(BIG_MESSAGE_BYTES,126i * symbolsInAMessage, symbolsInAMessage);127}128sentMessages[PIECES_NUMBER - 1] = ByteBuffer.wrap(BIG_MESSAGE_BYTES,129(PIECES_NUMBER - 1) * symbolsInAMessage, symbolsInTheLastMessage);130long prevSeqNum = 0L;131//Wrapping massages in direct order132for (int i = 0; i < PIECES_NUMBER; i++) {133netBuffers[i] = ByteBuffer.allocate(sendEngine.getSession()134.getPacketBufferSize());135SSLEngineResult[] r = new SSLEngineResult[1];136netBuffers[i] = doWrap(sendEngine, sender, 0, sentMessages[i], r);137long seqNum = r[0].sequenceNumber();138if (Long.compareUnsigned(seqNum, prevSeqNum) <= 0) {139throw new AssertionError("Sequence number of the wrapped "140+ "message is less or equal than that of the"141+ " previous one! "142+ "Was " + prevSeqNum + ", now " + seqNum + ".");143}144prevSeqNum = seqNum;145}146//Unwrapping messages in random order and trying to reconstruct order147//from sequence number.148for (int i = 0; i < PIECES_NUMBER; i++) {149int recvNow = recievingSequence[i];150SSLEngineResult[] r = new SSLEngineResult[1];151ByteBuffer recvMassage = doUnWrap(recvEngine, reciever,152netBuffers[recvNow], r);153long seqNum = r[0].sequenceNumber();154recvMap.put(seqNum, recvMassage);155}156int mapSize = recvMap.size();157if (mapSize != PIECES_NUMBER) {158throw new AssertionError("The number of received massages "159+ mapSize + " is not equal to the number of sent messages "160+ PIECES_NUMBER + "!");161}162byte[] recvBigMsgBytes = new byte[BIG_MESSAGE_BYTES.length];163int counter = 0;164for (ByteBuffer msg : recvMap.values()) {165System.arraycopy(msg.array(), 0, recvBigMsgBytes,166counter * symbolsInAMessage, msg.remaining());167counter++;168}169String recvBigMsg = new String(recvBigMsgBytes);170if (!recvBigMsg.equals(BIG_MESSAGE)) {171throw new AssertionError("Received big message is not equal to"172+ " one that was sent! Received message is: " + recvBigMsg);173}174}175176private static void shuffleArray(int[] ar) {177final Random RNG = RandomFactory.getRandom();178for (int i = ar.length - 1; i > 0; i--) {179int index = RNG.nextInt(i + 1);180int a = ar[index];181ar[index] = ar[i];182ar[i] = a;183}184}185}186187188