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}