package net.rdrei.android.scdl2.api; import java.net.HttpURLConnection; import java.net.URLConnection; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import org.thoughtcrime.ssl.pinning.PinningTrustManager; import com.github.kevinsawicki.http.HttpRequest; import com.google.gson.reflect.TypeToken; import com.google.inject.Inject; import com.google.inject.Injector; import com.google.inject.assistedinject.Assisted; public class SecureSoundcloudApiQueryImpl<T extends SoundcloudEntity> extends AbstractSoundcloudApiQueryImpl<T> { @Inject private Injector mInjector; @Inject public SecureSoundcloudApiQueryImpl(@Assisted final URLWrapper url, @Assisted final HttpMethod method, @Assisted final TypeToken<T> typeToken) { super(url, method, typeToken); } @Override protected void setupPostRequest(final HttpRequest request) { pinSSLConnection(request); } /** * Applies the pinning SSL manager to the connection. * * @param connection */ private void pinSSLConnection(final HttpURLConnection connection) { if (!(connection instanceof HttpsURLConnection)) { throw new IllegalStateException("Not an SSL connection!"); } final TrustManager[] trustManagers = getPinningTrustManagers(); final SSLContext sslContext; try { sslContext = SSLContext.getInstance("TLS"); } catch (final NoSuchAlgorithmException e) { // Again, should not happen if I didn't type it wrong. throw new IllegalArgumentException(e); } try { sslContext.init(null, trustManagers, null); } catch (final KeyManagementException e) { throw new IllegalStateException(e); } ((HttpsURLConnection) connection).setSSLSocketFactory(sslContext .getSocketFactory()); } private void pinSSLConnection(final HttpRequest request) { request.applyTrustManager(getPinningTrustManagers()); } /** * @return An array containing an instance of the PinningTrustManager. */ private TrustManager[] getPinningTrustManagers() { final TrustManager[] trustManagers = new TrustManager[1]; trustManagers[0] = mInjector.getInstance(PinningTrustManager.class); return trustManagers; } @Override protected void setupGetConnection(final URLConnection connection) { pinSSLConnection((HttpsURLConnection) connection); } }