1 // Copyright (c) 1999-2004 Brian Wellington (bwelling@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
KEYBase()26 KEYBase() {}
27
28 public
KEYBase(Name name, int type, int dclass, long ttl, int flags, int proto, int alg, byte [] key)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
rrFromWire(DNSInput in)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
rrToString()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
getFlags()75 getFlags() {
76 return flags;
77 }
78
79 /**
80 * Returns the protocol that the key was created for
81 */
82 public int
getProtocol()83 getProtocol() {
84 return proto;
85 }
86
87 /**
88 * Returns the key's algorithm
89 */
90 public int
getAlgorithm()91 getAlgorithm() {
92 return alg;
93 }
94
95 /**
96 * Returns the binary data representing the key
97 */
98 public byte []
getKey()99 getKey() {
100 return key;
101 }
102
103 /**
104 * Returns the key's footprint (after computing it)
105 */
106 public int
getFootprint()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
getPublicKey()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
rrToWire(DNSOutput out, Compression c, boolean canonical)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