Source for java.security.cert.CertPath

   1: /* CertPath.java -- a sequence of certificates
   2:    Copyright (C) 2002, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is 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, or (at your option)
   9: 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; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 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: package java.security.cert;
  39: 
  40: import gnu.java.lang.CPStringBuilder;
  41: 
  42: import java.io.ByteArrayInputStream;
  43: import java.io.NotSerializableException;
  44: import java.io.ObjectStreamException;
  45: import java.io.Serializable;
  46: import java.util.Iterator;
  47: import java.util.List;
  48: 
  49: /**
  50:  * This class represents an immutable sequence, or path, of security
  51:  * certificates. The path type must match the type of each certificate in the
  52:  * path, or in other words, for all instances of cert in a certpath object,
  53:  * <code>cert.getType().equals(certpath.getType())</code> will return true.
  54:  *
  55:  * <p>Since this class is immutable, it is thread-safe. During serialization,
  56:  * the path is consolidated into a {@link CertPathRep}, which preserves the
  57:  * data regardless of the underlying implementation of the path.
  58:  *
  59:  * @author Eric Blake (ebb9@email.byu.edu)
  60:  * @since 1.4
  61:  * @status updated to 1.4
  62:  */
  63: public abstract class CertPath implements Serializable
  64: {
  65:   /**
  66:    * The serialized representation of a path.
  67:    *
  68:    * @author Eric Blake (ebb9@email.byu.edu)
  69:    */
  70:   protected static class CertPathRep implements Serializable
  71:   {
  72:     /**
  73:      * Compatible with JDK 1.4+.
  74:      */
  75:     private static final long serialVersionUID = 3015633072427920915L;
  76: 
  77:     /**
  78:      * The certificate type.
  79:      *
  80:      * @serial the type of the certificate path
  81:      */
  82:     private final String type;
  83: 
  84:     /**
  85:      * The encoded form of the path.
  86:      *
  87:      * @serial the encoded form
  88:      */
  89:     private final byte[] data;
  90: 
  91:     /**
  92:      * Create the new serial representation.
  93:      *
  94:      * @param type the path type
  95:      * @param data the encoded path data
  96:      */
  97:     protected CertPathRep(String type, byte[] data)
  98:     {
  99:       this.type = type;
 100:       this.data = data;
 101:     }
 102: 
 103:     /**
 104:      * Decode the data into an actual {@link CertPath} upon deserialization.
 105:      *
 106:      * @return the replacement object
 107:      * @throws ObjectStreamException if replacement fails
 108:      */
 109:     protected Object readResolve() throws ObjectStreamException
 110:     {
 111:       try
 112:         {
 113:           return CertificateFactory.getInstance(type)
 114:             .generateCertPath(new ByteArrayInputStream(data));
 115:         }
 116:       catch (CertificateException e)
 117:         {
 118:           throw (ObjectStreamException)
 119:             new NotSerializableException("java.security.cert.CertPath: "
 120:                                          + type).initCause(e);
 121:         }
 122:     }
 123:   } // class CertPathRep
 124: 
 125:   /**
 126:    * Compatible with JDK 1.4+.
 127:    */
 128:   private static final long serialVersionUID = 6068470306649138683L;
 129: 
 130:   /**
 131:    * The path type.
 132:    *
 133:    * @serial the type of all certificates in this path
 134:    */
 135:   private final String type;
 136: 
 137:   /**
 138:    * Create a certificate path with the given type. Most code should use
 139:    * {@link CertificateFactory} to create CertPaths.
 140:    *
 141:    * @param type the type of the path
 142:    */
 143:   protected CertPath(String type)
 144:   {
 145:     this.type = type;
 146:   }
 147: 
 148:   /**
 149:    * Get the (non-null) type of all certificates in the path.
 150:    *
 151:    * @return the path certificate type
 152:    */
 153:   public String getType()
 154:   {
 155:     return type;
 156:   }
 157: 
 158:   /**
 159:    * Get an immutable iterator over the path encodings (all String names),
 160:    * starting with the default encoding. The iterator will throw an
 161:    * <code>UnsupportedOperationException</code> if an attempt is made to
 162:    * remove items from the list.
 163:    *
 164:    * @return the iterator of supported encodings in the path
 165:    */
 166:   public abstract Iterator<String> getEncodings();
 167: 
 168:   /**
 169:    * Compares this path to another for semantic equality. To be equal, both
 170:    * must be instances of CertPath, with the same type, and identical
 171:    * certificate lists. Overriding classes must not change this behavior.
 172:    *
 173:    * @param o the object to compare to
 174:    * @return true if the two are equal
 175:    */
 176:   public boolean equals(Object o)
 177:   {
 178:     if (! (o instanceof CertPath))
 179:       return false;
 180:     CertPath cp = (CertPath) o;
 181:     return type.equals(cp.type)
 182:       && getCertificates().equals(cp.getCertificates());
 183:   }
 184: 
 185:   /**
 186:    * Returns the hashcode of this certificate path. This is defined as:<br>
 187:    * <code>31 * getType().hashCode() + getCertificates().hashCode()</code>.
 188:    *
 189:    * @return the hashcode
 190:    */
 191:   public int hashCode()
 192:   {
 193:     return 31 * type.hashCode() + getCertificates().hashCode();
 194:   }
 195: 
 196:   public String toString()
 197:   {
 198:     List l = getCertificates();
 199:     int size = l.size();
 200:     int i = 0;
 201:     CPStringBuilder result = new CPStringBuilder(type);
 202:     result.append(" Cert Path: length = ").append(size).append(".\n[\n");
 203:     while (--size >= 0)
 204:       result.append(l.get(i++)).append('\n');
 205:     return result.append("\n]").toString();
 206:   }
 207: 
 208:   /**
 209:    * Returns the encoded form of this path, via the default encoding.
 210:    *
 211:    * @return the encoded form
 212:    * @throws CertificateEncodingException if encoding fails
 213:    */
 214:   public abstract byte[] getEncoded() throws CertificateEncodingException;
 215: 
 216:   /**
 217:    * Returns the encoded form of this path, via the specified encoding.
 218:    *
 219:    * @param encoding the encoding to use
 220:    * @return the encoded form
 221:    * @throws CertificateEncodingException if encoding fails or does not exist
 222:    */
 223:   public abstract byte[] getEncoded(String encoding)
 224:     throws CertificateEncodingException;
 225: 
 226:   /**
 227:    * Returns the immutable, thread-safe list of certificates in this path.
 228:    *
 229:    * @return the list of certificates, non-null but possibly empty
 230:    */
 231:   public abstract List<? extends Certificate> getCertificates();
 232: 
 233:   /**
 234:    * Serializes the path in its encoded form, to ensure reserialization with
 235:    * the appropriate factory object without worrying about list implementation.
 236:    * The result will always be an instance of {@link CertPathRep}.
 237:    *
 238:    * @return the replacement object
 239:    * @throws ObjectStreamException if the replacement creation fails
 240:    */
 241:   protected Object writeReplace() throws ObjectStreamException
 242:   {
 243:     try
 244:       {
 245:         return new CertPathRep(type, getEncoded());
 246:       }
 247:     catch (CertificateEncodingException e)
 248:       {
 249:         throw (ObjectStreamException)
 250:           new NotSerializableException("java.security.cert.CertPath: "
 251:                                        + type).initCause(e);
 252:       }
 253:   }
 254: } // class CertPath