1// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.*;
6import java.security.PublicKey;
7
8import 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
16abstract class KEYBase extends Record {
17
18private static final long serialVersionUID = 3469321722693285454L;
19
20protected int flags, proto, alg;
21protected byte [] key;
22protected int footprint = -1;
23protected PublicKey publicKey = null;
24
25protected
26KEYBase() {}
27
28public
29KEYBase(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
39void
40rrFromWire(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 */
49String
50rrToString() {
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 */
74public int
75getFlags() {
76	return flags;
77}
78
79/**
80 * Returns the protocol that the key was created for
81 */
82public int
83getProtocol() {
84	return proto;
85}
86
87/**
88 * Returns the key's algorithm
89 */
90public int
91getAlgorithm() {
92	return alg;
93}
94
95/**
96 * Returns the binary data representing the key
97 */
98public byte []
99getKey() {
100	return key;
101}
102
103/**
104 * Returns the key's footprint (after computing it)
105 */
106public int
107getFootprint() {
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 */
143public PublicKey
144getPublicKey() throws DNSSEC.DNSSECException {
145	if (publicKey != null)
146		return publicKey;
147
148	publicKey = DNSSEC.toPublicKey(this);
149	return publicKey;
150}
151
152void
153rrToWire(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