ServerHello.java revision f5309a39506c967feda8766feeba7f7271a458cb
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 java.io.IOException;
21import java.security.SecureRandom;
22import libcore.io.Streams;
23
24/**
25 *
26 * Represents server hello message.
27 * @see <a href="http://www.ietf.org/rfc/rfc2246.txt">TLS 1.0 spec., 7.4.1.3.
28 * Server hello.</a>
29 */
30public class ServerHello extends Message {
31
32    /**
33     * Server version
34     */
35    byte[] server_version = new byte[2];
36
37    /**
38     * Random bytes
39     */
40    byte[] random = new byte[32];
41
42    /**
43     * Session id
44     */
45    byte[] session_id;
46
47    /**
48     * Selected cipher suite
49     */
50    CipherSuite cipher_suite;
51
52    /**
53     * Selected compression method
54     */
55    byte compression_method;
56
57    /**
58     * Creates outbound message
59     * @param sr
60     * @param server_version
61     * @param session_id
62     * @param cipher_suite
63     * @param compression_method
64     */
65    public ServerHello(SecureRandom sr, byte[] server_version,
66            byte[] session_id, CipherSuite cipher_suite, byte compression_method) {
67        long gmt_unix_time = new java.util.Date().getTime() / 1000;
68        sr.nextBytes(random);
69        random[0] = (byte) ((gmt_unix_time & 0xFF000000) >>> 24);
70        random[1] = (byte) ((gmt_unix_time & 0xFF0000) >>> 16);
71        random[2] = (byte) ((gmt_unix_time & 0xFF00) >>> 8);
72        random[3] = (byte) (gmt_unix_time & 0xFF);
73        this.session_id = session_id;
74        this.cipher_suite = cipher_suite;
75        this.compression_method = compression_method;
76        this.server_version = server_version;
77        length = 38 + session_id.length;
78    }
79
80    /**
81     * Creates inbound message
82     * @param in
83     * @param length
84     * @throws IOException
85     */
86    public ServerHello(HandshakeIODataStream in, int length) throws IOException {
87
88        server_version[0] = (byte) in.read();
89        server_version[1] = (byte) in.read();
90        Streams.readFully(in, random);
91        int size = in.readUint8();
92        session_id = new byte[size];
93        in.read(session_id, 0, size);
94        byte b0 = (byte) in.read();
95        byte b1 = (byte) in.read();
96        cipher_suite = CipherSuite.getByCode(b0, b1);
97        compression_method = (byte) in.read();
98        this.length = 38 + session_id.length;
99        if (this.length != length) {
100            fatalAlert(AlertProtocol.DECODE_ERROR, "DECODE ERROR: incorrect ServerHello");
101        }
102
103    }
104
105    /**
106     * Sends message
107     * @param out
108     */
109    @Override
110    public void send(HandshakeIODataStream out) {
111        out.write(server_version);
112        out.write(random);
113        out.writeUint8(session_id.length);
114        out.write(session_id);
115        out.write(cipher_suite.toBytes());
116        out.write(compression_method);
117        length = 38 + session_id.length;
118    }
119
120    /**
121     * Returns server random
122     * @return
123     */
124    public byte[] getRandom() {
125        return random;
126    }
127
128    /**
129     * Returns message type
130     * @return
131     */
132    @Override
133    public int getType() {
134        return Handshake.SERVER_HELLO;
135    }
136}
137