Skip to content

Verify hostname after handshake

marci4 edited this page Apr 19, 2017 · 2 revisions

Introduction

Android proposes to verify the hostname of any connection.

See also: https://developer.android.com/training/articles/security-ssl.html#CommonHostnameProbs

Example

The following code is an example how to verify a hostname, in this example echo.websocket.org. The code is based on the example provided here.

package com.example.marci4.websockettest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import org.java_websocket.WebSocketImpl;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.net.URI;
import java.net.URISyntaxException;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        WebSocketClient client = null;
        try {
            client = new WebSocketClient(new URI("wss://echo.websocket.org")) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    Log.i("Client", "Open");
                }

                @Override
                public void onMessage(String message) {
                    Log.i("Client", "Message: " + message);
                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    Log.i("Client", "Close: " + reason + " Code: " + code + " Remote: " + remote);
                }

                @Override
                public void onError(Exception ex) {
                    Log.e("Client", "Error: " + ex.getMessage());
                }
            };
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        try {
            //Get SSLContext
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, null, null);
            client.setSocket(sslContext.getSocketFactory().createSocket());
            //Connect to server
            client.connectBlocking();
            //Verify 
            HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
            SSLSocket socket = (SSLSocket) client.getSocket();
            SSLSession s = socket.getSession();
            if (!hv.verify("echo.websocket.org", s)) {
                Log.e("Client", "Expected echo.websocket.org, found " + s.getPeerPrincipal());
                throw new SSLHandshakeException("Expected echo.websocket.org, found " + s.getPeerPrincipal());
            } else {
                Log.i("Client", "Success");
            }
        } catch (SSLHandshakeException e) {
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}