001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Boris Kuznetsov
020: * @version $Revision$
021: */package org.apache.harmony.xnet.provider.jsse;
022:
023: import org.apache.harmony.xnet.provider.jsse.Message;
024: import org.apache.harmony.xnet.provider.jsse.Handshake;
025: import org.apache.harmony.xnet.provider.jsse.HandshakeIODataStream;
026:
027: import java.io.IOException;
028: import java.math.BigInteger;
029:
030: /**
031: *
032: * Represents client key exchange message
033: * @see TLS 1.0 spec., 7.4.7. Client key exchange message
034: * (http://www.ietf.org/rfc/rfc2246.txt)
035: *
036: */
037: public class ClientKeyExchange extends Message {
038:
039: /**
040: * Exchange keys
041: */
042: final byte[] exchange_keys;
043:
044: /**
045: * Equals true if TLS1.0 protocol is used
046: */
047: boolean isTLS;
048:
049: /**
050: * Equals true if key exchange algorithm is RSA
051: */
052: final boolean isRSA;
053:
054: /**
055: * Creates outbound message
056: * @param encrypted_pre_master_secret
057: * @param isTLS
058: */
059: public ClientKeyExchange(byte[] encrypted_pre_master_secret,
060: boolean isTLS) {
061: this .exchange_keys = encrypted_pre_master_secret;
062: length = this .exchange_keys.length;
063: if (isTLS) {
064: length += 2;
065: }
066: this .isTLS = isTLS;
067: isRSA = true;
068: }
069:
070: /**
071: * Creates outbound message
072: * @param dh_Yc
073: */
074: public ClientKeyExchange(BigInteger dh_Yc) {
075: byte[] bb = dh_Yc.toByteArray();
076: if (bb[0] == 0) {
077: exchange_keys = new byte[bb.length - 1];
078: System.arraycopy(bb, 1, exchange_keys, 0,
079: exchange_keys.length);
080: } else {
081: exchange_keys = bb;
082: }
083: length = exchange_keys.length + 2;
084: isRSA = false;
085: }
086:
087: /**
088: * Creates empty message
089: *
090: */
091: public ClientKeyExchange() {
092: exchange_keys = new byte[0];
093: length = 0;
094: isRSA = false;
095: }
096:
097: /**
098: * Creates inbound message
099: * @param length
100: * @param isTLS
101: * @param isRSA
102: * @throws IOException
103: */
104: public ClientKeyExchange(HandshakeIODataStream in, int length,
105: boolean isTLS, boolean isRSA) throws IOException {
106: this .isTLS = isTLS;
107: this .isRSA = isRSA;
108: if (length == 0) {
109: this .length = 0;
110: exchange_keys = new byte[0];
111: } else {
112: int size;
113: if (isRSA && !isTLS) {// SSL3.0 RSA
114: size = length;
115: this .length = size;
116: } else { // DH or TLSv1 RSA
117: size = in.readUint16();
118: this .length = 2 + size;
119: }
120: exchange_keys = new byte[size];
121: in.read(exchange_keys, 0, size);
122: if (this .length != length) {
123: fatalAlert(AlertProtocol.DECODE_ERROR,
124: "DECODE ERROR: incorrect ClientKeyExchange");
125: }
126: }
127: }
128:
129: /**
130: * Sends message
131: * @param out
132: */
133: public void send(HandshakeIODataStream out) {
134: if (exchange_keys.length != 0) {
135: if (!isRSA || isTLS) {// DH or TLSv1 RSA
136: out.writeUint16(exchange_keys.length);
137: }
138: out.write(exchange_keys);
139: }
140: }
141:
142: /**
143: * Returns message type
144: * @return
145: */
146: public int getType() {
147: return Handshake.CLIENT_KEY_EXCHANGE;
148: }
149:
150: /**
151: * Returns true if the message is empty (in case of implicit DH Yc)
152: * @return
153: */
154: public boolean isEmpty() {
155: return (exchange_keys.length == 0);
156: }
157: }
|