1 // Copyright (c) 2004 Brian Wellington (bwelling@xbill.org)
2 
3 package org.xbill.DNS;
4 
5 import java.io.*;
6 import java.net.*;
7 import org.xbill.DNS.utils.*;
8 
9 /**
10  * IPsec Keying Material (RFC 4025)
11  *
12  * @author Brian Wellington
13  */
14 
15 public class IPSECKEYRecord extends Record {
16 
17 private static final long serialVersionUID = 3050449702765909687L;
18 
19 public static class Algorithm {
Algorithm()20 	private Algorithm() {}
21 
22 	public static final int DSA = 1;
23 	public static final int RSA = 2;
24 }
25 
26 public static class Gateway {
Gateway()27 	private Gateway() {}
28 
29 	public static final int None = 0;
30 	public static final int IPv4 = 1;
31 	public static final int IPv6 = 2;
32 	public static final int Name = 3;
33 }
34 
35 private int precedence;
36 private int gatewayType;
37 private int algorithmType;
38 private Object gateway;
39 private byte [] key;
40 
IPSECKEYRecord()41 IPSECKEYRecord() {}
42 
43 Record
getObject()44 getObject() {
45 	return new IPSECKEYRecord();
46 }
47 
48 /**
49  * Creates an IPSECKEY Record from the given data.
50  * @param precedence The record's precedence.
51  * @param gatewayType The record's gateway type.
52  * @param algorithmType The record's algorithm type.
53  * @param gateway The record's gateway.
54  * @param key The record's public key.
55  */
56 public
IPSECKEYRecord(Name name, int dclass, long ttl, int precedence, int gatewayType, int algorithmType, Object gateway, byte [] key)57 IPSECKEYRecord(Name name, int dclass, long ttl, int precedence,
58 	       int gatewayType, int algorithmType, Object gateway,
59 	       byte [] key)
60 {
61 	super(name, Type.IPSECKEY, dclass, ttl);
62 	this.precedence = checkU8("precedence", precedence);
63 	this.gatewayType = checkU8("gatewayType", gatewayType);
64 	this.algorithmType = checkU8("algorithmType", algorithmType);
65 	switch (gatewayType) {
66 	case Gateway.None:
67 		this.gateway = null;
68 		break;
69 	case Gateway.IPv4:
70 		if (!(gateway instanceof InetAddress))
71 			throw new IllegalArgumentException("\"gateway\" " +
72 							   "must be an IPv4 " +
73 							   "address");
74 		this.gateway = gateway;
75 		break;
76 	case Gateway.IPv6:
77 		if (!(gateway instanceof Inet6Address))
78 			throw new IllegalArgumentException("\"gateway\" " +
79 							   "must be an IPv6 " +
80 							   "address");
81 		this.gateway = gateway;
82 		break;
83 	case Gateway.Name:
84 		if (!(gateway instanceof Name))
85 			throw new IllegalArgumentException("\"gateway\" " +
86 							   "must be a DNS " +
87 							   "name");
88 		this.gateway = checkName("gateway", (Name) gateway);
89 		break;
90 	default:
91 		throw new IllegalArgumentException("\"gatewayType\" " +
92 						   "must be between 0 and 3");
93 	}
94 
95 	this.key = key;
96 }
97 
98 void
rrFromWire(DNSInput in)99 rrFromWire(DNSInput in) throws IOException {
100 	precedence = in.readU8();
101 	gatewayType = in.readU8();
102 	algorithmType = in.readU8();
103 	switch (gatewayType) {
104 	case Gateway.None:
105 		gateway = null;
106 		break;
107 	case Gateway.IPv4:
108 		gateway = InetAddress.getByAddress(in.readByteArray(4));
109 		break;
110 	case Gateway.IPv6:
111 		gateway = InetAddress.getByAddress(in.readByteArray(16));
112 		break;
113 	case Gateway.Name:
114 		gateway = new Name(in);
115 		break;
116 	default:
117 		throw new WireParseException("invalid gateway type");
118 	}
119 	if (in.remaining() > 0)
120 		key = in.readByteArray();
121 }
122 
123 void
rdataFromString(Tokenizer st, Name origin)124 rdataFromString(Tokenizer st, Name origin) throws IOException {
125 	precedence = st.getUInt8();
126 	gatewayType = st.getUInt8();
127 	algorithmType = st.getUInt8();
128 	switch (gatewayType) {
129 	case Gateway.None:
130 		String s = st.getString();
131 		if (!s.equals("."))
132 			throw new TextParseException("invalid gateway format");
133 		gateway = null;
134 		break;
135 	case Gateway.IPv4:
136 		gateway = st.getAddress(Address.IPv4);
137 		break;
138 	case Gateway.IPv6:
139 		gateway = st.getAddress(Address.IPv6);
140 		break;
141 	case Gateway.Name:
142 		gateway = st.getName(origin);
143 		break;
144 	default:
145 		throw new WireParseException("invalid gateway type");
146 	}
147 	key = st.getBase64(false);
148 }
149 
150 String
rrToString()151 rrToString() {
152 	StringBuffer sb = new StringBuffer();
153 	sb.append(precedence);
154 	sb.append(" ");
155 	sb.append(gatewayType);
156 	sb.append(" ");
157 	sb.append(algorithmType);
158 	sb.append(" ");
159 	switch (gatewayType) {
160 	case Gateway.None:
161 		sb.append(".");
162 		break;
163 	case Gateway.IPv4:
164 	case Gateway.IPv6:
165 		InetAddress gatewayAddr = (InetAddress) gateway;
166 		sb.append(gatewayAddr.getHostAddress());
167 		break;
168 	case Gateway.Name:
169 		sb.append(gateway);
170 		break;
171 	}
172 	if (key != null) {
173 		sb.append(" ");
174 		sb.append(base64.toString(key));
175 	}
176 	return sb.toString();
177 }
178 
179 /** Returns the record's precedence. */
180 public int
getPrecedence()181 getPrecedence() {
182 	return precedence;
183 }
184 
185 /** Returns the record's gateway type. */
186 public int
getGatewayType()187 getGatewayType() {
188 	return gatewayType;
189 }
190 
191 /** Returns the record's algorithm type. */
192 public int
getAlgorithmType()193 getAlgorithmType() {
194 	return algorithmType;
195 }
196 
197 /** Returns the record's gateway. */
198 public Object
getGateway()199 getGateway() {
200 	return gateway;
201 }
202 
203 /** Returns the record's public key */
204 public byte []
getKey()205 getKey() {
206 	return key;
207 }
208 
209 void
rrToWire(DNSOutput out, Compression c, boolean canonical)210 rrToWire(DNSOutput out, Compression c, boolean canonical) {
211 	out.writeU8(precedence);
212 	out.writeU8(gatewayType);
213 	out.writeU8(algorithmType);
214 	switch (gatewayType) {
215 	case Gateway.None:
216 		break;
217 	case Gateway.IPv4:
218 	case Gateway.IPv6:
219 		InetAddress gatewayAddr = (InetAddress) gateway;
220 		out.writeByteArray(gatewayAddr.getAddress());
221 		break;
222 	case Gateway.Name:
223 		Name gatewayName = (Name) gateway;
224 		gatewayName.toWire(out, null, canonical);
225 		break;
226 	}
227 	if (key != null)
228 		out.writeByteArray(key);
229 }
230 
231 }
232