1/* 2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.nio.ByteBuffer; 25import javax.net.ssl.SSLContext; 26import javax.net.ssl.SSLEngine; 27import javax.net.ssl.SSLEngineResult; 28import javax.net.ssl.SSLException; 29 30/** 31 * Testing SSLEngine incorrect app data packages unwrapping. 32 */ 33public class BufferOverflowUnderflowTest extends SSLEngineTestCase { 34 35 private final String MESSAGE = "Hello peer!"; 36 37 public static void main(String[] args) { 38 BufferOverflowUnderflowTest test = new BufferOverflowUnderflowTest(); 39 setUpAndStartKDCIfNeeded(); 40 test.runTests(); 41 } 42 43 @Override 44 protected void testOneCipher(String cipher) throws SSLException { 45 SSLContext context = getContext(); 46 int maxPacketSize = getMaxPacketSize(); 47 boolean useSNI = !TEST_MODE.equals("norm"); 48 SSLEngine clientEngine = getClientSSLEngine(context, useSNI); 49 SSLEngine serverEngine = getServerSSLEngine(context, useSNI); 50 clientEngine.setEnabledCipherSuites(new String[]{cipher}); 51 serverEngine.setEnabledCipherSuites(new String[]{cipher}); 52 serverEngine.setNeedClientAuth(!cipher.contains("anon")); 53 doHandshake(clientEngine, serverEngine, maxPacketSize, 54 HandshakeMode.INITIAL_HANDSHAKE); 55 checkBufferOverflowOnWrap(clientEngine); 56 checkBufferOverflowOnWrap(serverEngine); 57 checkBufferOverflowOnUnWrap(clientEngine, serverEngine); 58 checkBufferOverflowOnUnWrap(serverEngine, clientEngine); 59 checkBufferUnderflowOnUnWrap(serverEngine, clientEngine); 60 checkBufferUnderflowOnUnWrap(clientEngine, serverEngine); 61 } 62 63 private void checkBufferOverflowOnWrap(SSLEngine engine) 64 throws SSLException { 65 String mode = engine.getUseClientMode() ? "client" 66 : "server"; 67 System.out.println("=================================================" 68 + "==========="); 69 System.out.println("Testing SSLEngine buffer overflow" 70 + " on wrap by " + mode); 71 ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes()); 72 //Making net buffer size less than required by 1 byte. 73 ByteBuffer net = ByteBuffer 74 .allocate(engine.getSession().getPacketBufferSize() - 1); 75 SSLEngineResult r = engine.wrap(app, net); 76 checkResult(r, SSLEngineResult.Status.BUFFER_OVERFLOW); 77 System.out.println("Passed"); 78 } 79 80 private void checkBufferOverflowOnUnWrap(SSLEngine wrappingEngine, 81 SSLEngine unwrappingEngine) 82 throws SSLException { 83 String wrapperMode = wrappingEngine.getUseClientMode() ? "client" 84 : "server"; 85 String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client" 86 : "server"; 87 if (wrapperMode.equals(unwrapperMode)) { 88 throw new Error("Test error: both engines are in the same mode!"); 89 } 90 System.out.println("=================================================" 91 + "==========="); 92 System.out.println("Testing SSLEngine buffer overflow" 93 + " on unwrap by " + unwrapperMode); 94 ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes()); 95 ByteBuffer net = ByteBuffer 96 .allocate(wrappingEngine.getSession().getPacketBufferSize()); 97 SSLEngineResult r = wrappingEngine.wrap(app, net); 98 checkResult(r, SSLEngineResult.Status.OK); 99 //Making app buffer size less than required by 1 byte. 100 app = ByteBuffer.allocate(MESSAGE.length() - 1); 101 net.flip(); 102 r = unwrappingEngine.unwrap(net, app); 103 checkResult(r, SSLEngineResult.Status.BUFFER_OVERFLOW); 104 System.out.println("Passed"); 105 } 106 107 private void checkBufferUnderflowOnUnWrap(SSLEngine wrappingEngine, 108 SSLEngine unwrappingEngine) 109 throws SSLException { 110 String wrapperMode = wrappingEngine.getUseClientMode() ? "client" 111 : "server"; 112 String unwrapperMode = unwrappingEngine.getUseClientMode() ? "client" 113 : "server"; 114 if (wrapperMode.equals(unwrapperMode)) { 115 throw new Error("Test error: both engines are in the same mode!"); 116 } 117 System.out.println("=================================================" 118 + "==========="); 119 System.out.println("Testing SSLEngine buffer underflow" 120 + " on unwrap by " + unwrapperMode); 121 ByteBuffer app = ByteBuffer.wrap(MESSAGE.getBytes()); 122 ByteBuffer net = ByteBuffer 123 .allocate(wrappingEngine.getSession().getPacketBufferSize()); 124 SSLEngineResult r = wrappingEngine.wrap(app, net); 125 checkResult(r, SSLEngineResult.Status.OK); 126 app = ByteBuffer.allocate(unwrappingEngine.getSession() 127 .getApplicationBufferSize()); 128 net.flip(); 129 //Making net buffer size less than size of dtls message. 130 net.limit(net.limit() - 1); 131 r = unwrappingEngine.unwrap(net, app); 132 checkResult(r, SSLEngineResult.Status.BUFFER_UNDERFLOW); 133 System.out.println("Passed"); 134 } 135} 136