ClientKeyExchange.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.xnet.provider.jsse; 19 20import org.apache.harmony.xnet.provider.jsse.Message; 21import org.apache.harmony.xnet.provider.jsse.Handshake; 22import org.apache.harmony.xnet.provider.jsse.HandshakeIODataStream; 23 24import java.io.IOException; 25import java.math.BigInteger; 26 27/** 28 * Represents client key exchange message 29 * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.7. 30 * Client key exchange message</a> 31 * 32 */ 33public class ClientKeyExchange extends Message { 34 35 /** 36 * Exchange keys 37 */ 38 final byte[] exchange_keys; 39 40 /** 41 * Equals true if TLS1.0 protocol is used 42 */ 43 boolean isTLS; 44 45 /** 46 * Equals true if key exchange algorithm is RSA 47 */ 48 final boolean isRSA; 49 50 /** 51 * Creates outbound message 52 * @param encrypted_pre_master_secret 53 * @param isTLS 54 */ 55 public ClientKeyExchange(byte[] encrypted_pre_master_secret, boolean isTLS) { 56 this.exchange_keys = encrypted_pre_master_secret; 57 length = this.exchange_keys.length; 58 if (isTLS) { 59 length += 2; 60 } 61 this.isTLS = isTLS; 62 isRSA = true; 63 } 64 65 /** 66 * Creates outbound message 67 * @param dh_Yc 68 */ 69 public ClientKeyExchange(BigInteger dh_Yc) { 70 byte[] bb = dh_Yc.toByteArray(); 71 if (bb[0] == 0) { 72 exchange_keys = new byte[bb.length-1]; 73 System.arraycopy(bb, 1, exchange_keys, 0, exchange_keys.length); 74 } else { 75 exchange_keys = bb; 76 } 77 length = exchange_keys.length +2; 78 isRSA = false; 79 } 80 81 /** 82 * Creates empty message 83 * 84 */ 85 public ClientKeyExchange() { 86 exchange_keys = new byte[0]; 87 length = 0; 88 isRSA = false; 89 } 90 91 /** 92 * Creates inbound message 93 * @param length 94 * @param isTLS 95 * @param isRSA 96 * @throws IOException 97 */ 98 public ClientKeyExchange(HandshakeIODataStream in, int length, boolean isTLS, boolean isRSA) 99 throws IOException { 100 this.isTLS = isTLS; 101 this.isRSA = isRSA; 102 if (length == 0) { 103 this.length = 0; 104 exchange_keys = new byte[0]; 105 } else { 106 int size; 107 if (isRSA && !isTLS) {// SSL3.0 RSA 108 size = length; 109 this.length = size; 110 } else { // DH or TLSv1 RSA 111 size = in.readUint16(); 112 this.length = 2 + size; 113 } 114 exchange_keys = new byte[size]; 115 in.read(exchange_keys, 0, size); 116 if (this.length != length) { 117 fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ClientKeyExchange"); 118 } 119 } 120 } 121 122 /** 123 * Sends message 124 * @param out 125 */ 126 @Override 127 public void send(HandshakeIODataStream out) { 128 if (exchange_keys.length != 0) { 129 if (!isRSA || isTLS) {// DH or TLSv1 RSA 130 out.writeUint16(exchange_keys.length); 131 } 132 out.write(exchange_keys); 133 } 134 } 135 136 /** 137 * Returns message type 138 * @return 139 */ 140 @Override 141 public int getType() { 142 return Handshake.CLIENT_KEY_EXCHANGE; 143 } 144 145 /** 146 * Returns true if the message is empty (in case of implicit DH Yc) 147 * @return 148 */ 149 public boolean isEmpty() { 150 return (exchange_keys.length == 0); 151 } 152} 153