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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.io.IOException; 29 import javax.net.ssl.SSLProtocolException; 30 31 /* 32 * [RFC6066] TLS specifies a fixed maximum plaintext fragment length of 33 * 2^14 bytes. It may be desirable for constrained clients to negotiate 34 * a smaller maximum fragment length due to memory limitations or bandwidth 35 * limitations. 36 * 37 * In order to negotiate smaller maximum fragment lengths, clients MAY 38 * include an extension of type "max_fragment_length" in the (extended) 39 * client hello. The "extension_data" field of this extension SHALL 40 * contain: 41 * 42 * enum{ 43 * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) 44 * } MaxFragmentLength; 45 * 46 * whose value is the desired maximum fragment length. 47 */ 48 final class MaxFragmentLengthExtension extends HelloExtension { 49 50 private static final int MAX_FRAGMENT_LENGTH_512 = 1; // 2^9 51 private static final int MAX_FRAGMENT_LENGTH_1024 = 2; // 2^10 52 private static final int MAX_FRAGMENT_LENGTH_2048 = 3; // 2^11 53 private static final int MAX_FRAGMENT_LENGTH_4096 = 4; // 2^12 54 55 final int maxFragmentLength; 56 57 MaxFragmentLengthExtension(int fragmentSize) { 58 super(ExtensionType.EXT_MAX_FRAGMENT_LENGTH); 59 60 if (fragmentSize < 1024) { 61 maxFragmentLength = MAX_FRAGMENT_LENGTH_512; 62 } else if (fragmentSize < 2048) { 63 maxFragmentLength = MAX_FRAGMENT_LENGTH_1024; 64 } else if (fragmentSize < 4096) { 65 maxFragmentLength = MAX_FRAGMENT_LENGTH_2048; 66 } else { 67 maxFragmentLength = MAX_FRAGMENT_LENGTH_4096; 68 } 69 } 70 71 MaxFragmentLengthExtension(HandshakeInStream s, int len) 72 throws IOException { 73 super(ExtensionType.EXT_MAX_FRAGMENT_LENGTH); 74 75 // check the extension length 76 if (len != 1) { 77 throw new SSLProtocolException("Invalid " + type + " extension"); 78 } 79 80 maxFragmentLength = s.getInt8(); 81 if ((maxFragmentLength > 4) || (maxFragmentLength < 1)) { 82 throw new SSLProtocolException("Invalid " + type + " extension"); 83 } 84 } 85 86 // Length of the encoded extension, including the type and length fields 87 @Override 88 int length() { 89 return 5; // 4: extension type and length fields 90 // 1: MaxFragmentLength field 91 } 92 93 @Override 94 void send(HandshakeOutStream s) throws IOException { 95 s.putInt16(type.id); 96 s.putInt16(1); 97 s.putInt8(maxFragmentLength); 98 } 99 100 int getMaxFragLen() { 101 switch (maxFragmentLength) { 102 case MAX_FRAGMENT_LENGTH_512: 103 return 512; 104 case MAX_FRAGMENT_LENGTH_1024: 105 return 1024; 106 case MAX_FRAGMENT_LENGTH_2048: 107 return 2048; 108 case MAX_FRAGMENT_LENGTH_4096: 109 return 4096; 110 } 111 112 // unlikely to happen 113 return -1; 114 } 115 116 static boolean needFragLenNego(int fragmentSize) { 117 return (fragmentSize > 0) && (fragmentSize <= 4096); 118 } 119 120 static int getValidMaxFragLen(int fragmentSize) { 121 if (fragmentSize < 1024) { 122 return 512; 123 } else if (fragmentSize < 2048) { 124 return 1024; 125 } else if (fragmentSize < 4096) { 126 return 2048; 127 } else if (fragmentSize == 4096) { 128 return 4096; 129 } else { 130 return 16384; 131 } 132 } 133 134 @Override 135 public String toString() { 136 return "Extension " + type + ", max_fragment_length: " + 137 "(2^" + (maxFragmentLength + 8) + ")"; 138 } 139 }