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