Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.security.CodeSource

 1:  /* CodeSource.java -- Code location and certifcates
 2:  Copyright (C) 1998, 2002, 2004 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: 
 39:  package java.security;
 40: 
 41:  import java.io.ByteArrayInputStream;
 42:  import java.io.IOException;
 43:  import java.io.ObjectInputStream;
 44:  import java.io.ObjectOutputStream;
 45:  import java.io.Serializable;
 46:  import java.net.SocketPermission;
 47:  import java.net.URL;
 48:  // Note that this overrides Certificate in this package.
 49:  import java.security.cert.Certificate;
 50:  import java.security.cert.CertificateEncodingException;
 51:  import java.security.cert.CertificateException;
 52:  import java.security.cert.CertificateFactory;
 53:  import java.util.Arrays;
 54:  import java.util.HashSet;
 55:  import java.util.Iterator;
 56: 
 57:  /**
 58:  * This class represents a location from which code is loaded (as
 59:  * represented by a URL), and the list of certificates that are used to
 60:  * check the signatures of signed code loaded from this source.
 61:  *
 62:  * @author Aaron M. Renn (arenn@urbanophile.com)
 63:  * @author Eric Blake (ebb9@email.byu.edu)
 64:  * @since 1.1
 65:  * @status updated to 1.4
 66:  */
 67:  public class CodeSource implements Serializable
 68: {
 69:  /**
 70:  * Compatible with JDK 1.1+.
 71:  */
 72:  private static final long serialVersionUID = 4977541819976013951L;
 73: 
 74:  /**
 75:  * This is the URL that represents the code base from which code will
 76:  * be loaded.
 77:  *
 78:  * @serial the code location
 79:  */
 80:  private final URL location;
 81: 
 82:  /** The set of certificates for this code base. */
 83:  private transient HashSet certs;
 84: 
 85:  /**
 86:  * This creates a new instance of <code>CodeSource</code> that loads code
 87:  * from the specified URL location and which uses the specified certificates
 88:  * for verifying signatures.
 89:  *
 90:  * @param location the location from which code will be loaded
 91:  * @param certs the list of certificates
 92:  */
 93:  public CodeSource(URL location, Certificate[] certs)
 94:  {
 95:  this.location = location;
 96:  if (certs != null)
 97:  this.certs = new HashSet(Arrays.asList(certs));
 98:  }
 99: 
 100:  /**
 101:  * This method returns a hash value for this object.
 102:  *
 103:  * @return a hash value for this object
 104:  */
 105:  public int hashCode()
 106:  {
 107:  return (location == null ? 0 : location.hashCode())
 108:  ^ (certs == null ? 0 : certs.hashCode());
 109:  }
 110: 
 111:  /**
 112:  * This method tests the specified <code>Object</code> for equality with
 113:  * this object. This will be true if and only if the locations are equal
 114:  * and the certificate sets are identical (ignoring order).
 115:  *
 116:  * @param obj the <code>Object</code> to test against
 117:  * @return true if the specified object is equal to this one
 118:  */
 119:  public boolean equals(Object obj)
 120:  {
 121:  if (! (obj instanceof CodeSource))
 122:  return false;
 123:  CodeSource cs = (CodeSource) obj;
 124:  return (certs == null ? cs.certs == null : certs.equals(cs.certs))
 125:  && (location == null ? cs.location == null
 126:  : location.equals(cs.location));
 127:  }
 128: 
 129:  /**
 130:  * This method returns the URL specifying the location from which code
 131:  * will be loaded under this <code>CodeSource</code>.
 132:  *
 133:  * @return the code location for this <code>CodeSource</code>
 134:  */
 135:  public final URL getLocation()
 136:  {
 137:  return location;
 138:  }
 139: 
 140:  /**
 141:  * This method returns the list of digital certificates that can be used
 142:  * to verify the signatures of code loaded under this
 143:  * <code>CodeSource</code>.
 144:  *
 145:  * @return the certifcate list for this <code>CodeSource</code>
 146:  */
 147:  public final Certificate[] getCertificates()
 148:  {
 149:  if (certs == null)
 150:  return null;
 151:  Certificate[] c = new Certificate[certs.size()];
 152:  certs.toArray(c);
 153:  return c;
 154:  }
 155: 
 156:  /**
 157:  * This method tests to see if a specified <code>CodeSource</code> is
 158:  * implied by this object. Effectively, to meet this test, the specified
 159:  * object must have all the certifcates this object has (but may have more),
 160:  * and must have a location that is a subset of this object's. In order
 161:  * for this object to imply the specified object, the following must be
 162:  * true:
 163:  *
 164:  * <ol>
 165:  * <li><em>codesource</em> must not be <code>null</code>.</li>
 166:  * <li>If <em>codesource</em> has a certificate list, all of it's
 167:  * certificates must be present in the certificate list of this
 168:  * code source.</li>
 169:  * <li>If this object does not have a <code>null</code> location, then
 170:  * the following addtional tests must be passed.
 171:  *
 172:  * <ol>
 173:  * <li><em>codesource</em> must not have a <code>null</code>
 174:  * location.</li>
 175:  * <li><em>codesource</em>'s location must be equal to this object's
 176:  * location, or
 177:  * <ul>
 178:  * <li><em>codesource</em>'s location protocol, port, and ref (aka,
 179:  * anchor) must equal this objects</li>
 180:  * <li><em>codesource</em>'s location host must imply this object's
 181:  * location host, as determined by contructing
 182:  * <code>SocketPermission</code> objects from each with no
 183:  * action list and using that classes's <code>implies</code>
 184:  * method</li>
 185:  * <li>If this object's location file ends with a '/', then the
 186:  * specified object's location file must start with this
 187:  * object's location file. Otherwise, the specified object's
 188:  * location file must start with this object's location file
 189:  * with the '/' character appended to it.</li>
 190:  * </ul></li>
 191:  * </ol></li>
 192:  * </ol>
 193:  *
 194:  * <p>For example, each of these locations imply the location
 195:  * "http://java.sun.com/classes/foo.jar":</p>
 196:  * 
 197:  * <pre>
 198:  * http:
 199:  * http://*.sun.com/classes/*
 200:  * http://java.sun.com/classes/-
 201:  * http://java.sun.com/classes/foo.jar
 202:  * </pre>
 203:  * 
 204:  * <p>Note that the code source with null location and null certificates implies
 205:  * all other code sources.</p>
 206:  *
 207:  * @param cs the <code>CodeSource</code> to test against this object
 208:  * @return true if this specified <code>CodeSource</code> is implied
 209:  */
 210:  public boolean implies(CodeSource cs)
 211:  {
 212:  if (cs == null)
 213:  return false;
 214:  // First check the certificate list.
 215:  if (certs != null && (cs.certs == null || ! certs.containsAll(cs.certs)))
 216:  return false;
 217:  // Next check the location.
 218:  if (location == null)
 219:  return true;
 220:  if (cs.location == null
 221:  || ! location.getProtocol().equals(cs.location.getProtocol())
 222:  || (location.getPort() != -1
 223:  && location.getPort() != cs.location.getPort())
 224:  || (location.getRef() != null
 225:  && ! location.getRef().equals(cs.location.getRef())))
 226:  return false;
 227:  if (location.getHost() != null)
 228:  {
 229:  String their_host = cs.location.getHost();
 230:  if (their_host == null)
 231:  return false;
 232:  SocketPermission our_sockperm =
 233:  new SocketPermission(location.getHost(), "accept");
 234:  SocketPermission their_sockperm =
 235:  new SocketPermission(their_host, "accept");
 236:  if (! our_sockperm.implies(their_sockperm))
 237:  return false;
 238:  }
 239:  String our_file = location.getFile();
 240:  if (our_file != null)
 241:  {
 242:  if (! our_file.endsWith("/"))
 243:  our_file += "/";
 244:  String their_file = cs.location.getFile();
 245:  if (their_file == null
 246:  || ! their_file.startsWith(our_file))
 247:  return false;
 248:  }
 249:  return true;
 250:  }
 251: 
 252:  /**
 253:  * This method returns a <code>String</code> that represents this object.
 254:  * The result is in the format <code>"(" + getLocation()</code> followed
 255:  * by a space separated list of certificates (or "&lt;no certificates&gt;"),
 256:  * followed by <code>")"</code>.
 257:  *
 258:  * @return a <code>String</code> for this object
 259:  */
 260:  public String toString()
 261:  {
 262:  StringBuffer sb = new StringBuffer("(").append(location);
 263:  if (certs == null || certs.isEmpty())
 264:  sb.append(" <no certificates>");
 265:  else
 266:  {
 267:  Iterator iter = certs.iterator();
 268:  for (int i = certs.size(); --i >= 0; )
 269:  sb.append(' ').append(iter.next());
 270:  }
 271:  return sb.append(")").toString();
 272:  }
 273: 
 274:  /**
 275:  * Reads this object from a serialization stream.
 276:  *
 277:  * @param s the input stream
 278:  * @throws IOException if reading fails
 279:  * @throws ClassNotFoundException if deserialization fails
 280:  * @serialData this reads the location, then expects an int indicating the
 281:  * number of certificates. Each certificate is a String type
 282:  * followed by an int encoding length, then a byte[] encoding
 283:  */
 284:  private void readObject(ObjectInputStream s)
 285:  throws IOException, ClassNotFoundException
 286:  {
 287:  s.defaultReadObject();
 288:  int count = s.readInt();
 289:  certs = new HashSet();
 290:  while (--count >= 0)
 291:  {
 292:  String type = (String) s.readObject();
 293:  int bytes = s.readInt();
 294:  byte[] encoded = new byte[bytes];
 295:  for (int i = 0; i < bytes; i++)
 296:  encoded[i] = s.readByte();
 297:  ByteArrayInputStream stream = new ByteArrayInputStream(encoded);
 298:  try
 299:  {
 300:  CertificateFactory factory = CertificateFactory.getInstance(type);
 301:  certs.add(factory.generateCertificate(stream));
 302:  }
 303:  catch (CertificateException e)
 304:  {
 305:  // XXX Should we ignore this certificate?
 306:  }
 307:  }
 308:  }
 309: 
 310:  /**
 311:  * Writes this object to a serialization stream.
 312:  *
 313:  * @param s the output stream
 314:  * @throws IOException if writing fails
 315:  * @serialData this writes the location, then writes an int indicating the
 316:  * number of certificates. Each certificate is a String type
 317:  * followed by an int encoding length, then a byte[] encoding
 318:  */
 319:  private void writeObject(ObjectOutputStream s) throws IOException
 320:  {
 321:  s.defaultWriteObject();
 322:  if (certs == null)
 323:  s.writeInt(0);
 324:  else
 325:  {
 326:  int count = certs.size();
 327:  s.writeInt(count);
 328:  Iterator iter = certs.iterator();
 329:  while (--count >= 0)
 330:  {
 331:  Certificate c = (Certificate) iter.next();
 332:  s.writeObject(c.getType());
 333:  byte[] encoded;
 334:  try
 335:  {
 336:  encoded = c.getEncoded();
 337:  }
 338:  catch (CertificateEncodingException e)
 339:  {
 340:  // XXX Should we ignore this certificate?
 341:  encoded = null;
 342:  }
 343:  if (encoded == null)
 344:  s.writeInt(0);
 345:  else
 346:  {
 347:  s.writeInt(encoded.length);
 348:  for (int i = 0; i < encoded.length; i++)
 349:  s.writeByte(encoded[i]);
 350:  }
 351:  }
 352:  }
 353:  }
 354: } // class CodeSource
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

AltStyle によって変換されたページ (->オリジナル) /