2016-12-01 191 views
0
public class CustomTrustManager implements X509TrustManager { 

    private X509TrustManager trustManager; 
    // If a connection was previously attempted and failed the certificate check, that certificate chain will be saved here. 
    private Certificate[] rejectedCertificates = null; 
    private Certificate[] encounteredCertificates = null; 
    private KeyStore keyStore = null; 
    private Logger logger; 

    /** 
    * Constructor 
    * 
    * @param loggerFactory 
    *   see {@link InstanceLoggerFactory} 
    */ 
    public CustomTrustManager(InstanceLoggerFactory loggerFactory) { 
     try { 
     this.logger = loggerFactory.getLogger(CustomTrustManager.class); 
     keyStore = KeyStore.getInstance("JKS"); 
     // a keyStore must be initialized with load, even if certificate trust is not file based. 
     keyStore.load(null, null); 

     System.setProperty("com.sun.net.ssl.checkRevocation", "true"); 
     Security.setProperty("ocsp.enable", "true"); 
     } catch (Exception ex) { 
     logger.error("Problem initializing keyStore", ex); 
     } 
    } 

    /** 
    * Returns the rejected certificate based on the last usage 
    */ 
    public Certificate[] getRejectedCertificateChain() { 
     return rejectedCertificates; 
    } 

    /** 
    * Returns the encountered certificates based on the last usage 
    */ 
    public Certificate[] getEncounteredCertificates() { 
     return encounteredCertificates; 
    } 

    @Override 
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 
     if (trustManager != null) { 
     trustManager.checkClientTrusted(chain, authType); 
     } 
    } 

    /** 
    * Checks if a server is trusted, based on the wrapped keyStore's trust 
    * anchors. This will also capture the encountered certificate chain and, if 
    * trust fails, the rejected certificate chain. 
    */ 
    @Override 
    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CustomCertificateException { 
     // Capture the certificate if it fails 
     try { 
     encounteredCertificates = chain; 
     if (trustManager != null) { 
      trustManager.checkServerTrusted(chain, authType); 
     } else { 
      throw new RuntimeException("Trust manager is null"); 
     } 
     } catch (CertificateException ex) { 
     rejectedCertificates = chain; 
     throw new CustomCertificateException(ex, rejectedCertificates); 
     } catch (Exception ex) { 
     rejectedCertificates = chain; 
     throw new CustomCertificateException(new CertificateException(ex), rejectedCertificates); 
     } 
    } 

    @Override 
    public X509Certificate[] getAcceptedIssuers() { 
     return trustManager == null ? new X509Certificate[0] : trustManager.getAcceptedIssuers(); 
    } 

    /** 
    * initializes the internal trust manager with all known certificates 
    * certificates are stored in the keyStore object 
    */ 
    private void initTrustManager() { 
     try { 
     // initialize a new TMF with our keyStore 
     TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX", "SunJSSE"); 

     // keyStore must not be empty 
     CertPathParameters pkixParams = new PKIXBuilderParameters(keyStore, new X509CertSelector()); 
     ((PKIXBuilderParameters) pkixParams).setRevocationEnabled(true); 

     tmf.init(new CertPathTrustManagerParameters(pkixParams)); 

     // acquire X509 trust manager from factory 
     TrustManager tms[] = tmf.getTrustManagers(); 
     for (TrustManager tm : tms) { 
      if (tm instanceof X509TrustManager) { 
       trustManager = (X509TrustManager) tm; 
       break; 
      } 
     } 
     } catch (Exception ex) { 
     logger.error("Problem initializing trust manager", ex); 
     } 
    } 

... 
} 

在這裏,我已經實現了X509TrustManager信任管理器,並試圖將相應的檢查調用委託給在運行時發現的x509信任管理器。 我的問題是,我已經設置了關於OCSP的屬性,足以確保Java在驗證證書鏈時也可以執行OCSP?換句話說,checkServerTrusted()方法自己處理,如果屬性設置?如果設置了適當的屬性,X509TrustManagerImpl.checkServerTrusted()是否自行處理OCSP?

回答

1

它看起來不像你通過OCSP檢查撤銷。這裏是一個如何做到這一點的例子。您將需要目標證書和響應者URL。我從一個工作示例中提取了它,並將其修改爲儘可能通用。沒有測試過,但它應該工作或者非常接近工作。您可能不得不根據您的需求量身定製,但不是太多。

private void validateCertPath(X509Certificate targetCertificate, X509Certificate issuerCertificate, String responderURL, String trustAnchorDirectory) 
      throws CertPathValidatorException, 
          InvalidAlgorithmParameterException, 
          FileNotFoundException, 
          CertificateException, 
          NoSuchAlgorithmException { 

    List<X509Certificate> certList = new Vector<X509Certificate>(); 
    certList.add(targetCertificate); 
    certList.add(issuerCertificate); 

    CertificateFactory cf = CertificateFactory.getInstance("X.509"); 

    CertPath cp = cf.generateCertPath(certList); 

    CertPathValidator cpv = CertPathValidator.getInstance("PKIX"); 

    Set<TrustAnchor> trustStore = new HashSet<TrustAnchor>(); 
    TrustAnchor anchor = null; 
    X509Certificate cacert = null; 
    File directory = new File(trustAnchorDirectory); 
    String certFileNames[] = directory.list(); 

    for (String certFile : certFileNames) { 
     cacert = readCert(trustAnchorDirectory +"/" + certFile); 
     anchor = new TrustAnchor(cacert, null); 
     trustStore.add(anchor); 
    } 

    PKIXParameters params = new PKIXParameters(trustStore); 
    params.setRevocationEnabled(true); 

    Security.setProperty("ocsp.enable", "true"); 
    Security.setProperty("ocsp.responderURL", responderUrl); 

    PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(cp, params); 
    System.out.println("Certificate validated"); 
    System.out.println("Policy Tree:\n" + result.getPolicyTree()); 

}

相關問題