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:
025: import java.io.IOException;
026: import java.security.SecureRandom;
027:
028: /**
029: *
030: * Represents server hello message.
031: * @see TLS 1.0 spec., 7.4.1.3. Server hello.
032: */
033: public class ServerHello extends Message {
034:
035: /**
036: * Server version
037: */
038: byte[] server_version = new byte[2];
039:
040: /**
041: * Random bytes
042: */
043: byte[] random = new byte[32];
044:
045: /**
046: * Session id
047: */
048: byte[] session_id;
049:
050: /**
051: * Selected cipher suite
052: */
053: CipherSuite cipher_suite;
054:
055: /**
056: * Selected compression method
057: */
058: byte compression_method;
059:
060: /**
061: * Creates outbound message
062: * @param sr
063: * @param server_version
064: * @param session_id
065: * @param cipher_suite
066: * @param compression_method
067: */
068: public ServerHello(SecureRandom sr, byte[] server_version,
069: byte[] session_id, CipherSuite cipher_suite,
070: byte compression_method) {
071: long gmt_unix_time = new java.util.Date().getTime() / 1000;
072: sr.nextBytes(random);
073: random[0] = (byte) ((gmt_unix_time & 0xFF000000) >>> 24);
074: random[1] = (byte) ((gmt_unix_time & 0xFF0000) >>> 16);
075: random[2] = (byte) ((gmt_unix_time & 0xFF00) >>> 8);
076: random[3] = (byte) (gmt_unix_time & 0xFF);
077: this .session_id = session_id;
078: this .cipher_suite = cipher_suite;
079: this .compression_method = compression_method;
080: this .server_version = server_version;
081: length = 38 + session_id.length;
082: }
083:
084: /**
085: * Creates inbound message
086: * @param in
087: * @param length
088: * @throws IOException
089: */
090: public ServerHello(HandshakeIODataStream in, int length)
091: throws IOException {
092:
093: server_version[0] = (byte) in.read();
094: server_version[1] = (byte) in.read();
095: in.read(random, 0, 32);
096: int size = in.readUint8();
097: session_id = new byte[size];
098: in.read(session_id, 0, size);
099: byte b0 = (byte) in.read();
100: byte b1 = (byte) in.read();
101: cipher_suite = CipherSuite.getByCode(b0, b1);
102: compression_method = (byte) in.read();
103: this .length = 38 + session_id.length;
104: if (this .length != length) {
105: fatalAlert(AlertProtocol.DECODE_ERROR,
106: "DECODE ERROR: incorrect ServerHello");
107: }
108:
109: }
110:
111: /**
112: * Sends message
113: * @param out
114: */
115: public void send(HandshakeIODataStream out) {
116: out.write(server_version);
117: out.write(random);
118: out.writeUint8(session_id.length);
119: out.write(session_id);
120: out.write(cipher_suite.toBytes());
121: out.write(compression_method);
122: length = 38 + session_id.length;
123: }
124:
125: /**
126: * Returns server random
127: * @return
128: */
129: public byte[] getRandom() {
130: return random;
131: }
132:
133: /**
134: * Returns message type
135: * @return
136: */
137: public int getType() {
138: return Handshake.SERVER_HELLO;
139: }
140: }
|