1

I am trying to implement a custom ssl trustmanager for google.com. I exported the certificate in DER encoded binary X.509(.CER) format from google.com using the certificate export wizard in chrome.

Next I am using the certificate to implement a X509TrustManager for google.com

I am converting the certificate into an array of X509Certificate. I am doing a check on the public key of the exported certificate and the certificate chain which I get from google in checkServerTrusted() method.

This is my implementation

import java.io.FileInputStream;
import java.io.IOException;
import java.security.Key;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.util.ArrayList;
import java.util.Enumeration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.jboss.security.Base64Encoder;

public class GetCertificates {
    static private TrustManager[] trustmgr = new TrustManager[] { new X509TrustManager() {

        private X509Certificate[] compCerts = null;

        public void checkClientTrusted(X509Certificate[] certs, String authType) {
            System.out.println("checkClientTrusted");
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
            boolean match = false;
            compCerts = getcompanyCerts("C:/Users/vinod/Desktop/certificate tests/googleCert.cer");

            for (int i = 0; i < certs.length; i++) {
                for (int j = 0; j < compCerts.length; j++) {
                    PublicKey pubKey = compCerts[j].getPublicKey();
                    if (certs[i].getPublicKey().equals(pubKey)) {
                        match = true;
                        break;
                    }
                }
            }
            if (!match) {
                compCerts = null;
                throw new CertificateException();
            }

            System.out.println("checkServerTrusted");
        }

        public X509Certificate[] getAcceptedIssuers() {
            System.out.println("getAcceptedIssuers");
            return compCerts;
        }
    } };

    public void postMessage() {
        try {

            String server = "google.com";//github.com, google.com, 
            int port = 443;
            String protocol = "https";
            String authData = "";
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustmgr, new SecureRandom());
            SSLSocketFactory sf = new SSLSocketFactory(sslContext, new AllowAllHostnameVerifier());
            Scheme httpsScheme = new Scheme("https", port, sf);
            SchemeRegistry schemeRegistry = new SchemeRegistry();
            schemeRegistry.register(httpsScheme);
            ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
            DefaultHttpClient httpclient = new DefaultHttpClient(cm);
            HttpResponse httpClientResponse = null;
            HttpRequestBase httpBase = null;

            HttpGet httpGet = new HttpGet(protocol + "://" + server + ":" + String.valueOf(port));

            httpGet.addHeader("Authorization", "Basic " + authData);
            httpGet.addHeader("accept", "application/xml");
            httpBase = httpGet;
            httpClientResponse = httpclient.execute(httpBase);
            System.out.println(httpClientResponse.getStatusLine().getStatusCode());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static X509Certificate[] getcompanyCerts(String path)
    {
        try
        {
            X509Certificate x509Certificate[] = null;
            ArrayList<X509Certificate> serverCerts = new ArrayList<X509Certificate>();
            Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(new FileInputStream(path));
            X509Certificate cert1 = (X509Certificate) cert;
            serverCerts.add(cert1);
            x509Certificate = serverCerts.toArray(new X509Certificate[serverCerts.size()]);
            return x509Certificate;
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        new GetCertificates().postMessage();
    }

}

Public key from the certificate which I exported

Sun EC public key, 256 bits public x coord: 103858512549833402870596711608983633962395322362485707804776545539526450437829 public y coord: 551038063834479125183333778395955290333878428073207984470499584820613530179 parameters: secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)

Public key from google certificate chain

Sun RSA public key, 2048 bits modulus: 23143370852942880318350916000931697018095187779007718496802621885454913199787528262130121558631489120838817008741156066278392137072461769922534717322344763991314852008921195771153223806536069497781120172866861790294120988948493270866849076947675153622229006495917543748035309441307004545650688546140739858567714350881927672977958435382326618077408774333432728249263290793965486643049909764375831461262493963698376698137704130984951477859888660854457689871626252787358108605089635723759571477994625181232277846364760559779436524005104837073250536963577409319433417664849201259083657597612256894368314574080046815497557 public exponent: 65537

Exported certificate gives Sun EC public key, 256 bits but certificate from google gives Sun RSA public key, 2048 bits. Where am I going wrong. Is the way in which I exported the certificate wrong or any mistake with the way in which I am converting the certificate to X509Certificate.

user2703788
  • 163
  • 1
  • 16
  • Google.com is a heavily distributed system which consists of hundreds of computers in dozens of server locations all over the world. That not all computers are equipped with the same certificate may happen in such environments. AFAIR Google prefers CA certificate pinning instead of server certificate pinning. – Robert Aug 09 '16 at 13:55
  • Thanks for the response, I am very new to this area. do you mean I need to check only for valid CA in case of google, because the same code works for github.com with github's certificate. – user2703788 Aug 09 '16 at 14:55
  • You can try to pin the intermediate CA `Google Internet Authority G2` for google or the root CA `GeoTrust Global CA`. For both CAs it is very unlikely that someone will get a forged google.com certificate. – Robert Aug 09 '16 at 15:54

0 Answers0