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

  1. /*
  2.  * @(#)Identity.java    1.43 98/03/18
  3.  *
  4.  * Copyright 1996-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. import java.io.IOException;
  18. import java.io.Serializable;
  19. import java.util.*;
  20.  
  21. /**
  22.  * <p>This class represents identities: real-world objects such as people,
  23.  * companies or organizations whose identities can be authenticated using 
  24.  * their public keys. Identities may also be more abstract (or concrete) 
  25.  * constructs, such as daemon threads or smart cards.
  26.  *
  27.  * <p>All Identity objects have a name and a public key. Names are
  28.  * immutable. Identities may also be scoped. That is, if an Identity is
  29.  * specified to have a particular scope, then the name and public
  30.  * key of the Identity are unique within that scope.
  31.  *
  32.  * <p>An Identity also has a set of certificates (all certifying its own
  33.  * public key). The Principal names specified in these certificates need 
  34.  * not be the same, only the key.
  35.  *
  36.  * <p>An Identity can be subclassed, to include postal and email addresses,
  37.  * telephone numbers, images of faces and logos, and so on.
  38.  *
  39.  * @see IdentityScope
  40.  * @see Signer
  41.  * @see Principal
  42.  *
  43.  * @version 1.43 98/03/18
  44.  * @author Benjamin Renaud 
  45.  */
  46. public class Identity implements Principal, Serializable {
  47.  
  48.     /**
  49.      * The name for this identity.
  50.      */
  51.     private String name;
  52.  
  53.     /**
  54.      * The public key for this identity.
  55.      */
  56.     private PublicKey publicKey;
  57.  
  58.     /** use serialVersionUID from JDK 1.1. for interoperability */
  59.     private static final long serialVersionUID = 3609922007826600659L;
  60.  
  61.     /**
  62.      * Generic, descriptive information about the identity.
  63.      */
  64.     String info = "No further information available.";
  65.  
  66.     /**
  67.      * The scope of the identity.
  68.      */
  69.     IdentityScope scope;
  70.  
  71.     /**
  72.      * The certificates for this identity.
  73.      */
  74.     Vector certificates;
  75.  
  76.     /**
  77.      * Constructor for serialization only.
  78.      */
  79.     protected Identity() {
  80.     this("restoring...");
  81.     }
  82.  
  83.     /**
  84.      * Constructs an identity with the specified name and scope.
  85.      *
  86.      * @param name the identity name.  
  87.      * @param scope the scope of the identity.
  88.      *
  89.      * @exception KeyManagementException if there is already an identity 
  90.      * with the same name in the scope.
  91.      */
  92.     public Identity(String name, IdentityScope scope) throws
  93.     KeyManagementException {
  94.     this(name);
  95.     this.scope = scope;
  96.     }
  97.  
  98.     /**
  99.      * Constructs an identity with the specified name and no scope.
  100.      *
  101.      * @param name the identity name.
  102.      */
  103.     public Identity(String name) {
  104.     this.name = name;
  105.     }
  106.  
  107.     /**
  108.      * Constructs an identity with the specified name, info, certificates,
  109.      * and public key.
  110.      *
  111.      * @param name the identity name.
  112.      * @param info the information string.
  113.      * @param publicKey the public key for this identity.
  114.      * @param certificates the certificates to be added.
  115.      *
  116.      */
  117.     public Identity(String name,
  118.             String info,
  119.             java.security.cert.Certificate certificates[],
  120.             PublicKey publicKey) 
  121.     {
  122.     this.name = name;
  123.     this.info = info;
  124.     this.publicKey = publicKey;
  125.     if (certificates != null) {
  126.         this.certificates = new Vector();
  127.         for (int i=0; i < certificates.length; i++) {
  128.         if (certificates[i] != null)
  129.             this.certificates.add(certificates[i]);
  130.         }
  131.     }
  132.     }
  133.  
  134.     /**
  135.      * Returns this identity's name.
  136.      *
  137.      * @return the name of this identity.
  138.      */
  139.     public final String getName() {
  140.     return name;
  141.     }
  142.  
  143.     /**
  144.      * Returns this identity's scope.
  145.      *
  146.      * @return the scope of this identity.
  147.      */
  148.     public final IdentityScope getScope() {
  149.     return scope;
  150.     }
  151.  
  152.     /**
  153.      * Returns this identity's public key.
  154.      * 
  155.      * @return the public key for this identity.
  156.      */
  157.     public PublicKey getPublicKey() {
  158.     return publicKey;
  159.     }
  160.  
  161.     /**
  162.      * Sets this identity's public key. The old key and all of this
  163.      * identity's certificates are removed by this operation. 
  164.      *
  165.      * @param key the public key for this identity.
  166.      *
  167.      * @exception KeyManagementException if another identity in the 
  168.      * identity's scope has the same public key, or if another exception occurs.  
  169.      */
  170.     /* Should we throw an exception if this is already set? */
  171.     public void setPublicKey(PublicKey key) throws KeyManagementException {
  172.     
  173.     check("Identity.setPublicKey");
  174.     this.publicKey = key;
  175.     }
  176.  
  177.     /**
  178.      * Specifies a general information string for this identity.
  179.      *
  180.      * @param info the information string.
  181.      *
  182.      * @see #getInfo
  183.      */
  184.     public void setInfo(String info) {
  185.     check("Identity.setInfo");
  186.     this.info = info;
  187.     }
  188.  
  189.     /**
  190.      * Returns general information previously specified for this identity.
  191.      *
  192.      * @return general information about this identity.
  193.      *
  194.      * @see #setInfo
  195.      */
  196.     public String getInfo() {
  197.     return info;
  198.     }
  199.  
  200.     /**
  201.      * Adds a certificate for this identity. If the identity has a public
  202.      * key, the public key in the certificate must be the same, and if
  203.      * the identity does not have a public key, the identity's
  204.      * public key is set to be that specified in the certificate.
  205.      *
  206.      * @param certificate the certificate to be added.
  207.      *
  208.      * @exception KeyManagementException if the certificate is not valid,
  209.      * if the public key in the certificate being added conflicts with
  210.      * this identity's public key, or if another exception occurs.
  211.      * 
  212.      * @deprecated Use the new <a href = 
  213.      * "#addCertificate(java.security.cert.Certificate)">
  214.      * addCertificate</a> method instead.
  215.      */
  216.     public void addCertificate(java.security.Certificate certificate)
  217.     throws KeyManagementException {
  218.  
  219.     check("Identity.addCertificate");
  220.  
  221.     if (certificates == null) {
  222.         certificates = new Vector();
  223.     }
  224.     if (publicKey != null) {
  225.         if (!keyEquals(publicKey, certificate.getPublicKey())) {
  226.         throw new KeyManagementException(
  227.             "public key different from cert public key");
  228.         }
  229.     } else {
  230.         publicKey = certificate.getPublicKey();
  231.     }
  232.     certificates.addElement(certificate);
  233.     }
  234.  
  235.     /**
  236.      * Adds a certificate for this identity. If the identity has a public
  237.      * key, the public key in the certificate must be the same, and if
  238.      * the identity does not have a public key, the identity's
  239.      * public key is set to be that specified in the certificate.
  240.      *
  241.      * @param certificate the certificate to be added.
  242.      *
  243.      * @exception KeyManagementException if the certificate is not valid,
  244.      * if the public key in the certificate being added conflicts with
  245.      * this identity's public key, or if another exception occurs.
  246.      * @since JDK1.2
  247.      */
  248.     public void addCertificate(java.security.cert.Certificate certificate)
  249.     throws KeyManagementException {
  250.  
  251.     check("Identity.addCertificate");
  252.  
  253.     if (certificates == null) {
  254.         certificates = new Vector();
  255.     }
  256.         PublicKey tmpKey = certificate.getPublicKey();
  257.     if (publicKey != null && tmpKey != null) {
  258.         if (!keyEquals(publicKey, tmpKey)) {
  259.         throw new KeyManagementException(
  260.             "public key different from cert public key");
  261.         }
  262.     } else {
  263.         publicKey = tmpKey;
  264.     }
  265.     certificates.addElement(certificate);
  266.     }
  267.  
  268.    private boolean keyEquals(Key aKey, Key anotherKey) {
  269.     if (aKey.getFormat().equalsIgnoreCase(anotherKey.getFormat())) {
  270.         return MessageDigest.isEqual(aKey.getEncoded(), 
  271.                      anotherKey.getEncoded());
  272.     } else {
  273.         return false;
  274.     }
  275.     }
  276.  
  277.     /**
  278.      * Removes a certificate from this identity.
  279.      *
  280.      * @param certificate the certificate to be removed.
  281.      *
  282.      * @exception KeyManagementException if the certificate is
  283.      * missing, or if another exception occurs.
  284.      * 
  285.      * @deprecated Use the new <a href = 
  286.      * "#removeCertificate(java.security.cert.Certificate)">
  287.      * removeCertificate</a> method instead.
  288.      */
  289.     public void removeCertificate(java.security.Certificate certificate)
  290.     throws KeyManagementException {
  291.     check("Identity.removeCertificate");
  292.     if (certificates != null) {
  293.         certificates.removeElement(certificate);
  294.     }
  295.     }
  296.  
  297.     /**
  298.      * Removes a certificate from this identity.
  299.      *
  300.      * @param certificate the certificate to be removed.
  301.      *
  302.      * @exception KeyManagementException if the certificate is
  303.      * missing, or if another exception occurs.
  304.      * @since JDK1.2
  305.      */
  306.     public void removeCertificate(java.security.cert.Certificate certificate)
  307.     throws KeyManagementException {
  308.     check("Identity.removeCertificate");
  309.     if (certificates != null) {
  310.         certificates.removeElement(certificate);
  311.     }
  312.     }
  313.  
  314.     /**
  315.      * Returns a copy of all the certificates for this identity.  
  316.      * 
  317.      * @return a copy of all the certificates for this identity. 
  318.      * 
  319.      * @deprecated Use <a href = 
  320.      * "#getCertificates()">getCertificates</a> instead.
  321.      */
  322.     public java.security.Certificate[] certificates() {
  323.     if (certificates == null) {
  324.         return new java.security.Certificate[0];
  325.     }
  326.     Vector v = new Vector();
  327.     int i;
  328.  
  329.     for (i=0; i < certificates.size(); i++) {
  330.         Object obj = certificates.elementAt(i);
  331.         if (obj instanceof java.security.Certificate) {
  332.         v.addElement(obj);
  333.         } else if (obj instanceof java.security.cert.Certificate) {
  334.         try {
  335.             java.security.Certificate oldC;
  336.             java.security.cert.Certificate newC = 
  337.                 (java.security.cert.Certificate) obj;
  338.  
  339.             byte[] encoded = newC.getEncoded();
  340.             oldC = new sun.security.x509.X509Cert(encoded);
  341.             v.addElement(oldC);
  342.         } catch (IOException ioe) {
  343.             // ignore if we can't parse
  344.         } catch (java.security.cert.CertificateEncodingException cee) {
  345.             // ignore if we can't encode
  346.         }
  347.         }
  348.     }
  349.     java.security.Certificate certs[] = 
  350.         new java.security.Certificate[v.size()];
  351.     v.copyInto(certs);
  352.     return certs;
  353.     }
  354.  
  355.     /**
  356.      * Returns a copy of all the certificates for this identity.  
  357.      * 
  358.      * @return a copy of all the certificates for this identity.  
  359.      * @since JDK1.2
  360.      */
  361.     public java.security.cert.Certificate[] getCertificates() {
  362.     if (certificates == null) {
  363.         return new java.security.cert.Certificate[0];
  364.     }
  365.  
  366.     int n = certificates.size();
  367.     int len = 0, i;
  368.  
  369.     for (i=0; i < n; i++) {
  370.         if (certificates.elementAt(i) instanceof 
  371.         java.security.cert.Certificate) {
  372.         len++;
  373.         }
  374.     }
  375.  
  376.     java.security.cert.Certificate[] certs =
  377.                            new java.security.cert.Certificate[len];
  378.     len = 0;
  379.  
  380.     for (i=0; i < n; i++) {
  381.         Object obj = certificates.elementAt(i);
  382.         if (obj instanceof java.security.cert.Certificate) {
  383.         certs[len] = (java.security.cert.Certificate) obj;
  384.         len++;
  385.         }
  386.     }
  387.     return certs;
  388.     }
  389.  
  390.     /**
  391.      * Tests for equality between the specified object and this identity.
  392.      * This first tests to see if the entities actually refer to the same
  393.      * object, in which case it returns true. Next, it checks to see if
  394.      * the entities have the same name and the same scope. If they do, 
  395.      * the method returns true. Otherwise, it calls <a href = 
  396.      * "#identityEquals">identityEquals</a>, which subclasses should 
  397.      * override.
  398.      *
  399.      * @param identity the object to test for equality with this identity.  
  400.      *
  401.      * @return true if the objects are considered equal, false otherwise.
  402.      *
  403.      * @see #identityEquals 
  404.      */
  405.     public final boolean equals(Object identity) {
  406.  
  407.     if (identity == this) {
  408.         return true;
  409.     }
  410.  
  411.     if (identity instanceof Identity) {
  412.         Identity i = (Identity)identity;
  413.         if ((scope !=null) && 
  414.         (i.getScope() == scope) && 
  415.         i.getName().equals(name)) {
  416.         return true;
  417.         } else {
  418.         return identityEquals(i);        
  419.         }
  420.     }
  421.     return false;
  422.     }
  423.  
  424.     /**
  425.      * Tests for equality between the specified identity and this identity.
  426.      * This method should be overriden by subclasses to test for equality. 
  427.      * The default behavior is to return true if the names and public keys 
  428.      * are equal.
  429.      *
  430.      * @param identity the identity to test for equality with this identity.
  431.      * 
  432.      * @return true if the identities are considered equal, false
  433.      * otherwise. 
  434.      *
  435.      * @see #equals 
  436.      */
  437.     protected boolean identityEquals(Identity identity) {
  438.     return (name.equals(identity.name) && 
  439.         publicKey.equals(identity.publicKey));
  440.     }
  441.  
  442.     /**
  443.      * Returns a parsable name for identity: identityName.scopeName
  444.      */
  445.     String fullName() {
  446.     String parsable = name;
  447.     if (scope != null) {
  448.         parsable += "." + scope.getName();
  449.     }
  450.     return parsable;
  451.     }
  452.  
  453.     /**
  454.      * Returns a short string describing this identity, telling its
  455.      * name and its scope (if any).
  456.      *
  457.      * @return information about this identity, such as its name and the  
  458.      * name of its scope (if any).
  459.      */
  460.     public String toString() {
  461.     String printable = name;
  462.     if (scope != null) {
  463.         printable += "[" + scope.getName() + "]";
  464.     }
  465.     return printable;
  466.     }
  467.  
  468.     /**
  469.      * Returns a string representation of this identity, with
  470.      * optionally more details than that provided by the
  471.      * <code>toString</code> method without any arguments.
  472.      *
  473.      * @param detailed whether or not to provide detailed information.  
  474.      *
  475.      * @return information about this identity. If <code>detailed</code>
  476.      * is true, then this method returns more information than that 
  477.      * provided by the <code>toString</code> method without any arguments.
  478.      *
  479.      * @see #toString
  480.      */
  481.     public String toString(boolean detailed) {
  482.     String out = toString();
  483.     if (detailed) {
  484.         out += "\n";
  485.         out += printKeys();
  486.         out += "\n" + printCertificates();
  487.         if (info != null) {
  488.         out += "\n\t" + info;
  489.         } else {
  490.         out += "\n\tno additional information available.";
  491.         }
  492.     }      
  493.     return out;
  494.     }
  495.  
  496.     String printKeys() {
  497.     String key = "";
  498.     if (publicKey != null) {
  499.         key = "\tpublic key initialized";
  500.     } else {
  501.         key = "\tno public key";
  502.     }
  503.     return key;
  504.     }
  505.  
  506.     String printCertificates() {
  507.     String out = "";
  508.     if (certificates == null) {
  509.         return "\tno certificates";
  510.     } else {
  511.         out += "\tcertificates: \n";
  512.         Enumeration e = certificates.elements();
  513.         int i = 1;
  514.         while (e.hasMoreElements()) {
  515.         Object obj = e.nextElement();
  516.         if (obj instanceof java.security.Certificate) {
  517.             java.security.Certificate cert = 
  518.                 (java.security.Certificate) obj;
  519.             out += "\tcertificate " + i++ +
  520.                 "\tfor  : " + cert.getPrincipal() + "\n";
  521.             out += "\t\t\tfrom : " + 
  522.                 cert.getGuarantor() + "\n";
  523.         } else if (obj instanceof java.security.cert.X509Certificate) {
  524.             java.security.cert.X509Certificate cert =
  525.                             (java.security.cert.X509Certificate)obj;
  526.             out += "\tcertificate " + i++ +
  527.                                "\tfor  : " + cert.getSubjectDN() + "\n";
  528.             out += "\t\t\tfrom : " + 
  529.                    cert.getIssuerDN() + "\n";
  530.         } else {
  531.             out += obj.toString();    
  532.         }
  533.         }
  534.     }
  535.     return out;
  536.     }
  537.     
  538.     /**
  539.      * Returns a hashcode for this identity.
  540.      *
  541.      * @return a hashcode for this identity.
  542.      */
  543.     public int hashCode() {
  544.     String scopedName = name;
  545.     if (scope != null) {
  546.         scopedName += scope.getName();
  547.     }
  548.     return scopedName.hashCode();
  549.     }
  550.  
  551.     private static void check(String directive) {
  552.     SecurityManager security = System.getSecurityManager();
  553.     if (security != null) {
  554.         security.checkSecurityAccess(directive);
  555.     }
  556.     }
  557. }
  558.