package org.forest.ssl;

import org.forest.exceptions.ForestRuntimeException;
import org.forest.http.ForestRequest;

import javax.net.ssl.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @author gongjun[jun.gong@thebeastshop.com]
 * @since 2018-03-01 18:59
 */
public class SSLUtils {

    /**
     * 自定义SSL证书
     * @param request
     * @return
     */
    public static SSLContext customSSL(ForestRequest request) {
        SSLContext sslContext = null;
        SSLKeyStore fKeyStore = request.getKeyStore();
        final KeyStore keyStore = fKeyStore.getTrustStore();
        String certPass = fKeyStore.getCertPass();
        if (keyStore != null) {
            try {

                sslContext = SSLContext.getInstance("TLS");

                //密钥库
                KeyManagerFactory kmf = KeyManagerFactory.getInstance("sunx509");
                kmf.init(keyStore, certPass.toCharArray());

                TrustManagerFactory tmf = TrustManagerFactory
                        .getInstance(TrustManagerFactory.getDefaultAlgorithm());
                tmf.init(keyStore);

                X509TrustManager defaultTrustManager = (X509TrustManager) tmf
                        .getTrustManagers()[0];
//                SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
//                sslContext.init(kmf.getKeyManagers(), new TrustManager[] { tm }, null);
                sslContext.init(null, tmf.getTrustManagers(), null);

//                SSLContextBuilder scBuilder = SSLContexts.custom();
//                if (keystorePass != null) {
//                    sslContext = scBuilder
//                            .loadKeyMaterial(trustStore, keystorePass.toCharArray())
//                            .build();
//                } else {
//                    sslContext = scBuilder
//                            .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy())
//                            .build();
//                }
            } catch (NoSuchAlgorithmException e) {
                throw new ForestRuntimeException(e);
            } catch (KeyManagementException e) {
                throw new ForestRuntimeException(e);
            } catch (KeyStoreException e) {
                throw new ForestRuntimeException(e);
            } catch (UnrecoverableKeyException e) {
                throw new ForestRuntimeException(e);
            }
        }
        return sslContext;
    }


    /**
     * 绕过SSL验证
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sc = SSLContext.getInstance("SSLv3");
        TrustAllManager trustManager = new TrustAllManager();
        sc.init(null, new TrustManager[] { trustManager }, null);
        return sc;
    }



    /**
     * 获取SSL上下文
     * @param request
     * @return
     */
    public static SSLContext getSSLContext(ForestRequest request) throws KeyManagementException, NoSuchAlgorithmException {
        if (request.getKeyStore() == null) {
            return SSLUtils.createIgnoreVerifySSL();
        }
        return SSLUtils.customSSL(request);
    }

    public static SSLSocketFactory getSSLSocketFactory(ForestRequest request) {
        if (request == null) {
            return null;
        }
        try {
            SSLContext sslContext = SSLUtils.getSSLContext(request);
            if (sslContext == null) {
                throw new ForestRuntimeException("SSL context cannot be initialized.");
            }
            return sslContext.getSocketFactory();
        } catch (KeyManagementException e) {
            throw new ForestRuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new ForestRuntimeException(e);
        }
    }


    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain;
            tm.checkServerTrusted(chain, authType);
        }
    }

}

@@ -18,16 +18,169 @@
 t.ssl;%0A%0A
+import org.apache.http.conn.ssl.SSLContextBuilder;%0Aimport org.apache.http.conn.ssl.SSLContexts;%0Aimport org.apache.http.conn.ssl.TrustSelfSignedStrategy;%0A
 import o
@@ -894,24 +894,26 @@
      try %7B%0A%0A
+//
             
@@ -1302,24 +1302,26 @@
 keyStore);%0A%0A
+//
             
@@ -1386,16 +1386,18 @@
 er) tmf%0A
+//
         
@@ -1605,32 +1605,34 @@
  %7B tm %7D, null);%0A
+//
                 
@@ -1683,24 +1683,322 @@
 , null);%0A%0A//
+                sslContext =%0A//                        SSLContexts.custom().useSSL().loadKeyMaterial(keyStore, certPass.toCharArray())%0A//                                .loadTrustMaterial(keyStore).build();%0A//                sslContext.init(kmf.getKeyManagers(), new TrustManager%5B%5D %7B tm %7D, null);%0A%0A
             
@@ -2049,26 +2049,24 @@
 s.custom();%0A
-//
             
@@ -2073,24 +2073,20 @@
     if (
-keystore
+cert
 Pass != 
@@ -2093,18 +2093,16 @@
 null) %7B%0A
-//
         
@@ -2128,34 +2128,32 @@
 ext = scBuilder%0A
-//
                 
@@ -2185,28 +2185,22 @@
 ial(
-trust
+key
 Store, 
-keystore
+cert
 Pass
@@ -2207,34 +2207,32 @@
 .toCharArray())%0A
-//
                 
@@ -2245,34 +2245,32 @@
       .build();%0A
-//
                 
@@ -2278,18 +2278,16 @@
  else %7B%0A
-//
         
@@ -2321,18 +2321,16 @@
 Builder%0A
-//
         
@@ -2368,21 +2368,19 @@
 aterial(
-trust
+key
 Store, n
@@ -2405,26 +2405,24 @@
 Strategy())%0A
-//
             
@@ -2439,34 +2439,32 @@
       .build();%0A
-//
                 

fix SSL