001/* 002 * Copyright 2015-2024 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 org.minidns.dnsmessage.DnsMessage; 014import org.minidns.dnsmessage.Question; 015import org.minidns.record.Data; 016import org.minidns.record.DelegatingDnssecRR; 017import org.minidns.record.Record; 018 019import java.io.IOException; 020import java.math.BigInteger; 021import java.security.spec.InvalidKeySpecException; 022import java.util.List; 023 024public class DnssecValidationFailedException extends IOException { 025 private static final long serialVersionUID = 5413184667629832742L; 026 027 public DnssecValidationFailedException(Question question, String reason) { 028 super("Validation of request to " + question + " failed: " + reason); 029 } 030 031 public DnssecValidationFailedException(String message) { 032 super(message); 033 } 034 035 public DnssecValidationFailedException(String message, Throwable cause) { 036 super(message, cause); 037 } 038 039 public DnssecValidationFailedException(Record<? extends Data> record, String reason) { 040 super("Validation of record " + record + " failed: " + reason); 041 } 042 043 public DnssecValidationFailedException(List<Record<? extends Data>> records, String reason) { 044 super("Validation of " + records.size() + " " + records.get(0).type + " record" + (records.size() > 1 ? "s" : "") + " failed: " + reason); 045 } 046 047 public static class DataMalformedException extends DnssecValidationFailedException { 048 049 /** 050 * 051 */ 052 private static final long serialVersionUID = 1L; 053 054 private final byte[] data; 055 056 public DataMalformedException(IOException exception, byte[] data) { 057 super("Malformed data", exception); 058 this.data = data; 059 } 060 061 public DataMalformedException(String message, IOException exception, byte[] data) { 062 super(message, exception); 063 this.data = data; 064 } 065 066 public byte[] getData() { 067 return data; 068 } 069 } 070 071 public static class DnssecInvalidKeySpecException extends DnssecValidationFailedException { 072 073 /** 074 * 075 */ 076 private static final long serialVersionUID = 1L; 077 078 public DnssecInvalidKeySpecException(InvalidKeySpecException exception) { 079 super("Invalid key spec", exception); 080 } 081 082 public DnssecInvalidKeySpecException(String message, InvalidKeySpecException exception, byte[] data) { 083 super(message, exception); 084 } 085 086 } 087 088 public static class AuthorityDoesNotContainSoa extends DnssecValidationFailedException { 089 090 /** 091 * 092 */ 093 private static final long serialVersionUID = 1L; 094 095 private final DnsMessage response; 096 097 public AuthorityDoesNotContainSoa(DnsMessage response) { 098 super("Autority does not contain SOA"); 099 this.response = response; 100 } 101 102 public DnsMessage getResponse() { 103 return response; 104 } 105 } 106 107 public static final class DigestComparisonFailedException extends DnssecValidationFailedException { 108 109 /** 110 * 111 */ 112 private static final long serialVersionUID = 1L; 113 114 private final Record<? extends Data> record; 115 private final DelegatingDnssecRR ds; 116 private final byte[] digest; 117 private final String digestHex; 118 119 private DigestComparisonFailedException(String message, Record<? extends Data> record, DelegatingDnssecRR ds, byte[] digest, String digestHex) { 120 super(message); 121 this.record = record; 122 this.ds = ds; 123 this.digest = digest; 124 this.digestHex = digestHex; 125 } 126 127 public Record<? extends Data> getRecord() { 128 return record; 129 } 130 131 public DelegatingDnssecRR getDelegaticDnssecRr() { 132 return ds; 133 } 134 135 public byte[] getDigest() { 136 return digest.clone(); 137 } 138 139 public String getDigestHex() { 140 return digestHex; 141 } 142 143 public static DigestComparisonFailedException from(Record<? extends Data> record, DelegatingDnssecRR ds, byte[] digest) { 144 BigInteger digestBigInteger = new BigInteger(1, digest); 145 String digestHex = digestBigInteger.toString(16).toUpperCase(); 146 147 String message = "Digest for " + record + " does not match. Digest of delegating DNSSEC RR " + ds + " is '" 148 + ds.getDigestHex() + "' while we calculated '" + digestHex + "'"; 149 return new DigestComparisonFailedException(message, record, ds, digest, digestHex); 150 } 151 } 152}