1 /* 2 * Copyright (c) 2006, 2012, 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 30 import javax.net.ssl.SSLProtocolException; 31 32 /* 33 * For secure renegotiation, RFC5746 defines a new TLS extension, 34 * "renegotiation_info" (with extension type 0xff01), which contains a 35 * cryptographic binding to the enclosing TLS connection (if any) for 36 * which the renegotiation is being performed. The "extension data" 37 * field of this extension contains a "RenegotiationInfo" structure: 38 * 39 * struct { 40 * opaque renegotiated_connection<0..255>; 41 * } RenegotiationInfo; 42 */ 43 final class RenegotiationInfoExtension extends HelloExtension { 44 private final byte[] renegotiated_connection; 45 46 RenegotiationInfoExtension(byte[] clientVerifyData, 47 byte[] serverVerifyData) { 48 super(ExtensionType.EXT_RENEGOTIATION_INFO); 49 50 if (clientVerifyData.length != 0) { 51 renegotiated_connection = 52 new byte[clientVerifyData.length + serverVerifyData.length]; 53 System.arraycopy(clientVerifyData, 0, renegotiated_connection, 54 0, clientVerifyData.length); 55 56 if (serverVerifyData.length != 0) { 57 System.arraycopy(serverVerifyData, 0, renegotiated_connection, 58 clientVerifyData.length, serverVerifyData.length); 59 } 60 } else { 61 // ignore both the client and server verify data. 62 renegotiated_connection = new byte[0]; 63 } 64 } 65 66 RenegotiationInfoExtension(HandshakeInStream s, int len) 67 throws IOException { 68 super(ExtensionType.EXT_RENEGOTIATION_INFO); 69 70 // check the extension length 71 if (len < 1) { 72 throw new SSLProtocolException("Invalid " + type + " extension"); 73 } 74 75 int renegoInfoDataLen = s.getInt8(); 76 if (renegoInfoDataLen + 1 != len) { // + 1 = the byte we just read 77 throw new SSLProtocolException("Invalid " + type + " extension"); 78 } 79 80 renegotiated_connection = new byte[renegoInfoDataLen]; 81 if (renegoInfoDataLen != 0) { 82 s.read(renegotiated_connection, 0, renegoInfoDataLen); 83 } 84 } 85 86 87 // Length of the encoded extension, including the type and length fields 88 @Override 89 int length() { 90 return 5 + renegotiated_connection.length; 91 } 92 93 @Override 94 void send(HandshakeOutStream s) throws IOException { 95 s.putInt16(type.id); 96 s.putInt16(renegotiated_connection.length + 1); 97 s.putBytes8(renegotiated_connection); 98 } 99 100 boolean isEmpty() { 101 return renegotiated_connection.length == 0; 102 } 103 104 byte[] getRenegotiatedConnection() { 105 return renegotiated_connection; 106 } 107 108 @Override 109 public String toString() { 110 return "Extension " + type + ", renegotiated_connection: " + 111 (renegotiated_connection.length == 0 ? "<empty>" : 112 Debug.toString(renegotiated_connection)); 113 } 114 115 }