Android Open Source - hello-pinnedcerts Main Activity






From Project

Back to project page hello-pinnedcerts.

License

The source code is released under:

Copyright (c) 2014 Ivan Ku?t Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Softwar...

If you think the Android project hello-pinnedcerts listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package co.infinum.https;
//from   w  ww. jav  a 2  s . c om
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.HashMap;
import java.util.Map;

import co.infinum.https.retrofit.GitHubService;
import co.infinum.https.retrofit.Logger;
import co.infinum.https.retrofit.User;
import de.greenrobot.event.EventBus;
import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.OkClient;
import retrofit.client.Response;

/**
 * Activity that demonstrates the use of HttpClientBuilder and RetrofitApacheClientBuilder. The main idea
 * is to show how to pin certificates to Apache and Retrofit clients and that requests to unauthorized
 * host's will be forbidden.
 * <p/>
 * There are three examples that can be run from app by using options in the actionbar menu item.
 * <ul>
 * <li>The first action demonstrates how to use HttpClientBuilder and make a valid request to the
 * host whose certificate is pinned</li>
 * <li>The second action demonstrates how to use RetrofitClientBuilder and make a valid request to
 * the host whose certificate is pinned</li>
 * <li>The last action demonstrates what happens if a request is being meade to a host signed with
 * a certificate that isn't pinned</li>
 * </ul>
 * <p/>
 * As a side note, EventBus library has been used to simplify callback from the Apache client.
 */
public class MainActivity extends ActionBarActivity {

    /**
     * Test URL.
     */
    private static final String TEST_URL = "https://api.github.com";

    /**
     * This URL will be forbidden since only the urls for host defined via certificate keystore
     * are allowed.
     */
    private static final String FORBIDDEN_URL = "https://www.google.hr";

    /**
     * Test Github username.
     */
    private static final String USER = "ikust";

    /**
     * Password for the certificate store.
     */
    private static final char[] STORE_PASS = new char[]{'t', 'e', 's', 't', 'i', 'n', 'g'};

    /**
     * TextView that displays request status or error.
     */
    private TextView statusTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        statusTextView = (TextView) findViewById(R.id.statusTextView);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    /**
     * An example of simple request with Apache HTTP client with pinned certificate.
     */
    private void makeApacheRequest() {
        HttpGet request = new HttpGet(TEST_URL);
        request.addHeader("User-Agent", "hello-pinnedcerts");

        EventBus.getDefault().post(request);
    }

    /**
     * Executes Apache HTTPS request on background thread.
     *
     * @param request
     */
    public void onEventAsync(HttpGet request) {

        try {
            DefaultHttpClient httpClient = new HttpClientBuilder()
                    .setConnectionTimeout(10000)
                    .setSocketTimeout(60000)
                    .setHttpPort(80)
                    .setHttpsPort(443)
                    .setCookieStore(new BasicCookieStore())
                    .pinCertificates(getResources(), R.raw.keystore, STORE_PASS)
                    .build();

            HttpResponse response = httpClient.execute(request);

            Map<String, Object> data = new HashMap<String, Object>();
            data.put("request", request);
            data.put("response", response);
            EventBus.getDefault().post(data);
        } catch (IOException e) {
            e.printStackTrace();
            EventBus.getDefault().post(request.getURI().toString()+" "+e.getMessage());
        } catch (CertificateException e) {
            e.printStackTrace();
            EventBus.getDefault().post(request.getURI().toString()+" "+e.getMessage());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            EventBus.getDefault().post(request.getURI().toString()+" "+e.getMessage());
        } catch (KeyStoreException e) {
            e.printStackTrace();
            EventBus.getDefault().post(request.getURI().toString()+" "+e.getMessage());
        }
    }

    /**
     * Called after Apache request was completed. Shows status in label.
     *
     * @param data data object with request and response in it
     */
    public void onEventMainThread(Map<String, Object> data) {
          HttpGet request = (HttpGet) data.get("request");
          HttpResponse response = (HttpResponse) data.get("response");

        statusTextView.setText("Apache "+request.getURI().toString()+" "+response.getStatusLine().toString());
    }

    /**
     * Called after there was an error executing Apache request. Shows exception in label.
     *
     * @param e
     */
    public void onEventMainThread(String e) {
        statusTextView.setText("Apache "+e);
    }


    /**
     * Executes Retrofit request.
     */
    private void makeRetrofitRequest() {
        try {
            OkClient retrofitClient = new RetrofitClientBuilder()
                    .setConnectionTimeout(10000)
                    .pinCertificates(getResources(), R.raw.keystore, STORE_PASS)
                    .build();

            RestAdapter restAdapter = new RestAdapter.Builder()
                    .setEndpoint(TEST_URL)
                    .setLogLevel(RestAdapter.LogLevel.FULL)
                    .setLog(new Logger())
                    .setClient(retrofitClient)
                    .build();

            GitHubService service = restAdapter.create(GitHubService.class);

            service.getUser(USER, "token "+this.getString(R.string.oauth_token), new Callback<User>() {

                @Override
                public void success(User user, Response response) {
                    statusTextView.setText("Retrofit "+TEST_URL+" "+response.getStatus() + " " + response.getReason());
                }

                @Override
                public void failure(RetrofitError error) {
                    statusTextView.setText("Retrofit "+TEST_URL+ " "+error.getMessage());
                }
            });
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    /**
     * Demonstrates that a request to a host with certificate different than the pinned one will fail.
     */
    private void makeForbiddenRequest() {
        try {
          OkClient retrofitClient = new RetrofitClientBuilder()
              .setConnectionTimeout(10000)
              .pinCertificates(getResources(), R.raw.keystore, STORE_PASS)
              .build();

          RestAdapter restAdapter = new RestAdapter.Builder()
              .setEndpoint(FORBIDDEN_URL)
              .setLogLevel(RestAdapter.LogLevel.FULL)
              .setLog(new Logger())
              .setClient(retrofitClient)
              .build();

          GitHubService service = restAdapter.create(GitHubService.class);

          service.getUser(USER, "dummy", new Callback<User>() {

            @Override
            public void success(User user, Response response) {
              statusTextView.setText("Retrofit "+FORBIDDEN_URL+" "+response.getStatus() + " " + response.getReason());
            }

            @Override
            public void failure(RetrofitError error) {
              statusTextView.setText("Retrofit "+FORBIDDEN_URL+ " "+error.getMessage());
            }
          });
        } catch (CertificateException e) {
          e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
          e.printStackTrace();
        } catch (KeyStoreException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
          e.printStackTrace();
        } catch (KeyManagementException e) {
          e.printStackTrace();
        }
    }

    @Override
    protected void onStart() {
        super.onStart();

        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();

        EventBus.getDefault().unregister(this);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        switch (id) {
            case R.id.action_apache:
                makeApacheRequest();
                return true;
            case R.id.action_retrofit:
                makeRetrofitRequest();
                return true;
            case R.id.action_not_allowed:
                makeForbiddenRequest();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

    }

}




Java Source Code List

co.infinum.https.CustomTrustManager.java
co.infinum.https.HttpClientBuilder.java
co.infinum.https.IgnorantHttpClient.java
co.infinum.https.MainActivity.java
co.infinum.https.RetrofitApacheClientBuilder.java
co.infinum.https.RetrofitClientBuilder.java
co.infinum.https.retrofit.GitHubService.java
co.infinum.https.retrofit.Logger.java
co.infinum.https.retrofit.User.java