001/*
002 * Copyright 2015-2018 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.dnssec;
012
013import java.util.Collections;
014import java.util.List;
015
016import org.minidns.constants.DnssecConstants.DigestAlgorithm;
017import org.minidns.dnsmessage.Question;
018import org.minidns.record.DNSKEY;
019import org.minidns.record.Data;
020import org.minidns.record.RRSIG;
021import org.minidns.record.Record;
022import org.minidns.record.Record.TYPE;
023
024public abstract class UnverifiedReason {
025    public abstract String getReasonString();
026
027    @Override
028    public String toString() {
029        return getReasonString();
030    }
031
032    @Override
033    public int hashCode() {
034        return getReasonString().hashCode();
035    }
036
037    @Override
038    public boolean equals(Object obj) {
039        return obj instanceof UnverifiedReason && ((UnverifiedReason) obj).getReasonString().equals(getReasonString());
040    }
041
042    public static class AlgorithmNotSupportedReason extends UnverifiedReason {
043        private final String algorithm;
044        private final TYPE type;
045        private final Record<? extends Data> record;
046
047        public AlgorithmNotSupportedReason(byte algorithm, TYPE type, Record<? extends Data> record) {
048            this.algorithm = Integer.toString(algorithm & 0xff);
049            this.type = type;
050            this.record = record;
051        }
052
053        @Override
054        public String getReasonString() {
055            return type.name() + " algorithm " + algorithm + " required to verify " + record.name + " is unknown or not supported by platform";
056        }
057    }
058
059    public static class AlgorithmExceptionThrownReason extends UnverifiedReason {
060        private final int algorithmNumber;
061        private final String kind;
062        private final Exception reason;
063        private final Record<? extends Data> record;
064
065        public AlgorithmExceptionThrownReason(DigestAlgorithm algorithm, String kind, Record<? extends Data> record, Exception reason) {
066            this.algorithmNumber = algorithm.value;
067            this.kind = kind;
068            this.record = record;
069            this.reason = reason;
070        }
071
072        @Override
073        public String getReasonString() {
074            return kind + " algorithm " + algorithmNumber + " threw exception while verifying " + record.name + ": " + reason;
075        }
076    }
077
078    public static class ConflictsWithSep extends UnverifiedReason {
079        private final Record<DNSKEY> record;
080
081        public ConflictsWithSep(Record<DNSKEY> record) {
082            this.record = record;
083        }
084
085        @Override
086        public String getReasonString() {
087            return "Zone " + record.name.ace + " is in list of known SEPs, but DNSKEY from response mismatches!";
088        }
089    }
090
091    public static class NoTrustAnchorReason extends UnverifiedReason {
092        private final String zone;
093
094        public NoTrustAnchorReason(String zone) {
095            this.zone = zone;
096        }
097
098        @Override
099        public String getReasonString() {
100            return "No trust anchor was found for zone " + zone + ". Try enabling DLV";
101        }
102    }
103
104    public static class NoSecureEntryPointReason extends UnverifiedReason {
105        private final String zone;
106
107        public NoSecureEntryPointReason(String zone) {
108            this.zone = zone;
109        }
110
111        @Override
112        public String getReasonString() {
113            return "No secure entry point was found for zone " + zone;
114        }
115    }
116
117    public static class NoRootSecureEntryPointReason extends UnverifiedReason {
118        public NoRootSecureEntryPointReason() {
119        }
120
121        @Override
122        public String getReasonString() {
123            return "No secure entry point was found for the root zone (\"Did you forget to configure a root SEP?\")";
124        }
125    }
126
127    public static class NoSignaturesReason extends UnverifiedReason {
128        private final Question question;
129
130        public NoSignaturesReason(Question question) {
131            this.question = question;
132        }
133
134        @Override
135        public String getReasonString() {
136            return "No signatures were attached to answer on question for " + question.type + " at " + question.name;
137        }
138    }
139
140    public static class NoActiveSignaturesReason extends UnverifiedReason {
141        private final Question question;
142        private final List<RRSIG> outdatedRrSigs;
143
144        public NoActiveSignaturesReason(Question question, List<RRSIG> outdatedRrSigs) {
145            this.question = question;
146            assert !outdatedRrSigs.isEmpty();
147            this.outdatedRrSigs = Collections.unmodifiableList(outdatedRrSigs);
148        }
149
150        @Override
151        public String getReasonString() {
152            return "No currently active signatures were attached to answer on question for " + question.type + " at " + question.name;
153        }
154
155        public List<RRSIG> getOutdatedRrSigs() {
156            return outdatedRrSigs;
157        }
158    }
159
160    public static class NSECDoesNotMatchReason extends UnverifiedReason {
161        private final Question question;
162        private final Record<? extends Data> record;
163
164        public NSECDoesNotMatchReason(Question question, Record<? extends Data> record) {
165            this.question = question;
166            this.record = record;
167        }
168
169        @Override
170        public String getReasonString() {
171            return "NSEC " + record.name + " does nat match question for " + question.type + " at " + question.name;
172        }
173    }
174}