Search in sources :

Example 1 with DNSKEY

use of org.minidns.record.DNSKEY in project minidns by MiniDNS.

the class DNSSECClient method verifySecureEntryPoint.

private Set<UnverifiedReason> verifySecureEntryPoint(Question q, final Record<DNSKEY> sepRecord) throws IOException {
    final DNSKEY dnskey = sepRecord.payloadData;
    Set<UnverifiedReason> unverifiedReasons = new HashSet<>();
    Set<UnverifiedReason> activeReasons = new HashSet<>();
    if (knownSeps.containsKey(sepRecord.name)) {
        if (dnskey.keyEquals(knownSeps.get(sepRecord.name))) {
            return unverifiedReasons;
        } else {
            unverifiedReasons.add(new UnverifiedReason.ConflictsWithSep(sepRecord));
            return unverifiedReasons;
        }
    }
    // configured with one and we can abort stating the reason.
    if (sepRecord.name.isRootLabel()) {
        unverifiedReasons.add(new UnverifiedReason.NoRootSecureEntryPointReason());
        return unverifiedReasons;
    }
    DelegatingDnssecRR delegation = null;
    DNSSECMessage dsResp = queryDnssec(sepRecord.name, TYPE.DS);
    if (dsResp == null) {
        LOGGER.fine("There is no DS record for " + sepRecord.name + ", server gives no result");
    } else {
        unverifiedReasons.addAll(dsResp.getUnverifiedReasons());
        for (Record<? extends Data> record : dsResp.answerSection) {
            Record<DS> dsRecord = record.ifPossibleAs(DS.class);
            if (dsRecord == null)
                continue;
            DS ds = dsRecord.payloadData;
            if (dnskey.getKeyTag() == ds.keyTag) {
                delegation = ds;
                activeReasons = dsResp.getUnverifiedReasons();
                break;
            }
        }
        if (delegation == null) {
            LOGGER.fine("There is no DS record for " + sepRecord.name + ", server gives empty result");
        }
    }
    if (delegation == null && dlv != null && !dlv.isChildOf(sepRecord.name)) {
        DNSSECMessage dlvResp = queryDnssec(DNSName.from(sepRecord.name, dlv), TYPE.DLV);
        if (dlvResp != null) {
            unverifiedReasons.addAll(dlvResp.getUnverifiedReasons());
            for (Record<? extends Data> record : dlvResp.answerSection) {
                Record<DLV> dlvRecord = record.ifPossibleAs(DLV.class);
                if (dlvRecord == null)
                    continue;
                if (sepRecord.payloadData.getKeyTag() == dlvRecord.payloadData.keyTag) {
                    LOGGER.fine("Found DLV for " + sepRecord.name + ", awesome.");
                    delegation = dlvRecord.payloadData;
                    activeReasons = dlvResp.getUnverifiedReasons();
                    break;
                }
            }
        }
    }
    if (delegation != null) {
        UnverifiedReason unverifiedReason = verifier.verify(sepRecord, delegation);
        if (unverifiedReason != null) {
            unverifiedReasons.add(unverifiedReason);
        } else {
            unverifiedReasons = activeReasons;
        }
    } else if (unverifiedReasons.isEmpty()) {
        unverifiedReasons.add(new NoTrustAnchorReason(sepRecord.name.ace));
    }
    return unverifiedReasons;
}
Also used : DelegatingDnssecRR(org.minidns.record.DelegatingDnssecRR) DNSKEY(org.minidns.record.DNSKEY) DS(org.minidns.record.DS) DLV(org.minidns.record.DLV) NoTrustAnchorReason(org.minidns.dnssec.UnverifiedReason.NoTrustAnchorReason) HashSet(java.util.HashSet)

Example 2 with DNSKEY

use of org.minidns.record.DNSKEY in project minidns by MiniDNS.

the class DNSSECClient method verifySignedRecords.

private Set<UnverifiedReason> verifySignedRecords(Question q, RRSIG rrsig, List<Record<? extends Data>> records) throws IOException {
    Set<UnverifiedReason> result = new HashSet<>();
    DNSKEY dnskey = null;
    if (rrsig.typeCovered == TYPE.DNSKEY) {
        // Key must be present
        for (Record<? extends Data> record : records) {
            Record<DNSKEY> dnsKeyRecord = record.ifPossibleAs(DNSKEY.class);
            if (dnsKeyRecord == null)
                continue;
            if (dnsKeyRecord.payloadData.getKeyTag() == rrsig.keyTag) {
                dnskey = dnsKeyRecord.payloadData;
                break;
            }
        }
    } else if (q.type == TYPE.DS && rrsig.signerName.equals(q.name)) {
        // We should not probe for the self signed DS negative response, as it will be an endless loop.
        result.add(new NoTrustAnchorReason(q.name.ace));
        return result;
    } else {
        DNSSECMessage dnskeyRes = queryDnssec(rrsig.signerName, TYPE.DNSKEY);
        if (dnskeyRes == null) {
            throw new DNSSECValidationFailedException(q, "There is no DNSKEY " + rrsig.signerName + ", but it is used");
        }
        result.addAll(dnskeyRes.getUnverifiedReasons());
        for (Record<? extends Data> record : dnskeyRes.answerSection) {
            Record<DNSKEY> dnsKeyRecord = record.ifPossibleAs(DNSKEY.class);
            if (dnsKeyRecord == null)
                continue;
            if (dnsKeyRecord.payloadData.getKeyTag() == rrsig.keyTag) {
                dnskey = dnsKeyRecord.payloadData;
            }
        }
    }
    if (dnskey == null) {
        throw new DNSSECValidationFailedException(q, records.size() + " " + rrsig.typeCovered + " record(s) are signed using an unknown key.");
    }
    UnverifiedReason unverifiedReason = verifier.verify(records, rrsig, dnskey);
    if (unverifiedReason != null) {
        result.add(unverifiedReason);
    }
    return result;
}
Also used : Record(org.minidns.record.Record) Data(org.minidns.record.Data) NoTrustAnchorReason(org.minidns.dnssec.UnverifiedReason.NoTrustAnchorReason) DNSKEY(org.minidns.record.DNSKEY) HashSet(java.util.HashSet)

Example 3 with DNSKEY

use of org.minidns.record.DNSKEY in project minidns by MiniDNS.

the class DNSSECClient method verifyAnswer.

private Set<UnverifiedReason> verifyAnswer(DNSMessage dnsMessage) throws IOException {
    Question q = dnsMessage.questions.get(0);
    List<Record<? extends Data>> answers = dnsMessage.answerSection;
    List<Record<? extends Data>> toBeVerified = dnsMessage.copyAnswers();
    VerifySignaturesResult verifiedSignatures = verifySignatures(q, answers, toBeVerified);
    Set<UnverifiedReason> result = verifiedSignatures.reasons;
    if (!result.isEmpty()) {
        return result;
    }
    // Keep SEPs separated, we only need one valid SEP.
    boolean sepSignatureValid = false;
    Set<UnverifiedReason> sepReasons = new HashSet<>();
    for (Iterator<Record<? extends Data>> iterator = toBeVerified.iterator(); iterator.hasNext(); ) {
        Record<DNSKEY> record = iterator.next().ifPossibleAs(DNSKEY.class);
        if (record == null) {
            continue;
        }
        // Verify all DNSKEYs as if it was a SEP. If we find a single SEP we are safe.
        Set<UnverifiedReason> reasons = verifySecureEntryPoint(q, record);
        if (reasons.isEmpty()) {
            sepSignatureValid = true;
        } else {
            sepReasons.addAll(reasons);
        }
        if (!verifiedSignatures.sepSignaturePresent) {
            LOGGER.finer("SEP key is not self-signed.");
        }
        iterator.remove();
    }
    if (verifiedSignatures.sepSignaturePresent && !sepSignatureValid) {
        result.addAll(sepReasons);
    }
    if (verifiedSignatures.sepSignatureRequired && !verifiedSignatures.sepSignaturePresent) {
        result.add(new NoSecureEntryPointReason(q.name.ace));
    }
    if (!toBeVerified.isEmpty()) {
        if (toBeVerified.size() != answers.size()) {
            throw new DNSSECValidationFailedException(q, "Only some records are signed!");
        } else {
            result.add(new NoSignaturesReason(q));
        }
    }
    return result;
}
Also used : Data(org.minidns.record.Data) DNSKEY(org.minidns.record.DNSKEY) NoSignaturesReason(org.minidns.dnssec.UnverifiedReason.NoSignaturesReason) Question(org.minidns.dnsmessage.Question) Record(org.minidns.record.Record) NoSecureEntryPointReason(org.minidns.dnssec.UnverifiedReason.NoSecureEntryPointReason) HashSet(java.util.HashSet)

Example 4 with DNSKEY

use of org.minidns.record.DNSKEY in project minidns by MiniDNS.

the class Verifier method verify.

public UnverifiedReason verify(Record<DNSKEY> dnskeyRecord, DelegatingDnssecRR ds) {
    DNSKEY dnskey = dnskeyRecord.payloadData;
    DigestCalculator digestCalculator = algorithmMap.getDsDigestCalculator(ds.digestType);
    if (digestCalculator == null) {
        return new AlgorithmNotSupportedReason(ds.digestTypeByte, ds.getType(), dnskeyRecord);
    }
    byte[] dnskeyData = dnskey.toByteArray();
    byte[] dnskeyOwner = dnskeyRecord.name.getBytes();
    byte[] combined = new byte[dnskeyOwner.length + dnskeyData.length];
    System.arraycopy(dnskeyOwner, 0, combined, 0, dnskeyOwner.length);
    System.arraycopy(dnskeyData, 0, combined, dnskeyOwner.length, dnskeyData.length);
    byte[] digest;
    try {
        digest = digestCalculator.digest(combined);
    } catch (Exception e) {
        return new AlgorithmExceptionThrownReason(ds.digestType, "DS", dnskeyRecord, e);
    }
    if (!ds.digestEquals(digest)) {
        throw new DNSSECValidationFailedException(dnskeyRecord, "SEP is not properly signed by parent DS!");
    }
    return null;
}
Also used : AlgorithmExceptionThrownReason(org.minidns.dnssec.UnverifiedReason.AlgorithmExceptionThrownReason) AlgorithmNotSupportedReason(org.minidns.dnssec.UnverifiedReason.AlgorithmNotSupportedReason) DNSKEY(org.minidns.record.DNSKEY) IOException(java.io.IOException)

Example 5 with DNSKEY

use of org.minidns.record.DNSKEY in project minidns by MiniDNS.

the class DNSSECClientTest method testNoSEPAtKSK.

@SuppressWarnings("unchecked")
@Test
public void testNoSEPAtKSK() throws IOException {
    DNSKEY comKSK = dnskey(DNSKEY.FLAG_ZONE, algorithm, publicKey(algorithm, comPrivateKSK));
    applyZones(client, signedRootZone(sign(rootKSK, "", rootPrivateKSK, algorithm, record("", rootKSK), record("", rootZSK)), sign(rootZSK, "", rootPrivateZSK, algorithm, record("com", ds("com", digestType, comKSK))), sign(rootZSK, "", rootPrivateZSK, algorithm, record("com", ns("ns.com"))), sign(rootZSK, "", rootPrivateZSK, algorithm, record("ns.com", a("1.1.1.1")))), signedZone("com", "ns.com", "1.1.1.1", sign(comKSK, "com", comPrivateKSK, algorithm, record("com", comKSK), record("com", comZSK)), sign(comZSK, "com", comPrivateZSK, algorithm, record("example.com", a("1.1.1.2")))));
    DNSMessage message = client.query("example.com", Record.TYPE.A);
    assertNotNull(message);
    assertTrue(message.authenticData);
    checkCorrectExampleMessage(message);
}
Also used : DNSKEY(org.minidns.record.DNSKEY) DNSMessage(org.minidns.dnsmessage.DNSMessage) Test(org.junit.Test)

Aggregations

DNSKEY (org.minidns.record.DNSKEY)8 Data (org.minidns.record.Data)4 Record (org.minidns.record.Record)4 HashSet (java.util.HashSet)3 Test (org.junit.Test)3 DNSMessage (org.minidns.dnsmessage.DNSMessage)3 NoSignaturesReason (org.minidns.dnssec.UnverifiedReason.NoSignaturesReason)2 NoTrustAnchorReason (org.minidns.dnssec.UnverifiedReason.NoTrustAnchorReason)2 IOException (java.io.IOException)1 PrivateKey (java.security.PrivateKey)1 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 LinkedList (java.util.LinkedList)1 Question (org.minidns.dnsmessage.Question)1 DNSSECWorld.generatePrivateKey (org.minidns.dnssec.DNSSECWorld.generatePrivateKey)1 AlgorithmExceptionThrownReason (org.minidns.dnssec.UnverifiedReason.AlgorithmExceptionThrownReason)1 AlgorithmNotSupportedReason (org.minidns.dnssec.UnverifiedReason.AlgorithmNotSupportedReason)1 NoActiveSignaturesReason (org.minidns.dnssec.UnverifiedReason.NoActiveSignaturesReason)1 NoSecureEntryPointReason (org.minidns.dnssec.UnverifiedReason.NoSecureEntryPointReason)1 EDNS (org.minidns.edns.EDNS)1