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.java7; 012 013import org.minidns.dane.DaneVerifier; 014import org.minidns.dnssec.DnssecClient; 015 016import javax.net.ssl.SSLContext; 017import javax.net.ssl.SSLEngine; 018import javax.net.ssl.TrustManager; 019import javax.net.ssl.TrustManagerFactory; 020import javax.net.ssl.X509ExtendedTrustManager; 021import javax.net.ssl.X509TrustManager; 022 023import java.net.Socket; 024import java.security.KeyManagementException; 025import java.security.KeyStore; 026import java.security.KeyStoreException; 027import java.security.NoSuchAlgorithmException; 028import java.security.cert.CertificateException; 029import java.security.cert.X509Certificate; 030import java.util.logging.Logger; 031 032public class DaneExtendedTrustManager extends X509ExtendedTrustManager { 033 private static final Logger LOGGER = Logger.getLogger(DaneExtendedTrustManager.class.getName()); 034 035 private final X509TrustManager base; 036 private final DaneVerifier verifier; 037 038 public static void inject() { 039 inject(new DaneExtendedTrustManager()); 040 } 041 042 public static void inject(DaneExtendedTrustManager trustManager) { 043 try { 044 SSLContext sslContext = SSLContext.getInstance("TLS"); 045 sslContext.init(null, new TrustManager[] {trustManager}, null); 046 SSLContext.setDefault(sslContext); 047 } catch (NoSuchAlgorithmException | KeyManagementException e) { 048 throw new RuntimeException(e); 049 } 050 } 051 052 public DaneExtendedTrustManager() { 053 this(getDefaultTrustManager()); 054 } 055 056 public DaneExtendedTrustManager(DnssecClient client) { 057 this(client, getDefaultTrustManager()); 058 } 059 060 private static X509TrustManager getDefaultTrustManager() { 061 try { 062 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 063 tmf.init((KeyStore) null); 064 for (TrustManager trustManager : tmf.getTrustManagers()) { 065 if (trustManager instanceof X509TrustManager) 066 return (X509TrustManager) trustManager; 067 } 068 } catch (NoSuchAlgorithmException | KeyStoreException e) { 069 throw new RuntimeException("X.509 not supported.", e); 070 } 071 return null; 072 } 073 074 public DaneExtendedTrustManager(X509TrustManager base) { 075 this(new DaneVerifier(), base); 076 } 077 078 public DaneExtendedTrustManager(DnssecClient client, X509TrustManager base) { 079 this(new DaneVerifier(client), base); 080 } 081 082 public DaneExtendedTrustManager(DaneVerifier verifier, X509TrustManager base) { 083 this.verifier = verifier; 084 this.base = base; 085 } 086 087 @Override 088 public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { 089 if (base == null) { 090 LOGGER.warning("DaneExtendedTrustManager invalidly used for client certificate check and no fallback X509TrustManager specified"); 091 } else { 092 LOGGER.info("DaneExtendedTrustManager invalidly used for client certificate check forwarding request to fallback X509TrustManage"); 093 if (base instanceof X509ExtendedTrustManager) { 094 ((X509ExtendedTrustManager) base).checkClientTrusted(chain, authType, socket); 095 } else { 096 base.checkClientTrusted(chain, authType); 097 } 098 } 099 } 100 101 @Override 102 public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException { 103 if (!verifier.verifyCertificateChain(chain, socket.getInetAddress().getHostName(), socket.getPort())) { 104 if (base instanceof X509ExtendedTrustManager) { 105 ((X509ExtendedTrustManager) base).checkServerTrusted(chain, authType, socket); 106 } else { 107 base.checkClientTrusted(chain, authType); 108 } 109 } 110 } 111 112 @Override 113 public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { 114 if (base == null) { 115 LOGGER.warning("DaneExtendedTrustManager invalidly used for client certificate check and no fallback X509TrustManager specified"); 116 } else { 117 LOGGER.info("DaneExtendedTrustManager invalidly used for client certificate check, forwarding request to fallback X509TrustManage"); 118 if (base instanceof X509ExtendedTrustManager) { 119 ((X509ExtendedTrustManager) base).checkClientTrusted(chain, authType, engine); 120 } else { 121 base.checkClientTrusted(chain, authType); 122 } 123 } 124 } 125 126 @Override 127 public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException { 128 if (!verifier.verifyCertificateChain(chain, engine.getPeerHost(), engine.getPeerPort())) { 129 if (base instanceof X509ExtendedTrustManager) { 130 ((X509ExtendedTrustManager) base).checkServerTrusted(chain, authType, engine); 131 } else { 132 base.checkClientTrusted(chain, authType); 133 } 134 } 135 } 136 137 @Override 138 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { 139 if (base == null) { 140 LOGGER.warning("DaneExtendedTrustManager invalidly used for client certificate check and no fallback X509TrustManager specified"); 141 } else { 142 LOGGER.info("DaneExtendedTrustManager invalidly used for client certificate check, forwarding request to fallback X509TrustManage"); 143 base.checkClientTrusted(chain, authType); 144 } 145 } 146 147 @Override 148 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { 149 LOGGER.info("DaneExtendedTrustManager cannot be used without hostname information, forwarding request to fallback X509TrustManage"); 150 base.checkServerTrusted(chain, authType); 151 } 152 153 @Override 154 public X509Certificate[] getAcceptedIssuers() { 155 return base.getAcceptedIssuers(); 156 } 157}