/*
* *
* Copyright (C) 2014 Open Whisper Systems
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* /
*/
package org.anhonesteffort.flock.sync;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyStore;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
/**
* Programmer: rhodey
* Date: 3/18/14
*/
public class AppSecureSocketFactory implements SecureProtocolSocketFactory {
private static final String TAG = "org.anhonesteffort.flock.sync.AppSecureSocketFactory";
private Context appContext;
private boolean useFlockTrustStore;
private SSLContext sslContext;
public AppSecureSocketFactory(Context context, boolean useFlockTrustStore) {
this.appContext = context;
this.useFlockTrustStore = useFlockTrustStore;
}
private static SSLContext createAppStoreSSLContext(Context appContext, boolean useFlockTrustStore)
throws HttpClientError
{
if (appContext == null)
throw new HttpClientError("application context is null :(");
KeyStore trustStore;
try {
if (useFlockTrustStore) {
AssetManager assetManager = appContext.getAssets();
InputStream keyStoreInputStream = assetManager.open("flock.store");
trustStore = KeyStore.getInstance("BKS");
trustStore.load(keyStoreInputStream, "owsflock".toCharArray());
}
else {
trustStore = KeyStore.getInstance("AndroidCAStore");
trustStore.load(null, null);
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init(trustStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext;
} catch (Exception e) {
Log.e(TAG, "createAppStoreSSLContext() - flock store? " + useFlockTrustStore, e);
throw new HttpClientError(e.toString());
}
}
private SSLContext getSSLContext() throws HttpClientError {
if (sslContext == null)
sslContext = createAppStoreSSLContext(appContext, useFlockTrustStore);
return sslContext;
}
@Override
public Socket createSocket(String host, int port)
throws HttpClientError, IOException
{
return getSSLContext().getSocketFactory().createSocket(host, port);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws HttpClientError, IOException
{
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket(String host, int port, InetAddress localAddress, int localPort)
throws HttpClientError, IOException
{
return getSSLContext().getSocketFactory().createSocket(host, port, localAddress, localPort);
}
@Override
public Socket createSocket(String host,
int port,
InetAddress localAddress,
int localPort,
HttpConnectionParams params)
throws HttpClientError, IOException
{
if (params == null)
return createSocket(host, port, localAddress, localPort);
int timeout = params.getConnectionTimeout();
if (timeout == 0)
return createSocket(host, port, localAddress, localPort);
return ControllerThreadSocketFactory.createSocket(this, host, port, localAddress, localPort, timeout);
}
}