OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [libjava/] [classpath/] [java/] [security/] [CodeSource.java] - Blame information for rev 14

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 14 jlechner
/* 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.