mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			367 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			367 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Java
		
	
	
	
| /* SessionImpl.java -- concrete definition of SSLSession.
 | |
|    Copyright (C) 2006  Free Software Foundation, Inc.
 | |
| 
 | |
| This file is a part of GNU Classpath.
 | |
| 
 | |
| GNU Classpath is free software; you can redistribute it and/or modify
 | |
| it under the terms of the GNU General Public License as published by
 | |
| the Free Software Foundation; either version 2 of the License, or (at
 | |
| your option) any later version.
 | |
| 
 | |
| GNU Classpath is distributed in the hope that it will be useful, but
 | |
| WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License
 | |
| along with GNU Classpath; if not, write to the Free Software
 | |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 | |
| USA
 | |
| 
 | |
| Linking this library statically or dynamically with other modules is
 | |
| making a combined work based on this library.  Thus, the terms and
 | |
| conditions of the GNU General Public License cover the whole
 | |
| combination.
 | |
| 
 | |
| As a special exception, the copyright holders of this library give you
 | |
| permission to link this library with independent modules to produce an
 | |
| executable, regardless of the license terms of these independent
 | |
| modules, and to copy and distribute the resulting executable under
 | |
| terms of your choice, provided that you also meet, for each linked
 | |
| independent module, the terms and conditions of the license of that
 | |
| module.  An independent module is a module which is not derived from
 | |
| or based on this library.  If you modify this library, you may extend
 | |
| this exception to your version of the library, but you are not
 | |
| obligated to do so.  If you do not wish to do so, delete this
 | |
| exception statement from your version.  */
 | |
| 
 | |
| 
 | |
| package gnu.javax.net.ssl;
 | |
| 
 | |
| import gnu.java.lang.CPStringBuilder;
 | |
| 
 | |
| import java.io.Serializable;
 | |
| 
 | |
| import java.security.Principal;
 | |
| import java.security.SecureRandom;
 | |
| import java.security.cert.Certificate;
 | |
| 
 | |
| import java.util.Arrays;
 | |
| import java.util.HashMap;
 | |
| import java.util.Set;
 | |
| 
 | |
| import javax.crypto.SealedObject;
 | |
| import javax.net.ssl.SSLException;
 | |
| import javax.net.ssl.SSLPeerUnverifiedException;
 | |
| import javax.net.ssl.SSLSession;
 | |
| import javax.net.ssl.SSLSessionBindingEvent;
 | |
| import javax.net.ssl.SSLSessionBindingListener;
 | |
| import javax.net.ssl.SSLSessionContext;
 | |
| import javax.security.cert.X509Certificate;
 | |
| 
 | |
| /**
 | |
|  * A concrete implementation of the {@link SSLSession} interface. This
 | |
|  * class is provided to allow pluggable {@link AbstractSessionContext}
 | |
|  * implementations.
 | |
|  */
 | |
| public abstract class Session implements SSLSession, Serializable
 | |
| {
 | |
|   protected final long creationTime;
 | |
|   protected long lastAccessedTime;
 | |
|   protected int applicationBufferSize;
 | |
| 
 | |
|   protected ID sessionId;
 | |
|   protected Certificate[] localCerts;
 | |
|   protected Certificate[] peerCerts;
 | |
|   protected X509Certificate[] peerCertChain;
 | |
|   protected String peerHost;
 | |
|   protected int peerPort;
 | |
|   protected boolean peerVerified;
 | |
|   protected HashMap<String,Object> values;
 | |
|   protected boolean valid;
 | |
|   protected boolean truncatedMac = false;
 | |
|   transient protected SecureRandom random;
 | |
|   transient protected SSLSessionContext context;
 | |
| 
 | |
|   protected Session()
 | |
|   {
 | |
|     creationTime = System.currentTimeMillis();
 | |
|     values = new HashMap<String, Object>();
 | |
|     applicationBufferSize = (1 << 14);
 | |
|   }
 | |
| 
 | |
|   public void access()
 | |
|   {
 | |
|     lastAccessedTime = System.currentTimeMillis ();
 | |
|   }
 | |
| 
 | |
|   public int getApplicationBufferSize()
 | |
|   {
 | |
|     return applicationBufferSize;
 | |
|   }
 | |
| 
 | |
|   public String getCipherSuite()
 | |
|   {
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   public long getCreationTime()
 | |
|   {
 | |
|     return creationTime;
 | |
|   }
 | |
| 
 | |
|   public byte[] getId()
 | |
|   {
 | |
|     return sessionId.id();
 | |
|   }
 | |
| 
 | |
|   public ID id()
 | |
|   {
 | |
|     return sessionId;
 | |
|   }
 | |
| 
 | |
|   public long getLastAccessedTime()
 | |
|   {
 | |
|     return lastAccessedTime;
 | |
|   }
 | |
| 
 | |
|   public Certificate[] getLocalCertificates()
 | |
|   {
 | |
|     if (localCerts == null)
 | |
|       return null;
 | |
|     return (Certificate[]) localCerts.clone();
 | |
|   }
 | |
| 
 | |
|   public Principal getLocalPrincipal()
 | |
|   {
 | |
|     if (localCerts != null)
 | |
|       {
 | |
|         if (localCerts[0] instanceof java.security.cert.X509Certificate)
 | |
|           return ((java.security.cert.X509Certificate) localCerts[0]).getSubjectDN();
 | |
|       }
 | |
|     return null;
 | |
|   }
 | |
| 
 | |
|   public int getPacketBufferSize()
 | |
|   {
 | |
|     return applicationBufferSize + 2048;
 | |
|   }
 | |
| 
 | |
|   public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
 | |
|   {
 | |
|     if (!peerVerified)
 | |
|       throw new SSLPeerUnverifiedException("peer not verified");
 | |
|     if (peerCerts == null)
 | |
|       return null;
 | |
|     return (Certificate[]) peerCerts.clone();
 | |
|   }
 | |
| 
 | |
|   public X509Certificate[] getPeerCertificateChain()
 | |
|     throws SSLPeerUnverifiedException
 | |
|   {
 | |
|     if (!peerVerified)
 | |
|       throw new SSLPeerUnverifiedException("peer not verified");
 | |
|     if (peerCertChain == null)
 | |
|       return null;
 | |
|     return (X509Certificate[]) peerCertChain.clone();
 | |
|   }
 | |
| 
 | |
|   public String getPeerHost()
 | |
|   {
 | |
|     return peerHost;
 | |
|   }
 | |
| 
 | |
|   public int getPeerPort()
 | |
|   {
 | |
|     return peerPort;
 | |
|   }
 | |
| 
 | |
|   public Principal getPeerPrincipal() throws SSLPeerUnverifiedException
 | |
|   {
 | |
|     if (!peerVerified)
 | |
|       throw new SSLPeerUnverifiedException("peer not verified");
 | |
|     if (peerCertChain == null)
 | |
|       return null;
 | |
|     return peerCertChain[0].getSubjectDN();
 | |
|   }
 | |
| 
 | |
|   public SSLSessionContext getSessionContext()
 | |
|   {
 | |
|     return context;
 | |
|   }
 | |
| 
 | |
|   public String[] getValueNames()
 | |
|   {
 | |
|     Set<String> keys = this.values.keySet();
 | |
|     return keys.toArray(new String[keys.size()]);
 | |
|   }
 | |
| 
 | |
|   public Object getValue(String name)
 | |
|   {
 | |
|     return values.get(name);
 | |
|   }
 | |
| 
 | |
|   public void invalidate()
 | |
|   {
 | |
|     valid = false;
 | |
|   }
 | |
| 
 | |
|   public boolean isValid()
 | |
|   {
 | |
|     return valid;
 | |
|   }
 | |
| 
 | |
|   public void putValue(String name, Object value)
 | |
|   {
 | |
|     values.put(name, value);
 | |
|     try
 | |
|       {
 | |
|         if (value instanceof SSLSessionBindingListener)
 | |
|           ((SSLSessionBindingListener) value).valueBound
 | |
|             (new SSLSessionBindingEvent(this, name));
 | |
|       }
 | |
|     catch (Exception x)
 | |
|       {
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public void removeValue(String name)
 | |
|   {
 | |
|     Object value = values.remove(name);
 | |
|     try
 | |
|       {
 | |
|         if (value instanceof SSLSessionBindingListener)
 | |
|           ((SSLSessionBindingListener) value).valueUnbound
 | |
|             (new SSLSessionBindingEvent(this, name));
 | |
|       }
 | |
|     catch (Exception x)
 | |
|       {
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   public final boolean isTruncatedMac()
 | |
|   {
 | |
|     return truncatedMac;
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * Prepare this session for serialization. Private data will be encrypted
 | |
|    * with the given password, and this object will then be ready to be
 | |
|    * serialized.
 | |
|    *
 | |
|    * @param password The password to protect this session with.
 | |
|    * @throws SSLException If encrypting this session's private data fails.
 | |
|    */
 | |
|   public abstract void prepare (char[] password) throws SSLException;
 | |
| 
 | |
|   /**
 | |
|    * Repair this session's private data after deserialization. This method
 | |
|    * will decrypt this session's private data, and prepare the session for
 | |
|    * use in new SSL connections.
 | |
|    *
 | |
|    * @param password The password to decrypt the private data with.
 | |
|    * @throws SSLException
 | |
|    */
 | |
|   public abstract void repair(char[] password) throws SSLException;
 | |
| 
 | |
|   /**
 | |
|    * Get the private data of this session. This method may only be called
 | |
|    * after first calling {@link #prepare(char[])}.
 | |
|    *
 | |
|    * @return The sealed private data.
 | |
|    * @throws SSLException If the private data have not been sealed.
 | |
|    */
 | |
|   public abstract SealedObject privateData() throws SSLException;
 | |
| 
 | |
|   /**
 | |
|    * Set the private data of this session.
 | |
|    * @param data
 | |
|    * @throws SSLException
 | |
|    */
 | |
|   public abstract void setPrivateData(SealedObject data) throws SSLException;
 | |
| 
 | |
|   // Inner classes.
 | |
|   // -------------------------------------------------------------------------
 | |
| 
 | |
|   /**
 | |
|    * An SSL or TLS session ID.
 | |
|    */
 | |
|   public static final class ID implements Comparable, Serializable
 | |
|   {
 | |
| 
 | |
|     // Fields.
 | |
|     // -----------------------------------------------------------------------
 | |
| 
 | |
|     static final long serialVersionUID = 7887036954666565936L;
 | |
|     /** The ID itself. */
 | |
|     private final byte[] id;
 | |
| 
 | |
|     // Constructor.
 | |
|     // -----------------------------------------------------------------------
 | |
| 
 | |
|     /**
 | |
|      * Creates a new ID.
 | |
|      *
 | |
|      * @param id The ID. The array is cloned.
 | |
|      */
 | |
|     public ID (final byte[] id)
 | |
|     {
 | |
|       if (id.length > 32)
 | |
|         throw new IllegalArgumentException ("session ID's are limited to 32 bytes");
 | |
|       this.id = (byte[]) id.clone();
 | |
|     }
 | |
| 
 | |
|     // Instance methods.
 | |
|     // -----------------------------------------------------------------------
 | |
| 
 | |
|     public byte[] id()
 | |
|     {
 | |
|       return (byte[]) id.clone();
 | |
|     }
 | |
| 
 | |
|     public boolean equals(Object other)
 | |
|     {
 | |
|       if (!(other instanceof ID))
 | |
|         return false;
 | |
|       return Arrays.equals(id, ((ID) other).id);
 | |
|     }
 | |
| 
 | |
|     public int hashCode()
 | |
|     {
 | |
|       int code = 0;
 | |
|       for (int i = 0; i < id.length; i++)
 | |
|         code |= (id[i] & 0xFF) << ((i & 3) << 3);
 | |
|       return code;
 | |
|     }
 | |
| 
 | |
|     public int compareTo(Object other)
 | |
|     {
 | |
|       byte[] id2 = ((ID) other).id;
 | |
|       if (id.length != id2.length)
 | |
|         return (id.length < id2.length) ? -1 : 1;
 | |
|       for (int i = 0; i < id.length; i++)
 | |
|         {
 | |
|           if ((id[i] & 0xFF) < (id2[i] & 0xFF))
 | |
|             return -1;
 | |
|           if ((id[i] & 0xFF) > (id2[i] & 0xFF))
 | |
|             return 1;
 | |
|         }
 | |
|       return 0;
 | |
|     }
 | |
| 
 | |
|     public String toString()
 | |
|     {
 | |
|       CPStringBuilder str = new CPStringBuilder (3 * id.length + 1);
 | |
|       for (int i = 0; i < id.length; i++)
 | |
|         {
 | |
|           int x = id[i] & 0xFF;
 | |
|           str.append (Character.forDigit ((x >>> 4) & 0xF, 16));
 | |
|           str.append (Character.forDigit (x & 0xF, 16));
 | |
|           if (i != id.length - 1)
 | |
|             str.append (':');
 | |
|         }
 | |
|       return str.toString ();
 | |
|     }
 | |
|   }
 | |
| }
 |