OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / javax / net / ssl / Session.java
1 /* SessionImpl.java -- concrete definition of SSLSession.
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;
40
41 import java.io.Serializable;
42
43 import java.security.Principal;
44 import java.security.SecureRandom;
45 import java.security.cert.Certificate;
46
47 import java.util.Arrays;
48 import java.util.HashMap;
49 import java.util.Set;
50
51 import javax.crypto.SealedObject;
52 import javax.net.ssl.SSLException;
53 import javax.net.ssl.SSLPeerUnverifiedException;
54 import javax.net.ssl.SSLSession;
55 import javax.net.ssl.SSLSessionBindingEvent;
56 import javax.net.ssl.SSLSessionBindingListener;
57 import javax.net.ssl.SSLSessionContext;
58 import javax.security.cert.X509Certificate;
59
60 /**
61  * A concrete implementation of the {@link SSLSession} interface. This
62  * class is provided to allow pluggable {@link AbstractSessionContext}
63  * implementations.
64  */
65 public abstract class Session implements SSLSession, Serializable
66 {
67   protected final long creationTime;
68   protected long lastAccessedTime;
69   protected int applicationBufferSize;
70   
71   protected ID sessionId;
72   protected Certificate[] localCerts;
73   protected Certificate[] peerCerts;
74   protected X509Certificate[] peerCertChain;
75   protected String peerHost;
76   protected int peerPort;
77   protected boolean peerVerified;
78   protected HashMap<String,Object> values;
79   protected boolean valid;
80   protected boolean truncatedMac = false;
81   transient protected SecureRandom random;
82   transient protected SSLSessionContext context;
83
84   protected Session()
85   {
86     creationTime = System.currentTimeMillis();
87     values = new HashMap<String, Object>();
88     applicationBufferSize = (1 << 14);
89   }
90
91   public void access()
92   {
93     lastAccessedTime = System.currentTimeMillis ();
94   }
95
96   public int getApplicationBufferSize()
97   {
98     return applicationBufferSize;
99   }
100
101   public String getCipherSuite()
102   {
103     return null;
104   }
105
106   public long getCreationTime()
107   {
108     return creationTime;
109   }
110
111   public byte[] getId()
112   {
113     return sessionId.id();
114   }
115
116   public ID id()
117   {
118     return sessionId;
119   }
120
121   public long getLastAccessedTime()
122   {
123     return lastAccessedTime;
124   }
125
126   public Certificate[] getLocalCertificates()
127   {
128     if (localCerts == null)
129       return null;
130     return (Certificate[]) localCerts.clone();
131   }
132
133   public Principal getLocalPrincipal()
134   {
135     if (localCerts != null)
136       {
137         if (localCerts[0] instanceof java.security.cert.X509Certificate)
138           return ((java.security.cert.X509Certificate) localCerts[0]).getSubjectDN();
139       }
140     return null;
141   }
142   
143   public int getPacketBufferSize()
144   {
145     return applicationBufferSize + 2048;
146   }
147   
148   public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
149   {
150     if (!peerVerified)
151       throw new SSLPeerUnverifiedException("peer not verified");
152     if (peerCerts == null)
153       return null;
154     return (Certificate[]) peerCerts.clone();
155   }
156
157   public X509Certificate[] getPeerCertificateChain()
158     throws SSLPeerUnverifiedException
159   {
160     if (!peerVerified)
161       throw new SSLPeerUnverifiedException("peer not verified");
162     if (peerCertChain == null)
163       return null;
164     return (X509Certificate[]) peerCertChain.clone();
165   }
166   
167   public String getPeerHost()
168   {
169     return peerHost;
170   }
171   
172   public int getPeerPort()
173   {
174     return peerPort;
175   }
176   
177   public Principal getPeerPrincipal() throws SSLPeerUnverifiedException
178   {
179     if (!peerVerified)
180       throw new SSLPeerUnverifiedException("peer not verified");
181     if (peerCertChain == null)
182       return null;
183     return peerCertChain[0].getSubjectDN();
184   }
185   
186   public SSLSessionContext getSessionContext()
187   {
188     return context;
189   }
190   
191   public String[] getValueNames()
192   {
193     Set<String> keys = this.values.keySet();
194     return keys.toArray(new String[keys.size()]);
195   }
196   
197   public Object getValue(String name)
198   {
199     return values.get(name);
200   }
201   
202   public void invalidate()
203   {
204     valid = false;
205   }
206   
207   public boolean isValid()
208   {
209     return valid;
210   }
211   
212   public void putValue(String name, Object value)
213   {
214     values.put(name, value);
215     try
216       {
217         if (value instanceof SSLSessionBindingListener)
218           ((SSLSessionBindingListener) value).valueBound
219             (new SSLSessionBindingEvent(this, name));
220       }
221     catch (Exception x)
222       {
223       }
224   }
225   
226   public void removeValue(String name)
227   {
228     Object value = values.remove(name);
229     try
230       {
231         if (value instanceof SSLSessionBindingListener)
232           ((SSLSessionBindingListener) value).valueUnbound
233             (new SSLSessionBindingEvent(this, name));
234       }
235     catch (Exception x)
236       {
237       }   
238   }
239   
240   public final boolean isTruncatedMac()
241   {
242     return truncatedMac;
243   }
244
245   /**
246    * Prepare this session for serialization. Private data will be encrypted
247    * with the given password, and this object will then be ready to be
248    * serialized.
249    * 
250    * @param password The password to protect this session with.
251    * @throws SSLException If encrypting this session's private data fails.
252    */
253   public abstract void prepare (char[] password) throws SSLException;
254   
255   /**
256    * Repair this session's private data after deserialization. This method
257    * will decrypt this session's private data, and prepare the session for
258    * use in new SSL connections.
259    * 
260    * @param password The password to decrypt the private data with.
261    * @throws SSLException
262    */
263   public abstract void repair(char[] password) throws SSLException;
264   
265   /**
266    * Get the private data of this session. This method may only be called
267    * after first calling {@link #prepare(char[])}.
268    * 
269    * @return The sealed private data.
270    * @throws SSLException If the private data have not been sealed.
271    */
272   public abstract SealedObject privateData() throws SSLException;
273   
274   /**
275    * Set the private data of this session.
276    * @param data
277    * @throws SSLException
278    */
279   public abstract void setPrivateData(SealedObject data) throws SSLException;
280
281   // Inner classes.
282   // -------------------------------------------------------------------------
283
284   /**
285    * An SSL or TLS session ID.
286    */
287   public static final class ID implements Comparable, Serializable
288   {
289
290     // Fields.
291     // -----------------------------------------------------------------------
292
293     static final long serialVersionUID = 7887036954666565936L;
294     /** The ID itself. */
295     private final byte[] id;
296
297     // Constructor.
298     // -----------------------------------------------------------------------
299
300     /**
301      * Creates a new ID.
302      *
303      * @param id The ID. The array is cloned.
304      */
305     public ID (final byte[] id)
306     {
307       if (id.length > 32)
308         throw new IllegalArgumentException ("session ID's are limited to 32 bytes");
309       this.id = (byte[]) id.clone();
310     }
311
312     // Instance methods.
313     // -----------------------------------------------------------------------
314
315     public byte[] id()
316     {
317       return (byte[]) id.clone();
318     }
319
320     public boolean equals(Object other)
321     {
322       if (!(other instanceof ID))
323         return false;
324       return Arrays.equals(id, ((ID) other).id);
325     }
326
327     public int hashCode()
328     {
329       int code = 0;
330       for (int i = 0; i < id.length; i++)
331         code |= (id[i] & 0xFF) << ((i & 3) << 3);
332       return code;
333     }
334
335     public int compareTo(Object other)
336     {
337       byte[] id2 = ((ID) other).id;
338       if (id.length != id2.length)
339         return (id.length < id2.length) ? -1 : 1;
340       for (int i = 0; i < id.length; i++)
341         {
342           if ((id[i] & 0xFF) < (id2[i] & 0xFF))
343             return -1;
344           if ((id[i] & 0xFF) > (id2[i] & 0xFF))
345             return 1;
346         }
347       return 0;
348     }
349
350     public String toString()
351     {
352       StringBuffer str = new StringBuffer (3 * id.length + 1);
353       for (int i = 0; i < id.length; i++)
354         {
355           int x = id[i] & 0xFF;
356           str.append (Character.forDigit ((x >>> 4) & 0xF, 16));
357           str.append (Character.forDigit (x & 0xF, 16));
358           if (i != id.length - 1)
359             str.append (':');
360         }
361       return str.toString ();
362     }
363   }
364 }