use of org.minidns.record.TLSA in project minidns by MiniDNS.
the class DaneVerifier method verifyCertificateChain.
/**
* Verifies a certificate chain to be valid when used with the given connection details using DANE.
*
* @param chain A certificate chain that should be verified using DANE.
* @param hostName The DNS name of the host this certificate chain belongs to.
* @param port The port number that was used to reach the server providing the certificate chain in question.
* @return Whether the DANE verification is the only requirement according to the TLSA record.
* If this method returns {@code false}, additional PKIX validation is required.
* @throws CertificateException if the certificate chain provided differs from the one enforced using DANE.
*/
public boolean verifyCertificateChain(X509Certificate[] chain, String hostName, int port) throws CertificateException {
DNSName req = DNSName.from("_" + port + "._tcp." + hostName);
DNSMessage res;
try {
res = client.query(req, Record.TYPE.TLSA);
} catch (IOException e) {
throw new RuntimeException(e);
}
if (!res.authenticData) {
String msg = "Got TLSA response from DNS server, but was not signed properly.";
if (res instanceof DNSSECMessage) {
msg += " Reasons:";
for (UnverifiedReason reason : ((DNSSECMessage) res).getUnverifiedReasons()) {
msg += " " + reason;
}
}
LOGGER.info(msg);
return false;
}
List<DaneCertificateException.CertificateMismatch> certificateMismatchExceptions = new LinkedList<>();
boolean verified = false;
for (Record<? extends Data> record : res.answerSection) {
if (record.type == Record.TYPE.TLSA && record.name.equals(req)) {
TLSA tlsa = (TLSA) record.payloadData;
try {
verified |= checkCertificateMatches(chain[0], tlsa, hostName);
} catch (DaneCertificateException.CertificateMismatch certificateMismatchException) {
// Record the mismatch and only throw an exception if no
// TLSA RR is able to verify the cert. This allows for TLSA
// certificate rollover.
certificateMismatchExceptions.add(certificateMismatchException);
}
if (verified)
break;
}
}
if (!verified && !certificateMismatchExceptions.isEmpty()) {
throw new DaneCertificateException.MultipleCertificateMismatchExceptions(certificateMismatchExceptions);
}
return verified;
}
Aggregations