001/* 002 * Copyright 2015-2020 the original author or authors 003 * 004 * This software is licensed under the Apache License, Version 2.0, 005 * the GNU Lesser General Public License version 2 or later ("LGPL") 006 * and the WTFPL. 007 * You may choose either license to govern your use of this software only 008 * upon the condition that you accept all of the terms of either 009 * the Apache License 2.0, the LGPL 2.1+ or the WTFPL. 010 */ 011package org.minidns.dane; 012 013import javax.net.ssl.TrustManager; 014import javax.net.ssl.TrustManagerFactory; 015import javax.net.ssl.X509TrustManager; 016import java.security.KeyStore; 017import java.security.KeyStoreException; 018import java.security.NoSuchAlgorithmException; 019import java.security.cert.CertificateException; 020import java.security.cert.X509Certificate; 021 022public class ExpectingTrustManager implements X509TrustManager { 023 private CertificateException exception; 024 private final X509TrustManager trustManager; 025 026 /** 027 * Creates a new instance of ExpectingTrustManager. 028 * 029 * @param trustManager The {@link X509TrustManager} to be used for verification. 030 * {@code null} to use the system default. 031 */ 032 public ExpectingTrustManager(X509TrustManager trustManager) { 033 this.trustManager = trustManager == null ? getDefaultTrustManager() : trustManager; 034 } 035 036 public boolean hasException() { 037 return exception != null; 038 } 039 040 public CertificateException getException() { 041 CertificateException e = exception; 042 exception = null; 043 return e; 044 } 045 046 @Override 047 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 048 try { 049 trustManager.checkClientTrusted(chain, authType); 050 } catch (CertificateException e) { 051 exception = e; 052 } 053 } 054 055 @Override 056 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 057 try { 058 trustManager.checkServerTrusted(chain, authType); 059 } catch (CertificateException e) { 060 exception = e; 061 } 062 } 063 064 @Override 065 public X509Certificate[] getAcceptedIssuers() { 066 return trustManager.getAcceptedIssuers(); 067 } 068 069 private static X509TrustManager getDefaultTrustManager() { 070 try { 071 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 072 tmf.init((KeyStore) null); 073 for (TrustManager trustManager : tmf.getTrustManagers()) { 074 if (trustManager instanceof X509TrustManager) 075 return (X509TrustManager) trustManager; 076 } 077 } catch (NoSuchAlgorithmException | KeyStoreException e) { 078 throw new RuntimeException("X.509 not supported.", e); 079 } 080 return null; 081 } 082}