1/* 2 * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package java.security; 27 28import java.io.Serializable; 29import java.util.*; 30 31/** 32 * <p>This class represents identities: real-world objects such as people, 33 * companies or organizations whose identities can be authenticated using 34 * their public keys. Identities may also be more abstract (or concrete) 35 * constructs, such as daemon threads or smart cards. 36 * 37 * <p>All Identity objects have a name and a public key. Names are 38 * immutable. Identities may also be scoped. That is, if an Identity is 39 * specified to have a particular scope, then the name and public 40 * key of the Identity are unique within that scope. 41 * 42 * <p>An Identity also has a set of certificates (all certifying its own 43 * public key). The Principal names specified in these certificates need 44 * not be the same, only the key. 45 * 46 * <p>An Identity can be subclassed, to include postal and email addresses, 47 * telephone numbers, images of faces and logos, and so on. 48 * 49 * @see IdentityScope 50 * @see Signer 51 * @see Principal 52 * 53 * @author Benjamin Renaud 54 * @since 1.1 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(since="1.2") 61public 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<>(); 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<>(); 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 certificates.removeElement(certificate); 301 } 302 } 303 304 /** 305 * Returns a copy of all the certificates for this identity. 306 * 307 * @return a copy of all the certificates for this identity. 308 */ 309 public Certificate[] certificates() { 310 if (certificates == null) { 311 return new Certificate[0]; 312 } 313 int len = certificates.size(); 314 Certificate[] certs = new Certificate[len]; 315 certificates.copyInto(certs); 316 return certs; 317 } 318 319 /** 320 * Tests for equality between the specified object and this identity. 321 * This first tests to see if the entities actually refer to the same 322 * object, in which case it returns true. Next, it checks to see if 323 * the entities have the same name and the same scope. If they do, 324 * the method returns true. Otherwise, it calls 325 * {@link #identityEquals(Identity) identityEquals}, which subclasses should 326 * override. 327 * 328 * @param identity the object to test for equality with this identity. 329 * 330 * @return true if the objects are considered equal, false otherwise. 331 * 332 * @see #identityEquals 333 */ 334 public final boolean equals(Object identity) { 335 336 if (identity == this) { 337 return true; 338 } 339 340 if (identity instanceof Identity) { 341 Identity i = (Identity)identity; 342 if (this.fullName().equals(i.fullName())) { 343 return true; 344 } else { 345 return identityEquals(i); 346 } 347 } 348 return false; 349 } 350 351 /** 352 * Tests for equality between the specified identity and this identity. 353 * This method should be overriden by subclasses to test for equality. 354 * The default behavior is to return true if the names and public keys 355 * are equal. 356 * 357 * @param identity the identity to test for equality with this identity. 358 * 359 * @return true if the identities are considered equal, false 360 * otherwise. 361 * 362 * @see #equals 363 */ 364 protected boolean identityEquals(Identity identity) { 365 if (!name.equalsIgnoreCase(identity.name)) 366 return false; 367 368 if ((publicKey == null) ^ (identity.publicKey == null)) 369 return false; 370 371 if (publicKey != null && identity.publicKey != null) 372 if (!publicKey.equals(identity.publicKey)) 373 return false; 374 375 return true; 376 377 } 378 379 /** 380 * Returns a parsable name for identity: identityName.scopeName 381 */ 382 String fullName() { 383 String parsable = name; 384 if (scope != null) { 385 parsable += "." + scope.getName(); 386 } 387 return parsable; 388 } 389 390 /** 391 * Returns a short string describing this identity, telling its 392 * name and its scope (if any). 393 * 394 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 395 * method is called with {@code "printIdentity"} 396 * as its argument to see if it's ok to return the string. 397 * 398 * @return information about this identity, such as its name and the 399 * name of its scope (if any). 400 * 401 * @exception SecurityException if a security manager exists and its 402 * {@code checkSecurityAccess} method doesn't allow 403 * returning a string describing this identity. 404 * 405 * @see SecurityManager#checkSecurityAccess 406 */ 407 public String toString() { 408 check("printIdentity"); 409 String printable = name; 410 if (scope != null) { 411 printable += "[" + scope.getName() + "]"; 412 } 413 return printable; 414 } 415 416 /** 417 * Returns a string representation of this identity, with 418 * optionally more details than that provided by the 419 * {@code toString} method without any arguments. 420 * 421 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 422 * method is called with {@code "printIdentity"} 423 * as its argument to see if it's ok to return the string. 424 * 425 * @param detailed whether or not to provide detailed information. 426 * 427 * @return information about this identity. If {@code detailed} 428 * is true, then this method returns more information than that 429 * provided by the {@code toString} method without any arguments. 430 * 431 * @exception SecurityException if a security manager exists and its 432 * {@code checkSecurityAccess} method doesn't allow 433 * returning a string describing this identity. 434 * 435 * @see #toString 436 * @see SecurityManager#checkSecurityAccess 437 */ 438 public String toString(boolean detailed) { 439 String out = toString(); 440 if (detailed) { 441 out += "\n"; 442 out += printKeys(); 443 out += "\n" + printCertificates(); 444 if (info != null) { 445 out += "\n\t" + info; 446 } else { 447 out += "\n\tno additional information available."; 448 } 449 } 450 return out; 451 } 452 453 String printKeys() { 454 String key = ""; 455 if (publicKey != null) { 456 key = "\tpublic key initialized"; 457 } else { 458 key = "\tno public key"; 459 } 460 return key; 461 } 462 463 String printCertificates() { 464 String out = ""; 465 if (certificates == null) { 466 return "\tno certificates"; 467 } else { 468 out += "\tcertificates: \n"; 469 470 int i = 1; 471 for (Certificate cert : certificates) { 472 out += "\tcertificate " + i++ + 473 "\tfor : " + cert.getPrincipal() + "\n"; 474 out += "\t\t\tfrom : " + 475 cert.getGuarantor() + "\n"; 476 } 477 } 478 return out; 479 } 480 481 /** 482 * Returns a hashcode for this identity. 483 * 484 * @return a hashcode for this identity. 485 */ 486 public int hashCode() { 487 return name.hashCode(); 488 } 489 490 private static void check(String directive) { 491 SecurityManager security = System.getSecurityManager(); 492 if (security != null) { 493 security.checkSecurityAccess(directive); 494 } 495 } 496} 497