All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.spardat.xma.security.SSLCertificateReader Maven / Gradle / Ivy

package at.spardat.xma.security;


import java.io.FileInputStream;
import java.io.IOException;


import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.PKIXParameters;
import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import at.spardat.xma.boot.BootRuntime;
import at.spardat.xma.boot.Statics;



import java.security.cert.CertificateException;

public class SSLCertificateReader {

	public static String SSL_CERT = "SSL_CERT";
	public static String SSL_CERT_ISSUED_TO = "SSL_CERT_ISSUED_TO";
	public static String SSL_CERT_ISSUED_BY = "SSL_CERT_ISSUED_BY";
	public static String SSL_CERT_VALID_FROM = "SSL_CERT_VALID_FROM";
	public static String SSL_CERT_VALID_TO = "SSL_CERT_VALID_TO";

	/**
	 * test part
	 * 
	 * @param args
	 * @since version_number
	 * @author s6718
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.setProperty("http.proxyHost", "proxy-sd.s-mxs.net");
		System.setProperty("http.proxyPort", "8080");
		System.setProperty("https.proxyHost", "proxy-sd.s-mxs.net");
		System.setProperty("https.proxyPort", "8080");

		// URL url = new
		// URL("https://intranet.ersteopen.net/Portal.Node/portal");
		// String surl = "https://netbanking.sparkasse.at/sPortal/";
		// String surl = "https://andis.s-mxs.net/andis/"; //proxy
		// String surl = "https://intranet.ersteopen.net/Portal.Node/portal/";
		//https://seabooks.dev.imcplus.net/SeaBooks/
		String surl = "https://dev.imcplus.net/svn/sb"; // proxy // this will
														// give validation error
														// without
														// authentication
		String tunnelHost = System.getProperty("https.proxyHost");
		int tunnelPort = Integer.getInteger("https.proxyPort").intValue();

		SSLCertificateReader s = new SSLCertificateReader();
		// s.readCertificate(surl); //default test case
		// following has to be used only if you get validation error
		// that means trying to access url without authentication but still want
		// to see
		// certificate - this is what found so far.
		 try {
            s.readCertificateProxy(surl, tunnelHost, tunnelPort);
        }
        catch ( Exception e ) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } // test with
		// proxy
	}

	private ResourceBundle resourceBundle;

	// call method if want to invoke behind proxy
	/**
     * To read the Chain of certificates from the site  from the given URL, it always return
     * peer certificate first that means last child first
	 * 

	 * @param sUrl
	 *            url of the site
	 * @param sHost
	 *            host name or ipaddress of the proxy
	 * @param iPort
	 *            port of the proxy
     * @return it returns array of map containing details of certificate as
     *         below, every map will contain follwoing keys to retrieve data
     *         SSL_CERT = ArrayList containing String Array[2] as key and value 
     *         pair detail of the certificate, that can be shown in table.
     *         SSL_CERT_ISSUED_TO = String returns issued to information
     *         SSL_CERT_ISSUED_BY = String returns issued by information
     *         SSL_CERT_VALID_FROM = String returns valid from date
     *         SSL_CERT_VALID_TO = String returns valid till date
	 * @since version_number
	 * @author S6718
	 */
	public ArrayList readCertificateProxy(String sUrl, String sHost, int iPort)
			throws Exception {
		Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(sHost,
				iPort));
		return readCertificate(sUrl, proxy);

	}

	// direct invoke method
	/**
	 * To read the Chain of certificates from the site  from the given URL, it always return
     * peer certificate first that means last child first
	 * 
	 * @param sUrl
	 *            url of the site
     * @return it returns array of map containing details of certificate as
     *         below, every map will contain follwoing keys to retrieve data
     *         SSL_CERT = ArrayList containing String Array[2] as key and value 
     *         pair detail of the certificate, that can be shown in table.
     *         SSL_CERT_ISSUED_TO = String returns issued to information
     *         SSL_CERT_ISSUED_BY = String returns issued by information
     *         SSL_CERT_VALID_FROM = String returns valid from date
     *         SSL_CERT_VALID_TO = String returns valid till date
	 * @since version_number
	 * @author S6718
	 */
	public ArrayList readCertificate(String sUrl) throws Exception {
		return readCertificate(sUrl, null);
	}

	/**
	 * Method to return Chain of certificates from the site. It always return
	 * peer certificate first that means last child first
	 * 
	 * @param sUrl
	 *            url of the site to retrieve certificate
	 * @param proxy
	 *            proxy settings of the proxy server if any
	 * @return it returns array of map containing details of certificate as
	 *         below, every map will contain follwoing keys to retrieve data
	 *         SSL_CERT = ArrayList containing String Array[2] as key and value 
	 *         pair detail of the certificate, that can be shown in table.
	 *         SSL_CERT_ISSUED_TO = String returns issued to information
	 *         SSL_CERT_ISSUED_BY = String returns issued by information
	 *         SSL_CERT_VALID_FROM = String returns valid from date
	 *         SSL_CERT_VALID_TO = String returns valid till date
	 *         
	 * 
	 * @since version_number
	 * @author S6718
	 * @throws Exception
	 */
	private ArrayList  readCertificate(String sUrl, Proxy proxy)
			throws Exception {
	    ArrayList certChain = new ArrayList();

		try {

			URL url = new URL(sUrl);
			HttpsURLConnection uc = null;
			if (proxy != null) {
				SSLContext sc = SSLContext.getInstance("SSL");
				sc.init(null, trustAllCerts(), new java.security.SecureRandom());
				HttpsURLConnection.setDefaultSSLSocketFactory(sc
						.getSocketFactory());
				HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid());
				uc = (HttpsURLConnection) url.openConnection(proxy);
			} else
				uc = (HttpsURLConnection) url.openConnection();

			uc.connect();
			Certificate[] servercerts = uc.getServerCertificates();
			X509Certificate  childcert = null;
			HashMap cert =null;
			String[] sdata = new String[2];

	         for (int i =0; i< servercerts.length ; i++) {
	                X509Certificate x =(X509Certificate)servercerts[i];
	                List listdata = populateCertificateData(x);
	                addToAList(certChain, listdata, x);
	                if(childcert != null)
	                {
	                    try{
	                        childcert.verify(x.getPublicKey());
	                    }catch(java.security.SignatureException sg){
//	                        System.out.println(" not matched with ");
	                        //nothing to do
	                    }
	                }else
	                    childcert= x;
	                if (i == servercerts.length-1){
	                    //for last node try to gete root certificate
	                    X509Certificate xroot = getRootCertificate(x.getPublicKey(), x);
	                    if(xroot != null){
	                        //means verifed and match found
	                        listdata = populateCertificateData(xroot);
	                        addToAList(certChain, listdata, xroot);
	                    }
	                
	                }
	                
	            }

		} catch (Exception e) {
//			e.printStackTrace();
			throw e;
		}
		return certChain;
	}

	    /**
	     * Add additional details on top of map just to populate overview of certificate
	     * 
	     * @param certChain
	     * @param listdata
	     * @param x
	     */
	   private void addToAList(ArrayList certChain ,List listdata, X509Certificate x)
	    {// summery on top though it is inside in listdata.
	        HashMap cert = new HashMap();
	        cert.put(SSL_CERT_ISSUED_TO, getCN(x.getSubjectDN().getName()
	                .split(",")));
	        cert.put(SSL_CERT_ISSUED_BY, getCN(x.getIssuerDN().getName()
	                .split(",")));
	        cert.put(SSL_CERT_VALID_FROM, x.getNotBefore());
	        cert.put(SSL_CERT_VALID_TO, x.getNotAfter());

	        cert.put(SSL_CERT, listdata); // certificate details
	        certChain.add(0,cert);
	    }
	    
	   /**
	    * populate internal certificate details
	    * 
	    * @param c
	    * @return
	    */
	    private List populateCertificateData(Certificate c)
	    {
	        List listdata = new ArrayList();
	        String[] sdata = new String[2];
	        
	        X509Certificate x = (X509Certificate) c;

	        sdata[0] = getMessage("CertificateForm.Version", "Version");
	        sdata[1] = "V" + x.getVersion();
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.SerialNumber",
	                "Seriennummer (Serial Number)");
	        sdata[1] = x.getSerialNumber().toString(16);
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.Signature",
	                "Signaturalgorithmus (Signature)");
	        sdata[1] = "" + x.getSigAlgName();
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.IssuedBy",
	                "Aussteller (Issued By)");
	        sdata[1] = "" + x.getIssuerDN();
	        System.out.println("issuer>> " + x.getIssuerDN());
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.ValidFrom",
	                "G?ltig ab (Valid From)");
	        sdata[1] = "" + x.getNotBefore();
	        listdata.add(sdata);
	        System.out.println("Valid From >> " + x.getNotBefore());
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.ValidTill",
	                "G?ltig bis(Valid Till)");
	        sdata[1] = "" + x.getNotAfter();
	        System.out.println("Valid Till >> " + x.getNotAfter());
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.IssuedTo",
	                "Antragsteller (Subject/Issued To)");
	        sdata[1] = "" + x.getSubjectDN();
	        System.out.println("issued to >> " + x.getSubjectDN());
	        listdata.add(sdata);
	        sdata = new String[2];

	        sdata[0] = getMessage("CertificateForm.publicKey",
	                "?ffentlicher Schl?ssel (Public Key)");
	        sdata[1] = "" + x.getPublicKey();
	        byte[] encoded = x.getPublicKey().getEncoded();
	        String hexString = toHex(encoded);
	        listdata.add(sdata);
	        sdata = new String[2];
	        
	        return listdata;

	    }
	    
	    

	
	
	    // read binary to hex of certificate public key
	   static String toHex(byte[] digest) {
//	        System.out.println("...lendgth "+ digest.length);
	        StringBuilder sb = new StringBuilder();
	        for (byte b : digest) {
	            sb.append(String.format("%1$02X", b)).append(" ");
	        }

	        return sb.toString();
	    }

	   
	/**
	 * To override exception of validation of trusted certificate site
	 * 
	 * @return
	 */
	private TrustManager[] trustAllCerts() {
		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
			public java.security.cert.X509Certificate[] getAcceptedIssuers() {
				return null;
			}

			public void checkClientTrusted(X509Certificate[] certs,
					String authType) {
			}

			public void checkServerTrusted(X509Certificate[] certs,
					String authType) {
			}

		} };
		return trustAllCerts;

	}

	/**
	 * To skip validation error of trusted site.
	 * 
	 * @return always true
	 */
	public HostnameVerifier allHostsValid() {
		// Create all-trusting host name verifier
		HostnameVerifier allHostsValid = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};
		return allHostsValid;
	}

	/**
	 * method to extract name details from certificate string token
	 * 
	 * @param sdata
	 * @return
	 */
	private String getCN(String[] sdata) {
		for (int i=0; i




© 2015 - 2025 Weber Informatics LLC | Privacy Policy