1fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin/*
2fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * Copyright (C) 2014 The Android Open Source Project
3fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin *
4fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * Licensed under the Apache License, Version 2.0 (the "License");
5fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * you may not use this file except in compliance with the License.
6fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * You may obtain a copy of the License at
7fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin *
8fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin *      http://www.apache.org/licenses/LICENSE-2.0
9fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin *
10fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * Unless required by applicable law or agreed to in writing, software
11fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * distributed under the License is distributed on an "AS IS" BASIS,
12fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * See the License for the specific language governing permissions and
14fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * limitations under the License.
15fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin */
16fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
17fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinpackage libcore.tlswire.handshake;
18fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
19fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport libcore.tlswire.util.IoUtils;
20fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.io.ByteArrayInputStream;
21fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.io.DataInputStream;
22fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.io.IOException;
23fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.util.ArrayList;
24fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinimport java.util.List;
25fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
26fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin/**
27fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin * {@code server_name} (SNI) {@link HelloExtension} from TLS 1.2 RFC 5246.
28fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin */
29fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubinpublic class ServerNameHelloExtension extends HelloExtension {
30fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    private static final int TYPE_HOST_NAME = 0;
31fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
32b1fe85cc976c676eb50ff886596c93e04fd71d82Alex Klyubin    public List<String> hostnames;
33fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
34fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    @Override
35fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    protected void parseData() throws IOException {
36fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        byte[] serverNameListBytes = IoUtils.readTlsVariableLengthByteVector(
37fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin                new DataInputStream(new ByteArrayInputStream(data)), 0xffff);
38fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        ByteArrayInputStream serverNameListIn = new ByteArrayInputStream(serverNameListBytes);
39fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        DataInputStream in = new DataInputStream(serverNameListIn);
40fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        hostnames = new ArrayList<String>();
41fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        while (serverNameListIn.available() > 0) {
42fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            int type = in.readUnsignedByte();
43fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            if (type != TYPE_HOST_NAME) {
44fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin                throw new IOException("Unsupported ServerName type: " + type);
45fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            }
46fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            byte[] hostnameBytes = IoUtils.readTlsVariableLengthByteVector(in, 0xffff);
47fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            String hostname = new String(hostnameBytes, "US-ASCII");
48fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin            hostnames.add(hostname);
49fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        }
50fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    }
51fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin
52fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    @Override
53fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    public String toString() {
54fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin        return "HelloExtension{type: server_name, hostnames: " + hostnames + "}";
55fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin    }
56fb30da617fb979e7ae98c5a22b926aa15c6f2502Alex Klyubin}
57