This is what I am doing. I am downloading a JSON file that contains HTTP and HTTPS websites. These websites are images. I want to display these images in my app. For the HTTP it works perfectly, but for the HTTPS it says there is no image to download. So basically it is not reaching to the HTTPS. I am using the Android Dev sites way of accessing the HTTPS connection, but that is where I think my problem is coming from. I have the selfsigned cert in a folder res/raw and I access that using the Resources. The if statement does break out the two HTTP and HTTPS websites and works fine as far as I can tell. Can i do this like I am doing or is there a better way of doing this? Thank you for any help.
public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
Resources resources = null;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
protected Bitmap doInBackground(String... params)
{
return downloadBitmap(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
Log.d("Downloading the image: ", "No Image found");
}
}
}
}
//URL connection to download the image
private Bitmap downloadBitmap(String url) {
HttpURLConnection urlConnection = null;
HttpsURLConnection urlConnection2 = null;
try {
//check to see if the image is coming from a HTTP connection
//then download via a HTTP connection
//if not then use a HTTPS connection
if(url.contains("https"))
{
try {
Log.d("Use HTTPS", url);
URL urlHTTPS = new URL(url);
urlConnection2 = (HttpsURLConnection) urlHTTPS.openConnection();
// Load CAs from an InputStream
// (could be from a resource or ByteArrayInputStream or ...)
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = resources.getAssets().open("fusionsystemca.crt");
Log.d("CA: ", caInput.toString());
//InputStream caInput = new BufferedInputStream(new FileInputStream(resources.getAssets().open("myca.crt")));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}
// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
urlConnection2.setSSLSocketFactory(context.getSocketFactory());
int statusCode = urlConnection2.getResponseCode();
Log.d("URL2 Status: " , Integer.toString(statusCode));
//check if the HTTP status code is equal to 200, which means that it is ok
if (statusCode != 200) {
return null;
}
InputStream in = urlConnection2.getInputStream();
if (in != null) {
Bitmap bitmap = BitmapFactory.decodeStream(in);
return bitmap;
}
}catch (Exception e)
{
urlConnection2.disconnect();
Log.d("ImageDownloader", "Error downloading image from " + url);
}
}else
{
URL uri = new URL(url);
urlConnection = (HttpURLConnection) uri.openConnection();
urlConnection.setRequestMethod("GET");
int statusCode = urlConnection.getResponseCode();
//check if the HTTP status code is equal to 200, which means that it is ok
if (statusCode != 200) {
return null;
}
InputStream inputStream = urlConnection.getInputStream();
if (inputStream != null) {
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
}
}
} catch (Exception e) {
urlConnection.disconnect();
Log.d("ImageDownloader", "Error downloading image from " + url);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if(urlConnection2 != null)
{
urlConnection2.disconnect();
}
}
return null;
}
//this is to add the selfsigned cert
}
Edits: I am still stuck with this error javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found. which is the cert is not being accepted. I went so far to add this method to the code so that every cert will be allowed and it still gives me the same issues.
public void trustAllHosts() {
X509TrustManager easyTrustManager = new X509TrustManager() {
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {easyTrustManager};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
}
are you sure the ssl certificates that you are trying to access are enlisted as "trusted" ? I had a similar problem where i was trying to access a resource with comodo certificate which was not trusted so it kept on breaking..