001    /* Identity.java --- Identity Class
002       Copyright (C) 1999, 2003, Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package java.security;
039    
040    import java.io.Serializable;
041    import java.util.Vector;
042    
043    /**
044     * The <code>Identity</code> class is used to represent people and companies
045     * that can be authenticated using public key encryption. The identities can
046     * also be abstract objects such as smart cards.
047     *
048     * <p><code>Identity</code> objects store a name and public key for each
049     * identity. The names cannot be changed and the identities can be scoped. Each
050     * identity (name and public key) within a scope are unique to that scope.</p>
051     *
052     * <p>Each identity has a set of ceritificates which all specify the same
053     * public key, but not necessarily the same name.</p>
054     *
055     * <p>The <code>Identity</code> class can be subclassed to allow additional
056     * information to be attached to it.</p>
057     *
058     * @author Mark Benvenuto
059     * @see IdentityScope
060     * @see Signer
061     * @see Principal
062     * @deprecated Replaced by <code>java.security.KeyStore</code>, the
063     * <code>java.security.cert</code> package, and
064     * <code>java.security.Principal</code>.
065     */
066    public abstract class Identity implements Principal, Serializable
067    {
068      private static final long serialVersionUID = 3609922007826600659L;
069    
070      private String name;
071      private IdentityScope scope;
072      private PublicKey publicKey;
073      private String info;
074      private Vector certificates;
075    
076      /** Constructor for serialization only. */
077      protected Identity()
078      {
079      }
080    
081      /**
082       * Constructs a new instance of <code>Identity</code> with the specified
083       * name and scope.
084       *
085       * @param name
086       *          the name to use.
087       * @param scope
088       *          the scope to use.
089       * @throws KeyManagementException
090       *           if the identity is already present.
091       */
092      public Identity(String name, IdentityScope scope)
093        throws KeyManagementException
094      {
095        this.name = name;
096        this.scope = scope;
097      }
098    
099      /**
100       * Constructs a new instance of <code>Identity</code> with the specified
101       * name and no scope.
102       *
103       * @param name
104       *          the name to use.
105       */
106      public Identity(String name)
107      {
108        this.name = name;
109        this.scope = null;
110      }
111    
112      /** @return the name of this identity. */
113      public final String getName()
114      {
115        return name;
116      }
117    
118      /** @return the scope of this identity. */
119      public final IdentityScope getScope()
120      {
121        return scope;
122      }
123    
124      /**
125       * @return the public key of this identity.
126       * @see #setPublicKey(java.security.PublicKey)
127       */
128      public PublicKey getPublicKey()
129      {
130        return publicKey;
131      }
132    
133      /**
134       * Sets the public key for this identity. The old key and all certificates
135       * are removed.
136       *
137       * @param key
138       *          the public key to use.
139       * @throws KeyManagementException
140       *           if this public key is used by another identity in the current
141       *           scope.
142       * @throws SecurityException
143       *           if a {@link SecurityManager} is installed which disallows this
144       *           operation.
145       */
146      public void setPublicKey(PublicKey key) throws KeyManagementException
147      {
148        SecurityManager sm = System.getSecurityManager();
149        if (sm != null)
150          sm.checkSecurityAccess("setIdentityPublicKey");
151    
152        this.publicKey = key;
153      }
154    
155      /**
156       * Sets the general information string.
157       *
158       * @param info
159       *          the general information string.
160       * @throws SecurityException
161       *           if a {@link SecurityManager} is installed which disallows this
162       *           operation.
163       */
164      public void setInfo(String info)
165      {
166        SecurityManager sm = System.getSecurityManager();
167        if (sm != null)
168          sm.checkSecurityAccess("setIdentityInfo");
169    
170        this.info = info;
171      }
172    
173      /**
174       * @return the general information string of this identity.
175       * @see #setInfo(String)
176       */
177      public String getInfo()
178      {
179        return info;
180      }
181    
182      /**
183       * Adds a certificate to the list of ceritificates for this identity. The
184       * public key in this certificate must match the existing public key if it
185       * exists.
186       *
187       * @param certificate
188       *          the certificate to add.
189       * @throws KeyManagementException
190       *           if the certificate is invalid, or the public key conflicts.
191       * @throws SecurityException
192       *           if a {@link SecurityManager} is installed which disallows this
193       *           operation.
194       */
195      public void addCertificate(Certificate certificate)
196        throws KeyManagementException
197      {
198        SecurityManager sm = System.getSecurityManager();
199        if (sm != null)
200          sm.checkSecurityAccess("addIdentityCertificate");
201    
202        // Check public key of this certificate against the first one in the vector
203        if (certificates.size() > 0)
204          {
205            if (((Certificate) certificates.firstElement()).getPublicKey() != publicKey)
206              throw new KeyManagementException("Public key does not match");
207          }
208        certificates.addElement(certificate);
209      }
210    
211      /**
212       * Removes a certificate from the list of ceritificates for this identity.
213       *
214       * @param certificate
215       *          the certificate to remove.
216       * @throws KeyManagementException
217       *           if the certificate is invalid.
218       * @throws SecurityException
219       *           if a {@link SecurityManager} is installed which disallows this
220       *           operation.
221       */
222      public void removeCertificate(Certificate certificate)
223        throws KeyManagementException
224      {
225        SecurityManager sm = System.getSecurityManager();
226        if (sm != null)
227          sm.checkSecurityAccess("removeIdentityCertificate");
228    
229        if (certificates.contains(certificate) == false)
230          throw new KeyManagementException("Certificate not found");
231    
232        certificates.removeElement(certificate);
233      }
234    
235      /** @return an array of {@link Certificate}s for this identity. */
236      public Certificate[] certificates()
237      {
238        Certificate[] certs = new Certificate[certificates.size()];
239        int max = certificates.size();
240        for (int i = 0; i < max; i++)
241          certs[i] = (Certificate) certificates.elementAt(i);
242    
243        return certs;
244      }
245    
246      /**
247       * Checks for equality between this Identity and a specified object. It first
248       * checks if they are the same object, then if the name and scope match and
249       * returns <code>true</code> if successful. If these tests fail, the
250       * {@link #identityEquals(Identity)} method is called.
251       *
252       * @return <code>true</code> if they are equal, <code>false</code>
253       *         otherwise.
254       */
255      public final boolean equals(Object identity)
256      {
257        if (identity instanceof Identity)
258          {
259            if (identity == this)
260              return true;
261    
262            if ((((Identity) identity).getName().equals(this.name)) &&
263                (((Identity) identity).getScope().equals(this.scope)))
264              return true;
265    
266            return identityEquals((Identity) identity);
267          }
268        return false;
269      }
270    
271      /**
272       * Checks for equality between this Identity and a specified object. A
273       * subclass should override this method. The default behavior is to return
274       * <code>true</code> if the public key and names match.
275       *
276       * @return <code>true</code> if they are equal, <code>false</code>
277       *         otherwise.
278       */
279      protected boolean identityEquals(Identity identity)
280      {
281        return ((identity.getName().equals(this.name)) &&
282                (identity.getPublicKey().equals(this.publicKey)));
283      }
284    
285      /**
286       * Returns a string representation of this Identity.
287       *
288       * @return a string representation of this Identity.
289       * @throws SecurityException
290       *           if a {@link SecurityManager} is installed which disallows this
291       *           operation.
292       */
293      public String toString()
294      {
295        SecurityManager sm = System.getSecurityManager();
296        if (sm != null)
297          sm.checkSecurityAccess("printIdentity");
298    
299        /* TODO: Insert proper format here */
300        return (name + ":@" + scope + " Public Key: " + publicKey);
301      }
302    
303      /**
304       * Returns a detailed string representation of this Identity.
305       *
306       * @param detailed
307       *          indicates whether or detailed information is desired.
308       * @return a string representation of this Identity.
309       * @throws SecurityException
310       *           if a {@link SecurityManager} is installed which disallows this
311       *           operation.
312       */
313      public String toString(boolean detailed)
314      {
315        SecurityManager sm = System.getSecurityManager();
316        if (sm != null)
317          sm.checkSecurityAccess("printIdentity");
318    
319        if (detailed)
320          {
321            /* TODO: Insert proper detailed format here */
322            return (name + ":@" + scope + " Public Key: " + publicKey);
323          }
324        else
325          {
326            /* TODO: Insert proper format here */
327            return (name + ":@" + scope + " Public Key: " + publicKey);
328          }
329      }
330    
331      /** @return a hashcode of this identity. */
332      public int hashCode()
333      {
334        int ret = name.hashCode();
335        if (publicKey != null)
336          ret |= publicKey.hashCode();
337        if (scope != null)
338          ret |= scope.hashCode();
339        if (info != null)
340          ret |= info.hashCode();
341        if (certificates != null)
342          ret |= certificates.hashCode();
343    
344        return ret;
345      }
346    }