1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) xbill.org) 2 3 package org.xbill.DNS; 4 5 import java.io.*; 6 import java.security.PublicKey; 7 8 import org.xbill.DNS.utils.*; 9 10 /** 11 * The base class for KEY/DNSKEY records, which have identical formats 12 * 13 * @author Brian Wellington 14 */ 15 16 abstract class KEYBase extends Record { 17 18 private static final long serialVersionUID = 3469321722693285454L; 19 20 protected int flags, proto, alg; 21 protected byte [] key; 22 protected int footprint = -1; 23 protected PublicKey publicKey = null; 24 25 protected 26 KEYBase() {} 27 28 public 29 KEYBase(Name name, int type, int dclass, long ttl, int flags, int proto, 30 int alg, byte [] key) 31 { 32 super(name, type, dclass, ttl); 33 this.flags = checkU16("flags", flags); 34 this.proto = checkU8("proto", proto); 35 this.alg = checkU8("alg", alg); 36 this.key = key; 37 } 38 39 void 40 rrFromWire(DNSInput in) throws IOException { 41 flags = in.readU16(); 42 proto = in.readU8(); 43 alg = in.readU8(); 44 if (in.remaining() > 0) 45 key = in.readByteArray(); 46 } 47 48 /** Converts the DNSKEY/KEY Record to a String */ 49 String 50 rrToString() { 51 StringBuffer sb = new StringBuffer(); 52 sb.append(flags); 53 sb.append(" "); 54 sb.append(proto); 55 sb.append(" "); 56 sb.append(alg); 57 if (key != null) { 58 if (Options.check("multiline")) { 59 sb.append(" (\n"); 60 sb.append(base64.formatString(key, 64, "\t", true)); 61 sb.append(" ; key_tag = "); 62 sb.append(getFootprint()); 63 } else { 64 sb.append(" "); 65 sb.append(base64.toString(key)); 66 } 67 } 68 return sb.toString(); 69 } 70 71 /** 72 * Returns the flags describing the key's properties 73 */ 74 public int 75 getFlags() { 76 return flags; 77 } 78 79 /** 80 * Returns the protocol that the key was created for 81 */ 82 public int 83 getProtocol() { 84 return proto; 85 } 86 87 /** 88 * Returns the key's algorithm 89 */ 90 public int 91 getAlgorithm() { 92 return alg; 93 } 94 95 /** 96 * Returns the binary data representing the key 97 */ 98 public byte [] 99 getKey() { 100 return key; 101 } 102 103 /** 104 * Returns the key's footprint (after computing it) 105 */ 106 public int 107 getFootprint() { 108 if (footprint >= 0) 109 return footprint; 110 111 int foot = 0; 112 113 DNSOutput out = new DNSOutput(); 114 rrToWire(out, null, false); 115 byte [] rdata = out.toByteArray(); 116 117 if (alg == DNSSEC.Algorithm.RSAMD5) { 118 int d1 = rdata[rdata.length - 3] & 0xFF; 119 int d2 = rdata[rdata.length - 2] & 0xFF; 120 foot = (d1 << 8) + d2; 121 } 122 else { 123 int i; 124 for (i = 0; i < rdata.length - 1; i += 2) { 125 int d1 = rdata[i] & 0xFF; 126 int d2 = rdata[i + 1] & 0xFF; 127 foot += ((d1 << 8) + d2); 128 } 129 if (i < rdata.length) { 130 int d1 = rdata[i] & 0xFF; 131 foot += (d1 << 8); 132 } 133 foot += ((foot >> 16) & 0xFFFF); 134 } 135 footprint = (foot & 0xFFFF); 136 return footprint; 137 } 138 139 /** 140 * Returns a PublicKey corresponding to the data in this key. 141 * @throws DNSSEC.DNSSECException The key could not be converted. 142 */ 143 public PublicKey 144 getPublicKey() throws DNSSEC.DNSSECException { 145 if (publicKey != null) 146 return publicKey; 147 148 publicKey = DNSSEC.toPublicKey(this); 149 return publicKey; 150 } 151 152 void 153 rrToWire(DNSOutput out, Compression c, boolean canonical) { 154 out.writeU16(flags); 155 out.writeU8(proto); 156 out.writeU8(alg); 157 if (key != null) 158 out.writeByteArray(key); 159 } 160 161 } 162