1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49:
50: import ;
51:
52:
79: public class TrustedAuthorities extends Value
80: implements Iterable<TrustedAuthorities.TrustedAuthority>
81: {
82: private final ByteBuffer buffer;
83:
84: public TrustedAuthorities(final ByteBuffer buffer)
85: {
86: this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
87: }
88:
89:
90:
91: public int length()
92: {
93: return 2 + (buffer.getShort(0) & 0xFFFF);
94: }
95:
96: public ByteBuffer buffer()
97: {
98: return (ByteBuffer) buffer.duplicate().limit(length());
99: }
100:
101: public int size()
102: {
103: int len = buffer.getShort(0) & 0xFFFF;
104: int n = 0;
105: for (int i = 2; i < len; i++)
106: {
107: TrustedAuthority auth =
108: new TrustedAuthority((ByteBuffer) buffer.duplicate().position(i));
109: i += auth.length();
110: n++;
111: }
112: return n;
113: }
114:
115: public TrustedAuthority get(final int index)
116: {
117: int len = buffer.getShort(0) & 0xFFFF;
118: int n = 0;
119: int i = 2;
120: while (i < len && n <= index)
121: {
122: TrustedAuthority auth =
123: new TrustedAuthority((ByteBuffer) buffer.duplicate().position(i));
124: if (n == index)
125: return auth;
126: i += auth.length();
127: n++;
128: }
129: throw new IndexOutOfBoundsException();
130: }
131:
132: public String toString()
133: {
134: return toString(null);
135: }
136:
137: public String toString(String prefix)
138: {
139: StringWriter str = new StringWriter();
140: PrintWriter out = new PrintWriter(str);
141: if (prefix != null) out.print(prefix);
142: out.println("struct {");
143: String subprefix = " ";
144: if (prefix != null)
145: subprefix = prefix + subprefix;
146: for(TrustedAuthority ta : this)
147: out.println(ta);
148: if (prefix != null) out.print(prefix);
149: out.print("} TrustedAuthorities;");
150: return str.toString();
151: }
152:
153: public Iterator<TrustedAuthority> iterator()
154: {
155: return new AuthoritiesIterator();
156: }
157:
158: public class AuthoritiesIterator implements Iterator<TrustedAuthority>
159: {
160: private int index;
161:
162: public AuthoritiesIterator()
163: {
164: index = 0;
165: }
166:
167: public TrustedAuthority next() throws NoSuchElementException
168: {
169: try
170: {
171: return get(index++);
172: }
173: catch (IndexOutOfBoundsException ioobe)
174: {
175: throw new NoSuchElementException();
176: }
177: }
178:
179: public boolean hasNext()
180: {
181: return index < size();
182: }
183:
184: public void remove()
185: {
186: throw new UnsupportedOperationException();
187: }
188: }
189:
190: public static class TrustedAuthority implements Constructed
191: {
192: private final ByteBuffer buffer;
193:
194: public TrustedAuthority(final ByteBuffer buffer)
195: {
196: this.buffer = buffer;
197: }
198:
199: public int length()
200: {
201: switch (type().getValue())
202: {
203: case 0: return 1;
204: case 1:
205: case 3: return 21;
206: case 2: return 3 + (buffer.getShort(1) & 0xFFFF);
207: }
208: throw new IllegalArgumentException("unknown authority type");
209: }
210:
211: public byte[] sha1Hash()
212: {
213: IdentifierType t = type();
214: if (t != IdentifierType.CERT_SHA1_HASH
215: && t != IdentifierType.KEY_SHA1_HASH)
216: throw new IllegalArgumentException(t + " does not have a hash value");
217: byte[] b = new byte[20];
218: ((ByteBuffer) buffer.duplicate().position(1)).get(b);
219: return b;
220: }
221:
222: public X500Principal name()
223: {
224: int len = buffer.getShort(1) & 0xFFFF;
225: byte[] b = new byte[len];
226: ((ByteBuffer) buffer.duplicate().position(3)).get(b);
227: return new X500Principal(b);
228: }
229:
230: public IdentifierType type()
231: {
232: switch (buffer.get(0))
233: {
234: case 0: return IdentifierType.PRE_AGREED;
235: case 1: return IdentifierType.KEY_SHA1_HASH;
236: case 2: return IdentifierType.X509_NAME;
237: case 3: return IdentifierType.CERT_SHA1_HASH;
238: }
239:
240: throw new IllegalArgumentException("invalid IdentifierType");
241: }
242:
243: public String toString()
244: {
245: return toString(null);
246: }
247:
248: public String toString(String prefix)
249: {
250: StringWriter str = new StringWriter();
251: PrintWriter out = new PrintWriter(str);
252: if (prefix != null) out.print(prefix);
253: out.println("struct {");
254: if (prefix != null) out.print(prefix);
255: out.print(" identifier_type = ");
256: out.print(type());
257: out.println(";");
258: switch (type().getValue())
259: {
260: case 0: break;
261: case 1:
262: case 3:
263: if (prefix != null) out.print(prefix);
264: out.print(" sha1_hash = ");
265: out.print(Util.toHexString(sha1Hash(), ':'));
266: out.println(";");
267: break;
268:
269: case 2:
270: if (prefix != null) out.print(prefix);
271: out.print(" name = ");
272: out.print(name());
273: out.println(";");
274: }
275: if (prefix != null) out.print(prefix);
276: out.print("} TrustedAuthority;");
277: return str.toString();
278: }
279: }
280:
281: public static enum IdentifierType
282: {
283: PRE_AGREED (0), KEY_SHA1_HASH (1), X509_NAME (2), CERT_SHA1_HASH (3);
284:
285: private final int value;
286:
287: private IdentifierType(final int value)
288: {
289: this.value = value;
290: }
291:
292: public int getValue()
293: {
294: return value;
295: }
296: }
297: }