Home | History | Annotate | Download | only in jsse
      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 
     18 package org.apache.harmony.xnet.provider.jsse;
     19 
     20 import java.io.IOException;
     21 import java.security.SecureRandom;
     22 import 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  */
     30 public 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