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