Search in sources :

Example 1 with TLSA

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;
}
Also used : TLSA(org.minidns.record.TLSA) IOException(java.io.IOException) DNSName(org.minidns.dnsname.DNSName) LinkedList(java.util.LinkedList) UnverifiedReason(org.minidns.dnssec.UnverifiedReason) DNSSECMessage(org.minidns.dnssec.DNSSECMessage) DNSMessage(org.minidns.dnsmessage.DNSMessage)

Aggregations

IOException (java.io.IOException)1 LinkedList (java.util.LinkedList)1 DNSMessage (org.minidns.dnsmessage.DNSMessage)1 DNSName (org.minidns.dnsname.DNSName)1 DNSSECMessage (org.minidns.dnssec.DNSSECMessage)1 UnverifiedReason (org.minidns.dnssec.UnverifiedReason)1 TLSA (org.minidns.record.TLSA)1