Back to project page hello-pinnedcerts.
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.
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); } } }