home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / security / CodeSource.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  6.9 KB  |  263 lines

  1. /*
  2.  * @(#)CodeSource.java    1.17 98/03/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.security;
  16.  
  17.  
  18. import java.net.URL;
  19. import java.net.SocketPermission;
  20.  
  21. /**
  22.  *
  23.  * <p>This class extends the concept of a codebase to
  24.  * encapsulate not only the location (URL) but also the public key(s)
  25.  * that should be used to verify signed code originating from that
  26.  * location.
  27.  *
  28.  * <p>Two CodeSource objects are considered equal if their locations
  29.  * are of identical value and if the two sets of public keys are of
  30.  * identical values.
  31.  *
  32.  * @version     1.17, 03/18/98
  33.  * @author Li Gong */
  34.  
  35. public class CodeSource implements java.io.Serializable {
  36.  
  37.     /** use serialVersionUID from JDK 1.2 for interoperability */
  38.     private static final long serialVersionUID = 63658367122772714L;
  39.  
  40.     /* when multiple locations and/or keys are associated with a
  41.        CodeSource in the future, the following two fields can be
  42.        replaced with arrays. */
  43.  
  44.     // code location.
  45.     private URL location;
  46.  
  47.     // public key.
  48.     private PublicKey pubkey[];
  49.  
  50.     // cached SocketPermission used for matchLocation
  51.     private transient SocketPermission sp;
  52.  
  53.     /**
  54.      * Constructs a CodeSource and associates it with the specified 
  55.      * location and set of public keys.
  56.      * 
  57.      * @param url the location (URL).
  58.      * 
  59.      * @param key the public key(s).
  60.      */
  61.     public CodeSource(URL url, PublicKey key[]) {
  62.     this.location = url;
  63.     this.pubkey = key;
  64.     }
  65.  
  66.     /**
  67.      * Returns the hash code value for this object.
  68.      *
  69.      * @return a hash code value for this object.
  70.      */
  71.  
  72.     public int hashCode() {
  73.     if (location != null)
  74.         return location.hashCode();
  75.     else 
  76.         return 0;
  77.     }
  78.  
  79.     /**
  80.      * Tests for equality between the specified object and this
  81.      * object. Two CodeSource objects are considered equal if their 
  82.      * locations are of identical value and if the two sets of 
  83.      * public keys are of identical values. It is not required that
  84.      * the keys be in the same order.
  85.      * 
  86.      * @param obj the object to test for equality with this object.
  87.      * 
  88.      * @return true if the objects are considered equal, false otherwise.
  89.      */
  90.     public boolean equals(Object obj) {
  91.     if (obj == this) 
  92.         return true;
  93.  
  94.     // objects types must be equal
  95.     if (!(obj instanceof CodeSource))
  96.         return false;
  97.  
  98.     CodeSource cs = (CodeSource) obj;
  99.  
  100.     // URLs must match
  101.     if (location == null) {
  102.         // if location is null, then cs.location must be null as well
  103.         if (cs.location != null) return false;
  104.     } else {
  105.         // if location is not null, then it must equal cs.location
  106.         if (!location.equals(cs.location)) return false;
  107.     }
  108.  
  109.     // Public keys must match
  110.     if (pubkey == null) {
  111.         // if pubkey is null, then cs.pubkey must be null as well
  112.         if (cs.pubkey != null) return false;
  113.     } else {
  114.         // if pubkey is not null, then it must equal cs.pubkey
  115.         // equality means that both arrays of keys are the same set
  116.         // step 1 -- every key in pubkey[] must match one in cs.pubkey[]
  117.         if (cs.pubkey == null) 
  118.         return false;
  119.  
  120.         boolean match;
  121.         for (int i = 0; i < pubkey.length; i++) {
  122.         match = false;
  123.         for (int j = 0; j < cs.pubkey.length; j++) {
  124.             if (pubkey[i].equals(cs.pubkey[j])) {
  125.             match = true;
  126.             break;
  127.             }
  128.         }
  129.         if (!match) return false;
  130.         }
  131.         // step 2 -- every key in cs.pubkey[] must match one in pubkey[]
  132.         for (int i = 0; i < cs.pubkey.length; i++) {
  133.         match = false;
  134.         for (int j = 0; j < pubkey.length; j++) {
  135.             if (cs.pubkey[i].equals(pubkey[j])) {
  136.             match = true;
  137.             break;
  138.             }
  139.         }
  140.         if (!match) return false;
  141.         }
  142.     }
  143.        
  144.     // they must be equal if we got here...
  145.     return true;
  146.     }
  147.  
  148.     /**
  149.      * Returns the location associated with this CodeSource.
  150.      * 
  151.      * @return the location (URL).
  152.      */
  153.     public final URL getLocation() {
  154.     /* since URL is practically immutable, returning itself is not
  155.            a security problem */
  156.     return this.location;
  157.     }
  158.  
  159.     /**
  160.      * Returns the public keys associated with this CodeSource.
  161.      * 
  162.      * @return the public keys.
  163.      */
  164.     public final PublicKey[] getKeys() {
  165.     /* return a clone copy, to avoid malicious modification to the
  166.        original object */
  167.     if (this.pubkey != null) {
  168.         return (PublicKey[])this.pubkey.clone();
  169.     } else {
  170.         return null;
  171.     }
  172.     }
  173.  
  174.     /**
  175.      * Returns true if two CodeSource's have the "same" location.
  176.      * 
  177.      * @param that CodeSource to compare against
  178.      */
  179.     boolean matchLocation(CodeSource that)
  180.     {
  181.         if (location == null) {
  182.         return ((that == null) || (that.location == null));
  183.         }
  184.  
  185.         if ((that == null) || (that.location == null))
  186.         return false;
  187.  
  188.         if (location.equals(that.location))
  189.         return true;
  190.  
  191.         if (!location.getProtocol().equals(that.location.getProtocol()))
  192.         return false;
  193.  
  194.         if ((location.getHost() != null)) {
  195.         if ((location.getHost().equals("") || 
  196.             location.getHost().equals("localhost")) &&
  197.             (that.location.getHost().equals("") || 
  198.              that.location.getHost().equals("localhost"))) {
  199.             // ok
  200.         } else if (!location.getHost().equals(
  201.                          that.location.getHost())) {
  202.             if (this.sp == null) {
  203.             this.sp = 
  204.                 new SocketPermission(location.getHost(),"resolve");
  205.             }
  206.             if (that.sp == null) {
  207.             if (that.location.getHost() == null ||
  208.                 that.location.getHost().equals(""))
  209.                 return false;
  210.             that.sp = 
  211.                new SocketPermission(that.location.getHost(),"resolve");
  212.             }
  213.  
  214.             boolean ok = this.sp.implies(that.sp);
  215.             if (!ok)
  216.             return false;
  217.         }
  218.         }
  219.  
  220.         if (location.getPort() != -1) {
  221.         if (location.getPort() != that.location.getPort())
  222.             return false;
  223.         }
  224.  
  225.         if (location.getFile().endsWith("/")) {
  226.         if (!that.location.getFile().startsWith(location.getFile()))
  227.             return false;
  228.         } else {
  229.           if ((!location.getFile().equals(that.location.getFile())) &&
  230.                (!that.location.getFile().startsWith(location.getFile()+"/"))) {
  231.             return false;
  232.           }
  233.         }
  234.  
  235.         if (location.getRef() == null)
  236.         return true;
  237.         else 
  238.         return location.getRef().equals(that.location.getRef());
  239.     }
  240.  
  241.     /**
  242.      * Returns a string describing this CodeSource, telling its
  243.      * URL and public keys.
  244.      * 
  245.      * @return information about this CodeSource.
  246.      */
  247.     public String toString() {
  248.     StringBuffer sb = new StringBuffer();
  249.     sb.append("(");
  250.     sb.append(this.location);
  251.     if (this.pubkey != null && this.pubkey.length > 0) {
  252.         for (int i=0; i < this.pubkey.length; i++) {
  253.         sb.append( " "+this.pubkey[i]);
  254.         }
  255.     } else {
  256.         sb.append(" <no public keys>");
  257.     }
  258.     sb.append(")");
  259.     return sb.toString();
  260.     }
  261. }
  262.  
  263.