OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / javax / net / ssl / provider / TrustedAuthorities.java
1 /* TrustedAuthorities.java
2    Copyright (C) 2006  Free Software Foundation, Inc.
3
4 This file is a part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or (at
9 your option) any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 USA
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version.  */
37
38
39 package gnu.javax.net.ssl.provider;
40
41 import gnu.java.security.x509.X500DistinguishedName;
42 import gnu.javax.net.ssl.provider.Extension.Value;
43
44 import java.io.PrintWriter;
45 import java.io.StringWriter;
46 import java.nio.ByteBuffer;
47 import java.nio.ByteOrder;
48 import java.util.Iterator;
49 import java.util.NoSuchElementException;
50
51 import javax.security.auth.x500.X500Principal;
52
53 /**
54  * The trusted authorities hello extension.
55  * 
56  * <pre>
57 struct {
58   TrustedAuthority trusted_authorities_list&lt;0..2^16-1&gt;;
59 } TrustedAuthorities;
60
61 struct {
62   IdentifierType identifier_type;
63   select (identifier_type) {
64     case pre_agreed: struct {};
65     case key_sha1_hash: SHA1Hash;
66     case x509_name: DistinguishedName;
67     case cert_sha1_hash: SHA1Hash;
68   } identifier;
69 } TrustedAuthority;
70
71 enum {
72   pre_agreed(0), key_sha1_hash(1), x509_name(2),
73   cert_sha1_hash(3), (255)
74 } IdentifierType;
75
76 opaque DistinguishedName&lt;1..2^16-1&gt;;</pre>
77  * 
78  * @author csm
79  */
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   // XXX really implement Builder.
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 }