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