Home | History | Annotate | Download | only in security
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
      4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      5  *
      6  * This code is free software; you can redistribute it and/or modify it
      7  * under the terms of the GNU General Public License version 2 only, as
      8  * published by the Free Software Foundation.  Oracle designates this
      9  * particular file as subject to the "Classpath" exception as provided
     10  * by Oracle in the LICENSE file that accompanied this code.
     11  *
     12  * This code is distributed in the hope that it will be useful, but WITHOUT
     13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  * version 2 for more details (a copy is included in the LICENSE file that
     16  * accompanied this code).
     17  *
     18  * You should have received a copy of the GNU General Public License version
     19  * 2 along with this work; if not, write to the Free Software Foundation,
     20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     21  *
     22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     23  * or visit www.oracle.com if you need additional information or have any
     24  * questions.
     25  */
     26 
     27 package java.security;
     28 
     29 import java.io.Serializable;
     30 import java.util.*;
     31 
     32 /**
     33  * <p>This class represents identities: real-world objects such as people,
     34  * companies or organizations whose identities can be authenticated using
     35  * their public keys. Identities may also be more abstract (or concrete)
     36  * constructs, such as daemon threads or smart cards.
     37  *
     38  * <p>All Identity objects have a name and a public key. Names are
     39  * immutable. Identities may also be scoped. That is, if an Identity is
     40  * specified to have a particular scope, then the name and public
     41  * key of the Identity are unique within that scope.
     42  *
     43  * <p>An Identity also has a set of certificates (all certifying its own
     44  * public key). The Principal names specified in these certificates need
     45  * not be the same, only the key.
     46  *
     47  * <p>An Identity can be subclassed, to include postal and email addresses,
     48  * telephone numbers, images of faces and logos, and so on.
     49  *
     50  * @see IdentityScope
     51  * @see Signer
     52  * @see Principal
     53  *
     54  * @author Benjamin Renaud
     55  * @deprecated This class is no longer used. Its functionality has been
     56  * replaced by {@code java.security.KeyStore}, the
     57  * {@code java.security.cert} package, and
     58  * {@code java.security.Principal}.
     59  */
     60 @Deprecated
     61 public abstract class Identity implements Principal, Serializable {
     62 
     63     /** use serialVersionUID from JDK 1.1.x for interoperability */
     64     private static final long serialVersionUID = 3609922007826600659L;
     65 
     66     /**
     67      * The name for this identity.
     68      *
     69      * @serial
     70      */
     71     private String name;
     72 
     73     /**
     74      * The public key for this identity.
     75      *
     76      * @serial
     77      */
     78     private PublicKey publicKey;
     79 
     80     /**
     81      * Generic, descriptive information about the identity.
     82      *
     83      * @serial
     84      */
     85     String info = "No further information available.";
     86 
     87     /**
     88      * The scope of the identity.
     89      *
     90      * @serial
     91      */
     92     IdentityScope scope;
     93 
     94     /**
     95      * The certificates for this identity.
     96      *
     97      * @serial
     98      */
     99     Vector<Certificate> certificates;
    100 
    101     /**
    102      * Constructor for serialization only.
    103      */
    104     protected Identity() {
    105         this("restoring...");
    106     }
    107 
    108     /**
    109      * Constructs an identity with the specified name and scope.
    110      *
    111      * @param name the identity name.
    112      * @param scope the scope of the identity.
    113      *
    114      * @exception KeyManagementException if there is already an identity
    115      * with the same name in the scope.
    116      */
    117     public Identity(String name, IdentityScope scope) throws
    118     KeyManagementException {
    119         this(name);
    120         if (scope != null) {
    121             scope.addIdentity(this);
    122         }
    123         this.scope = scope;
    124     }
    125 
    126     /**
    127      * Constructs an identity with the specified name and no scope.
    128      *
    129      * @param name the identity name.
    130      */
    131     public Identity(String name) {
    132         this.name = name;
    133     }
    134 
    135     /**
    136      * Returns this identity's name.
    137      *
    138      * @return the name of this identity.
    139      */
    140     public final String getName() {
    141         return name;
    142     }
    143 
    144     /**
    145      * Returns this identity's scope.
    146      *
    147      * @return the scope of this identity.
    148      */
    149     public final IdentityScope getScope() {
    150         return scope;
    151     }
    152 
    153     /**
    154      * Returns this identity's public key.
    155      *
    156      * @return the public key for this identity.
    157      *
    158      * @see #setPublicKey
    159      */
    160     public PublicKey getPublicKey() {
    161         return publicKey;
    162     }
    163 
    164     /**
    165      * Sets this identity's public key. The old key and all of this
    166      * identity's certificates are removed by this operation.
    167      *
    168      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    169      * method is called with {@code "setIdentityPublicKey"}
    170      * as its argument to see if it's ok to set the public key.
    171      *
    172      * @param key the public key for this identity.
    173      *
    174      * @exception KeyManagementException if another identity in the
    175      * identity's scope has the same public key, or if another exception occurs.
    176      *
    177      * @exception  SecurityException  if a security manager exists and its
    178      * {@code checkSecurityAccess} method doesn't allow
    179      * setting the public key.
    180      *
    181      * @see #getPublicKey
    182      * @see SecurityManager#checkSecurityAccess
    183      */
    184     /* Should we throw an exception if this is already set? */
    185     public void setPublicKey(PublicKey key) throws KeyManagementException {
    186 
    187         check("setIdentityPublicKey");
    188         this.publicKey = key;
    189         certificates = new Vector<Certificate>();
    190     }
    191 
    192     /**
    193      * Specifies a general information string for this identity.
    194      *
    195      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    196      * method is called with {@code "setIdentityInfo"}
    197      * as its argument to see if it's ok to specify the information string.
    198      *
    199      * @param info the information string.
    200      *
    201      * @exception  SecurityException  if a security manager exists and its
    202      * {@code checkSecurityAccess} method doesn't allow
    203      * setting the information string.
    204      *
    205      * @see #getInfo
    206      * @see SecurityManager#checkSecurityAccess
    207      */
    208     public void setInfo(String info) {
    209         check("setIdentityInfo");
    210         this.info = info;
    211     }
    212 
    213     /**
    214      * Returns general information previously specified for this identity.
    215      *
    216      * @return general information about this identity.
    217      *
    218      * @see #setInfo
    219      */
    220     public String getInfo() {
    221         return info;
    222     }
    223 
    224     /**
    225      * Adds a certificate for this identity. If the identity has a public
    226      * key, the public key in the certificate must be the same, and if
    227      * the identity does not have a public key, the identity's
    228      * public key is set to be that specified in the certificate.
    229      *
    230      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    231      * method is called with {@code "addIdentityCertificate"}
    232      * as its argument to see if it's ok to add a certificate.
    233      *
    234      * @param certificate the certificate to be added.
    235      *
    236      * @exception KeyManagementException if the certificate is not valid,
    237      * if the public key in the certificate being added conflicts with
    238      * this identity's public key, or if another exception occurs.
    239      *
    240      * @exception  SecurityException  if a security manager exists and its
    241      * {@code checkSecurityAccess} method doesn't allow
    242      * adding a certificate.
    243      *
    244      * @see SecurityManager#checkSecurityAccess
    245      */
    246     public void addCertificate(Certificate certificate)
    247     throws KeyManagementException {
    248 
    249         check("addIdentityCertificate");
    250 
    251         if (certificates == null) {
    252             certificates = new Vector<Certificate>();
    253         }
    254         if (publicKey != null) {
    255             if (!keyEquals(publicKey, certificate.getPublicKey())) {
    256                 throw new KeyManagementException(
    257                     "public key different from cert public key");
    258             }
    259         } else {
    260             publicKey = certificate.getPublicKey();
    261         }
    262         certificates.addElement(certificate);
    263     }
    264 
    265     private boolean keyEquals(PublicKey aKey, PublicKey anotherKey) {
    266         String aKeyFormat = aKey.getFormat();
    267         String anotherKeyFormat = anotherKey.getFormat();
    268         if ((aKeyFormat == null) ^ (anotherKeyFormat == null))
    269             return false;
    270         if (aKeyFormat != null && anotherKeyFormat != null)
    271             if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat))
    272                 return false;
    273         return java.util.Arrays.equals(aKey.getEncoded(),
    274                                      anotherKey.getEncoded());
    275     }
    276 
    277 
    278     /**
    279      * Removes a certificate from this identity.
    280      *
    281      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    282      * method is called with {@code "removeIdentityCertificate"}
    283      * as its argument to see if it's ok to remove a certificate.
    284      *
    285      * @param certificate the certificate to be removed.
    286      *
    287      * @exception KeyManagementException if the certificate is
    288      * missing, or if another exception occurs.
    289      *
    290      * @exception  SecurityException  if a security manager exists and its
    291      * {@code checkSecurityAccess} method doesn't allow
    292      * removing a certificate.
    293      *
    294      * @see SecurityManager#checkSecurityAccess
    295      */
    296     public void removeCertificate(Certificate certificate)
    297     throws KeyManagementException {
    298         check("removeIdentityCertificate");
    299         if (certificates != null) {
    300             // Android-changed: Throw a KeyManagementException if certificate is null or
    301             // not contained within |certificates|.
    302             if (certificate == null || !certificates.contains(certificate)) {
    303                 throw new KeyManagementException();
    304             }
    305             certificates.removeElement(certificate);
    306         }
    307     }
    308 
    309     /**
    310      * Returns a copy of all the certificates for this identity.
    311      *
    312      * @return a copy of all the certificates for this identity.
    313      */
    314     public Certificate[] certificates() {
    315         if (certificates == null) {
    316             return new Certificate[0];
    317         }
    318         int len = certificates.size();
    319         Certificate[] certs = new Certificate[len];
    320         certificates.copyInto(certs);
    321         return certs;
    322     }
    323 
    324     /**
    325      * Tests for equality between the specified object and this identity.
    326      * This first tests to see if the entities actually refer to the same
    327      * object, in which case it returns true. Next, it checks to see if
    328      * the entities have the same name and the same scope. If they do,
    329      * the method returns true. Otherwise, it calls
    330      * {@link #identityEquals(Identity) identityEquals}, which subclasses should
    331      * override.
    332      *
    333      * @param identity the object to test for equality with this identity.
    334      *
    335      * @return true if the objects are considered equal, false otherwise.
    336      *
    337      * @see #identityEquals
    338      */
    339     public final boolean equals(Object identity) {
    340 
    341         if (identity == this) {
    342             return true;
    343         }
    344 
    345         if (identity instanceof Identity) {
    346             Identity i = (Identity)identity;
    347             if (this.fullName().equals(i.fullName())) {
    348                 return true;
    349             } else {
    350                 return identityEquals(i);
    351             }
    352         }
    353         return false;
    354     }
    355 
    356     /**
    357      * Tests for equality between the specified identity and this identity.
    358      * This method should be overriden by subclasses to test for equality.
    359      * The default behavior is to return true if the names and public keys
    360      * are equal.
    361      *
    362      * @param identity the identity to test for equality with this identity.
    363      *
    364      * @return true if the identities are considered equal, false
    365      * otherwise.
    366      *
    367      * @see #equals
    368      */
    369     protected boolean identityEquals(Identity identity) {
    370         if (!name.equalsIgnoreCase(identity.name))
    371             return false;
    372 
    373         if ((publicKey == null) ^ (identity.publicKey == null))
    374             return false;
    375 
    376         if (publicKey != null && identity.publicKey != null)
    377             if (!publicKey.equals(identity.publicKey))
    378                 return false;
    379 
    380         return true;
    381 
    382     }
    383 
    384     /**
    385      * Returns a parsable name for identity: identityName.scopeName
    386      */
    387     String fullName() {
    388         String parsable = name;
    389         if (scope != null) {
    390             parsable += "." + scope.getName();
    391         }
    392         return parsable;
    393     }
    394 
    395     /**
    396      * Returns a short string describing this identity, telling its
    397      * name and its scope (if any).
    398      *
    399      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    400      * method is called with {@code "printIdentity"}
    401      * as its argument to see if it's ok to return the string.
    402      *
    403      * @return information about this identity, such as its name and the
    404      * name of its scope (if any).
    405      *
    406      * @exception  SecurityException  if a security manager exists and its
    407      * {@code checkSecurityAccess} method doesn't allow
    408      * returning a string describing this identity.
    409      *
    410      * @see SecurityManager#checkSecurityAccess
    411      */
    412     public String toString() {
    413         check("printIdentity");
    414         String printable = name;
    415         if (scope != null) {
    416             printable += "[" + scope.getName() + "]";
    417         }
    418         return printable;
    419     }
    420 
    421     /**
    422      * Returns a string representation of this identity, with
    423      * optionally more details than that provided by the
    424      * {@code toString} method without any arguments.
    425      *
    426      * <p>First, if there is a security manager, its {@code checkSecurityAccess}
    427      * method is called with {@code "printIdentity"}
    428      * as its argument to see if it's ok to return the string.
    429      *
    430      * @param detailed whether or not to provide detailed information.
    431      *
    432      * @return information about this identity. If {@code detailed}
    433      * is true, then this method returns more information than that
    434      * provided by the {@code toString} method without any arguments.
    435      *
    436      * @exception  SecurityException  if a security manager exists and its
    437      * {@code checkSecurityAccess} method doesn't allow
    438      * returning a string describing this identity.
    439      *
    440      * @see #toString
    441      * @see SecurityManager#checkSecurityAccess
    442      */
    443     public String toString(boolean detailed) {
    444         String out = toString();
    445         if (detailed) {
    446             out += "\n";
    447             out += printKeys();
    448             out += "\n" + printCertificates();
    449             if (info != null) {
    450                 out += "\n\t" + info;
    451             } else {
    452                 out += "\n\tno additional information available.";
    453             }
    454         }
    455         return out;
    456     }
    457 
    458     String printKeys() {
    459         String key = "";
    460         if (publicKey != null) {
    461             key = "\tpublic key initialized";
    462         } else {
    463             key = "\tno public key";
    464         }
    465         return key;
    466     }
    467 
    468     String printCertificates() {
    469         String out = "";
    470         if (certificates == null) {
    471             return "\tno certificates";
    472         } else {
    473             out += "\tcertificates: \n";
    474 
    475             int i = 1;
    476             for (Certificate cert : certificates) {
    477                 out += "\tcertificate " + i++ +
    478                     "\tfor  : " + cert.getPrincipal() + "\n";
    479                 out += "\t\t\tfrom : " +
    480                     cert.getGuarantor() + "\n";
    481             }
    482         }
    483         return out;
    484     }
    485 
    486     /**
    487      * Returns a hashcode for this identity.
    488      *
    489      * @return a hashcode for this identity.
    490      */
    491     public int hashCode() {
    492         return name.hashCode();
    493     }
    494 
    495     private static void check(String directive) {
    496         SecurityManager security = System.getSecurityManager();
    497         if (security != null) {
    498             security.checkSecurityAccess(directive);
    499         }
    500     }
    501 }
    502