diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/java/security/CodeSource.java | |
download | cbb-gcc-4.6.4-upstream.tar.bz2 cbb-gcc-4.6.4-upstream.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/java/security/CodeSource.java')
-rw-r--r-- | libjava/classpath/java/security/CodeSource.java | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/libjava/classpath/java/security/CodeSource.java b/libjava/classpath/java/security/CodeSource.java new file mode 100644 index 000000000..dd353eda0 --- /dev/null +++ b/libjava/classpath/java/security/CodeSource.java @@ -0,0 +1,356 @@ +/* CodeSource.java -- Code location and certifcates + Copyright (C) 1998, 2002, 2004 Free Software Foundation, Inc. + +This file is 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, 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; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, 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 java.security; + +import gnu.java.lang.CPStringBuilder; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.SocketPermission; +import java.net.URL; +// Note that this overrides Certificate in this package. +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; + +/** + * This class represents a location from which code is loaded (as + * represented by a URL), and the list of certificates that are used to + * check the signatures of signed code loaded from this source. + * + * @author Aaron M. Renn (arenn@urbanophile.com) + * @author Eric Blake (ebb9@email.byu.edu) + * @since 1.1 + * @status updated to 1.4 + */ +public class CodeSource implements Serializable +{ + /** + * Compatible with JDK 1.1+. + */ + private static final long serialVersionUID = 4977541819976013951L; + + /** + * This is the URL that represents the code base from which code will + * be loaded. + * + * @serial the code location + */ + private final URL location; + + /** The set of certificates for this code base. */ + private transient HashSet certs; + + /** + * This creates a new instance of <code>CodeSource</code> that loads code + * from the specified URL location and which uses the specified certificates + * for verifying signatures. + * + * @param location the location from which code will be loaded + * @param certs the list of certificates + */ + public CodeSource(URL location, Certificate[] certs) + { + this.location = location; + if (certs != null) + this.certs = new HashSet(Arrays.asList(certs)); + } + + /** + * This method returns a hash value for this object. + * + * @return a hash value for this object + */ + public int hashCode() + { + return (location == null ? 0 : location.hashCode()) + ^ (certs == null ? 0 : certs.hashCode()); + } + + /** + * This method tests the specified <code>Object</code> for equality with + * this object. This will be true if and only if the locations are equal + * and the certificate sets are identical (ignoring order). + * + * @param obj the <code>Object</code> to test against + * @return true if the specified object is equal to this one + */ + public boolean equals(Object obj) + { + if (! (obj instanceof CodeSource)) + return false; + CodeSource cs = (CodeSource) obj; + return (certs == null ? cs.certs == null : certs.equals(cs.certs)) + && (location == null ? cs.location == null + : location.equals(cs.location)); + } + + /** + * This method returns the URL specifying the location from which code + * will be loaded under this <code>CodeSource</code>. + * + * @return the code location for this <code>CodeSource</code> + */ + public final URL getLocation() + { + return location; + } + + /** + * This method returns the list of digital certificates that can be used + * to verify the signatures of code loaded under this + * <code>CodeSource</code>. + * + * @return the certifcate list for this <code>CodeSource</code> + */ + public final Certificate[] getCertificates() + { + if (certs == null) + return null; + Certificate[] c = new Certificate[certs.size()]; + certs.toArray(c); + return c; + } + + /** + * This method tests to see if a specified <code>CodeSource</code> is + * implied by this object. Effectively, to meet this test, the specified + * object must have all the certifcates this object has (but may have more), + * and must have a location that is a subset of this object's. In order + * for this object to imply the specified object, the following must be + * true: + * + * <ol> + * <li><em>codesource</em> must not be <code>null</code>.</li> + * <li>If <em>codesource</em> has a certificate list, all of it's + * certificates must be present in the certificate list of this + * code source.</li> + * <li>If this object does not have a <code>null</code> location, then + * the following addtional tests must be passed. + * + * <ol> + * <li><em>codesource</em> must not have a <code>null</code> + * location.</li> + * <li><em>codesource</em>'s location must be equal to this object's + * location, or + * <ul> + * <li><em>codesource</em>'s location protocol, port, and ref (aka, + * anchor) must equal this objects</li> + * <li><em>codesource</em>'s location host must imply this object's + * location host, as determined by contructing + * <code>SocketPermission</code> objects from each with no + * action list and using that classes's <code>implies</code> + * method</li> + * <li>If this object's location file ends with a '/', then the + * specified object's location file must start with this + * object's location file. Otherwise, the specified object's + * location file must start with this object's location file + * with the '/' character appended to it.</li> + * </ul></li> + * </ol></li> + * </ol> + * + * <p>For example, each of these locations imply the location + * "http://java.sun.com/classes/foo.jar":</p> + * + * <pre> + * http: + * http://*.sun.com/classes/* + * http://java.sun.com/classes/- + * http://java.sun.com/classes/foo.jar + * </pre> + * + * <p>Note that the code source with null location and null certificates implies + * all other code sources.</p> + * + * @param cs the <code>CodeSource</code> to test against this object + * @return true if this specified <code>CodeSource</code> is implied + */ + public boolean implies(CodeSource cs) + { + if (cs == null) + return false; + // First check the certificate list. + if (certs != null && (cs.certs == null || ! certs.containsAll(cs.certs))) + return false; + // Next check the location. + if (location == null) + return true; + if (cs.location == null + || ! location.getProtocol().equals(cs.location.getProtocol()) + || (location.getPort() != -1 + && location.getPort() != cs.location.getPort()) + || (location.getRef() != null + && ! location.getRef().equals(cs.location.getRef()))) + return false; + if (location.getHost() != null) + { + String their_host = cs.location.getHost(); + if (their_host == null) + return false; + SocketPermission our_sockperm = + new SocketPermission(location.getHost(), "accept"); + SocketPermission their_sockperm = + new SocketPermission(their_host, "accept"); + if (! our_sockperm.implies(their_sockperm)) + return false; + } + String our_file = location.getFile(); + if (our_file != null) + { + if (! our_file.endsWith("/")) + our_file += "/"; + String their_file = cs.location.getFile(); + if (their_file == null + || ! their_file.startsWith(our_file)) + return false; + } + return true; + } + + /** + * This method returns a <code>String</code> that represents this object. + * The result is in the format <code>"(" + getLocation()</code> followed + * by a space separated list of certificates (or "<no certificates>"), + * followed by <code>")"</code>. + * + * @return a <code>String</code> for this object + */ + public String toString() + { + CPStringBuilder sb = new CPStringBuilder("(").append(location); + if (certs == null || certs.isEmpty()) + sb.append(" <no certificates>"); + else + { + Iterator iter = certs.iterator(); + for (int i = certs.size(); --i >= 0; ) + sb.append(' ').append(iter.next()); + } + return sb.append(")").toString(); + } + + /** + * Reads this object from a serialization stream. + * + * @param s the input stream + * @throws IOException if reading fails + * @throws ClassNotFoundException if deserialization fails + * @serialData this reads the location, then expects an int indicating the + * number of certificates. Each certificate is a String type + * followed by an int encoding length, then a byte[] encoding + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + int count = s.readInt(); + certs = new HashSet(); + while (--count >= 0) + { + String type = (String) s.readObject(); + int bytes = s.readInt(); + byte[] encoded = new byte[bytes]; + for (int i = 0; i < bytes; i++) + encoded[i] = s.readByte(); + ByteArrayInputStream stream = new ByteArrayInputStream(encoded); + try + { + CertificateFactory factory = CertificateFactory.getInstance(type); + certs.add(factory.generateCertificate(stream)); + } + catch (CertificateException e) + { + // XXX Should we ignore this certificate? + } + } + } + + /** + * Writes this object to a serialization stream. + * + * @param s the output stream + * @throws IOException if writing fails + * @serialData this writes the location, then writes an int indicating the + * number of certificates. Each certificate is a String type + * followed by an int encoding length, then a byte[] encoding + */ + private void writeObject(ObjectOutputStream s) throws IOException + { + s.defaultWriteObject(); + if (certs == null) + s.writeInt(0); + else + { + int count = certs.size(); + s.writeInt(count); + Iterator iter = certs.iterator(); + while (--count >= 0) + { + Certificate c = (Certificate) iter.next(); + s.writeObject(c.getType()); + byte[] encoded; + try + { + encoded = c.getEncoded(); + } + catch (CertificateEncodingException e) + { + // XXX Should we ignore this certificate? + encoded = null; + } + if (encoded == null) + s.writeInt(0); + else + { + s.writeInt(encoded.length); + for (int i = 0; i < encoded.length; i++) + s.writeByte(encoded[i]); + } + } + } + } +} // class CodeSource |