Path: blob/master/src/java.base/share/classes/java/security/Identity.java
41152 views
/*1* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.security;2627import java.io.Serializable;28import java.util.*;2930/**31* <p>This class represents identities: real-world objects such as people,32* companies or organizations whose identities can be authenticated using33* their public keys. Identities may also be more abstract (or concrete)34* constructs, such as daemon threads or smart cards.35*36* <p>All Identity objects have a name and a public key. Names are37* immutable. Identities may also be scoped. That is, if an Identity is38* specified to have a particular scope, then the name and public39* key of the Identity are unique within that scope.40*41* <p>An Identity also has a set of certificates (all certifying its own42* public key). The Principal names specified in these certificates need43* not be the same, only the key.44*45* <p>An Identity can be subclassed, to include postal and email addresses,46* telephone numbers, images of faces and logos, and so on.47*48* @see IdentityScope49* @see Signer50* @see Principal51*52* @author Benjamin Renaud53* @since 1.154* @deprecated This class is deprecated and subject to removal in a future55* version of Java SE. It has been replaced by56* {@code java.security.KeyStore}, the {@code java.security.cert} package,57* and {@code java.security.Principal}.58*/59@Deprecated(since="1.2", forRemoval=true)60@SuppressWarnings("removal")61public abstract class Identity implements Principal, Serializable {6263/** use serialVersionUID from JDK 1.1.x for interoperability */64@java.io.Serial65private static final long serialVersionUID = 3609922007826600659L;6667/**68* The name for this identity.69*70* @serial71*/72private String name;7374/**75* The public key for this identity.76*77* @serial78*/79private PublicKey publicKey;8081/**82* Generic, descriptive information about the identity.83*84* @serial85*/86String info = "No further information available.";8788/**89* The scope of the identity.90*91* @serial92*/93IdentityScope scope;9495/**96* The certificates for this identity.97*98* @serial99*/100Vector<Certificate> certificates;101102/**103* Constructor for serialization only.104*/105protected Identity() {106this("restoring...");107}108109/**110* Constructs an identity with the specified name and scope.111*112* @param name the identity name.113* @param scope the scope of the identity.114*115* @throws KeyManagementException if there is already an identity116* with the same name in the scope.117*/118public Identity(String name, IdentityScope scope) throws119KeyManagementException {120this(name);121if (scope != null) {122scope.addIdentity(this);123}124this.scope = scope;125}126127/**128* Constructs an identity with the specified name and no scope.129*130* @param name the identity name.131*/132public Identity(String name) {133this.name = name;134}135136/**137* Returns this identity's name.138*139* @return the name of this identity.140*/141public final String getName() {142return name;143}144145/**146* Returns this identity's scope.147*148* @return the scope of this identity.149*/150public final IdentityScope getScope() {151return scope;152}153154/**155* Returns this identity's public key.156*157* @return the public key for this identity.158*159* @see #setPublicKey160*/161public PublicKey getPublicKey() {162return publicKey;163}164165/**166* Sets this identity's public key. The old key and all of this167* identity's certificates are removed by this operation.168*169* <p>First, if there is a security manager, its {@code checkSecurityAccess}170* method is called with {@code "setIdentityPublicKey"}171* as its argument to see if it's ok to set the public key.172*173* @param key the public key for this identity.174*175* @throws KeyManagementException if another identity in the176* identity's scope has the same public key, or if another exception occurs.177*178* @throws SecurityException if a security manager exists and its179* {@code checkSecurityAccess} method doesn't allow180* setting the public key.181*182* @see #getPublicKey183* @see SecurityManager#checkSecurityAccess184*/185/* Should we throw an exception if this is already set? */186public void setPublicKey(PublicKey key) throws KeyManagementException {187188check("setIdentityPublicKey");189this.publicKey = key;190certificates = new Vector<>();191}192193/**194* Specifies a general information string for this identity.195*196* <p>First, if there is a security manager, its {@code checkSecurityAccess}197* method is called with {@code "setIdentityInfo"}198* as its argument to see if it's ok to specify the information string.199*200* @param info the information string.201*202* @throws SecurityException if a security manager exists and its203* {@code checkSecurityAccess} method doesn't allow204* setting the information string.205*206* @see #getInfo207* @see SecurityManager#checkSecurityAccess208*/209public void setInfo(String info) {210check("setIdentityInfo");211this.info = info;212}213214/**215* Returns general information previously specified for this identity.216*217* @return general information about this identity.218*219* @see #setInfo220*/221public String getInfo() {222return info;223}224225/**226* Adds a certificate for this identity. If the identity has a public227* key, the public key in the certificate must be the same, and if228* the identity does not have a public key, the identity's229* public key is set to be that specified in the certificate.230*231* <p>First, if there is a security manager, its {@code checkSecurityAccess}232* method is called with {@code "addIdentityCertificate"}233* as its argument to see if it's ok to add a certificate.234*235* @param certificate the certificate to be added.236*237* @throws KeyManagementException if the certificate is not valid,238* if the public key in the certificate being added conflicts with239* this identity's public key, or if another exception occurs.240*241* @throws SecurityException if a security manager exists and its242* {@code checkSecurityAccess} method doesn't allow243* adding a certificate.244*245* @see SecurityManager#checkSecurityAccess246*/247public void addCertificate(Certificate certificate)248throws KeyManagementException {249250check("addIdentityCertificate");251252if (certificates == null) {253certificates = new Vector<>();254}255if (publicKey != null) {256if (!keyEquals(publicKey, certificate.getPublicKey())) {257throw new KeyManagementException(258"public key different from cert public key");259}260} else {261publicKey = certificate.getPublicKey();262}263certificates.addElement(certificate);264}265266private boolean keyEquals(PublicKey aKey, PublicKey anotherKey) {267String aKeyFormat = aKey.getFormat();268String anotherKeyFormat = anotherKey.getFormat();269if ((aKeyFormat == null) ^ (anotherKeyFormat == null))270return false;271if (aKeyFormat != null && anotherKeyFormat != null)272if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat))273return false;274return java.util.Arrays.equals(aKey.getEncoded(),275anotherKey.getEncoded());276}277278279/**280* Removes a certificate from this identity.281*282* <p>First, if there is a security manager, its {@code checkSecurityAccess}283* method is called with {@code "removeIdentityCertificate"}284* as its argument to see if it's ok to remove a certificate.285*286* @param certificate the certificate to be removed.287*288* @throws KeyManagementException if the certificate is289* missing, or if another exception occurs.290*291* @throws SecurityException if a security manager exists and its292* {@code checkSecurityAccess} method doesn't allow293* removing a certificate.294*295* @see SecurityManager#checkSecurityAccess296*/297public void removeCertificate(Certificate certificate)298throws KeyManagementException {299check("removeIdentityCertificate");300if (certificates != null) {301certificates.removeElement(certificate);302}303}304305/**306* Returns a copy of all the certificates for this identity.307*308* @return a copy of all the certificates for this identity.309*/310public Certificate[] certificates() {311if (certificates == null) {312return new Certificate[0];313}314int len = certificates.size();315Certificate[] certs = new Certificate[len];316certificates.copyInto(certs);317return certs;318}319320/**321* Tests for equality between the specified object and this identity.322* This first tests to see if the entities actually refer to the same323* object, in which case it returns true. Next, it checks to see if324* the entities have the same name and the same scope. If they do,325* the method returns true. Otherwise, it calls326* {@link #identityEquals(Identity) identityEquals}, which subclasses should327* override.328*329* @param identity the object to test for equality with this identity.330*331* @return true if the objects are considered equal, false otherwise.332*333* @see #identityEquals334*/335public final boolean equals(Object identity) {336if (identity == this) {337return true;338}339340return identity instanceof Identity other341&& (this.fullName().equals(other.fullName()) || identityEquals(other));342}343344/**345* Tests for equality between the specified identity and this identity.346* This method should be overridden by subclasses to test for equality.347* The default behavior is to return true if the names and public keys348* are equal.349*350* @param identity the identity to test for equality with this identity.351*352* @return true if the identities are considered equal, false353* otherwise.354*355* @see #equals356*/357protected boolean identityEquals(Identity identity) {358if (!name.equalsIgnoreCase(identity.name))359return false;360361if ((publicKey == null) ^ (identity.publicKey == null))362return false;363364if (publicKey != null && identity.publicKey != null)365if (!publicKey.equals(identity.publicKey))366return false;367368return true;369370}371372/**373* Returns a parsable name for identity: identityName.scopeName374*/375String fullName() {376String parsable = name;377if (scope != null) {378parsable += "." + scope.getName();379}380return parsable;381}382383/**384* Returns a short string describing this identity, telling its385* name and its scope (if any).386*387* <p>First, if there is a security manager, its {@code checkSecurityAccess}388* method is called with {@code "printIdentity"}389* as its argument to see if it's ok to return the string.390*391* @return information about this identity, such as its name and the392* name of its scope (if any).393*394* @throws SecurityException if a security manager exists and its395* {@code checkSecurityAccess} method doesn't allow396* returning a string describing this identity.397*398* @see SecurityManager#checkSecurityAccess399*/400public String toString() {401check("printIdentity");402String printable = name;403if (scope != null) {404printable += "[" + scope.getName() + "]";405}406return printable;407}408409/**410* Returns a string representation of this identity, with411* optionally more details than that provided by the412* {@code toString} method without any arguments.413*414* <p>First, if there is a security manager, its {@code checkSecurityAccess}415* method is called with {@code "printIdentity"}416* as its argument to see if it's ok to return the string.417*418* @param detailed whether or not to provide detailed information.419*420* @return information about this identity. If {@code detailed}421* is true, then this method returns more information than that422* provided by the {@code toString} method without any arguments.423*424* @throws SecurityException if a security manager exists and its425* {@code checkSecurityAccess} method doesn't allow426* returning a string describing this identity.427*428* @see #toString429* @see SecurityManager#checkSecurityAccess430*/431public String toString(boolean detailed) {432String out = toString();433if (detailed) {434out += "\n";435out += printKeys();436out += "\n" + printCertificates();437if (info != null) {438out += "\n\t" + info;439} else {440out += "\n\tno additional information available.";441}442}443return out;444}445446String printKeys() {447String key = "";448if (publicKey != null) {449key = "\tpublic key initialized";450} else {451key = "\tno public key";452}453return key;454}455456String printCertificates() {457String out = "";458if (certificates == null) {459return "\tno certificates";460} else {461out += "\tcertificates: \n";462463int i = 1;464for (Certificate cert : certificates) {465out += "\tcertificate " + i++ +466"\tfor : " + cert.getPrincipal() + "\n";467out += "\t\t\tfrom : " +468cert.getGuarantor() + "\n";469}470}471return out;472}473474/**475* Returns a hashcode for this identity.476*477* @return a hashcode for this identity.478*/479public int hashCode() {480return name.hashCode();481}482483private static void check(String directive) {484SecurityManager security = System.getSecurityManager();485if (security != null) {486security.checkSecurityAccess(directive);487}488}489}490491492