1 /* 2 * Copyright (c) 1996, 2013, 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 26 package java.security; 27 28 import java.io.Serializable; 29 import 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 * @deprecated This class is no longer used. Its functionality has been 55 * replaced by {@code java.security.KeyStore}, the 56 * {@code java.security.cert} package, and 57 * {@code java.security.Principal}. 58 */ 59 @Deprecated 60 public abstract class Identity implements Principal, Serializable { 61 62 /** use serialVersionUID from JDK 1.1.x for interoperability */ 63 private static final long serialVersionUID = 3609922007826600659L; 64 65 /** 66 * The name for this identity. 67 * 68 * @serial 69 */ 70 private String name; 71 72 /** 73 * The public key for this identity. 74 * 75 * @serial 76 */ 77 private PublicKey publicKey; 78 79 /** 80 * Generic, descriptive information about the identity. 81 * 82 * @serial 83 */ 84 String info = "No further information available."; 85 86 /** 87 * The scope of the identity. 88 * 89 * @serial 90 */ 91 IdentityScope scope; 92 93 /** 94 * The certificates for this identity. 95 * 96 * @serial 97 */ 98 Vector<Certificate> certificates; 99 100 /** 101 * Constructor for serialization only. 102 */ 103 protected Identity() { 104 this("restoring..."); 105 } 106 107 /** 108 * Constructs an identity with the specified name and scope. 109 * 110 * @param name the identity name. 111 * @param scope the scope of the identity. 112 * 113 * @exception KeyManagementException if there is already an identity 114 * with the same name in the scope. 115 */ 116 public Identity(String name, IdentityScope scope) throws 117 KeyManagementException { 118 this(name); 119 if (scope != null) { 120 scope.addIdentity(this); 121 } 122 this.scope = scope; 123 } 124 125 /** 126 * Constructs an identity with the specified name and no scope. 127 * 128 * @param name the identity name. 129 */ 130 public Identity(String name) { 131 this.name = name; 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 * @see #setPublicKey 158 */ 159 public PublicKey getPublicKey() { 160 return publicKey; 161 } 162 163 /** 164 * Sets this identity's public key. The old key and all of this 165 * identity's certificates are removed by this operation. 166 * 167 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 168 * method is called with {@code "setIdentityPublicKey"} 169 * as its argument to see if it's ok to set the public key. 170 * 171 * @param key the public key for this identity. 172 * 173 * @exception KeyManagementException if another identity in the 174 * identity's scope has the same public key, or if another exception occurs. 175 * 176 * @exception SecurityException if a security manager exists and its 177 * {@code checkSecurityAccess} method doesn't allow 178 * setting the public key. 179 * 180 * @see #getPublicKey 181 * @see SecurityManager#checkSecurityAccess 182 */ 183 /* Should we throw an exception if this is already set? */ 184 public void setPublicKey(PublicKey key) throws KeyManagementException { 185 186 check("setIdentityPublicKey"); 187 this.publicKey = key; 188 certificates = new Vector<Certificate>(); 189 } 190 191 /** 192 * Specifies a general information string for this identity. 193 * 194 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 195 * method is called with {@code "setIdentityInfo"} 196 * as its argument to see if it's ok to specify the information string. 197 * 198 * @param info the information string. 199 * 200 * @exception SecurityException if a security manager exists and its 201 * {@code checkSecurityAccess} method doesn't allow 202 * setting the information string. 203 * 204 * @see #getInfo 205 * @see SecurityManager#checkSecurityAccess 206 */ 207 public void setInfo(String info) { 208 check("setIdentityInfo"); 209 this.info = info; 210 } 211 212 /** 213 * Returns general information previously specified for this identity. 214 * 215 * @return general information about this identity. 216 * 217 * @see #setInfo 218 */ 219 public String getInfo() { 220 return info; 221 } 222 223 /** 224 * Adds a certificate for this identity. If the identity has a public 225 * key, the public key in the certificate must be the same, and if 226 * the identity does not have a public key, the identity's 227 * public key is set to be that specified in the certificate. 228 * 229 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 230 * method is called with {@code "addIdentityCertificate"} 231 * as its argument to see if it's ok to add a certificate. 232 * 233 * @param certificate the certificate to be added. 234 * 235 * @exception KeyManagementException if the certificate is not valid, 236 * if the public key in the certificate being added conflicts with 237 * this identity's public key, or if another exception occurs. 238 * 239 * @exception SecurityException if a security manager exists and its 240 * {@code checkSecurityAccess} method doesn't allow 241 * adding a certificate. 242 * 243 * @see SecurityManager#checkSecurityAccess 244 */ 245 public void addCertificate(Certificate certificate) 246 throws KeyManagementException { 247 248 check("addIdentityCertificate"); 249 250 if (certificates == null) { 251 certificates = new Vector<Certificate>(); 252 } 253 if (publicKey != null) { 254 if (!keyEquals(publicKey, certificate.getPublicKey())) { 255 throw new KeyManagementException( 256 "public key different from cert public key"); 257 } 258 } else { 259 publicKey = certificate.getPublicKey(); 260 } 261 certificates.addElement(certificate); 262 } 263 264 private boolean keyEquals(Key aKey, Key anotherKey) { 265 String aKeyFormat = aKey.getFormat(); 266 String anotherKeyFormat = anotherKey.getFormat(); 267 if ((aKeyFormat == null) ^ (anotherKeyFormat == null)) 268 return false; 269 if (aKeyFormat != null && anotherKeyFormat != null) 270 if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat)) 271 return false; 272 return java.util.Arrays.equals(aKey.getEncoded(), 273 anotherKey.getEncoded()); 274 } 275 276 277 /** 278 * Removes a certificate from this identity. 279 * 280 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 281 * method is called with {@code "removeIdentityCertificate"} 282 * as its argument to see if it's ok to remove a certificate. 283 * 284 * @param certificate the certificate to be removed. 285 * 286 * @exception KeyManagementException if the certificate is 287 * missing, or if another exception occurs. 288 * 289 * @exception SecurityException if a security manager exists and its 290 * {@code checkSecurityAccess} method doesn't allow 291 * removing a certificate. 292 * 293 * @see SecurityManager#checkSecurityAccess 294 */ 295 public void removeCertificate(Certificate certificate) 296 throws KeyManagementException { 297 check("removeIdentityCertificate"); 298 if (certificates != null) { 299 certificates.removeElement(certificate); 300 } 301 } 302 303 /** 304 * Returns a copy of all the certificates for this identity. 305 * 306 * @return a copy of all the certificates for this identity. 307 */ 308 public Certificate[] certificates() { 309 if (certificates == null) { 310 return new Certificate[0]; 311 } 312 int len = certificates.size(); 313 Certificate[] certs = new Certificate[len]; 314 certificates.copyInto(certs); 315 return certs; 316 } 317 318 /** 319 * Tests for equality between the specified object and this identity. 320 * This first tests to see if the entities actually refer to the same 321 * object, in which case it returns true. Next, it checks to see if 322 * the entities have the same name and the same scope. If they do, 323 * the method returns true. Otherwise, it calls 324 * {@link #identityEquals(Identity) identityEquals}, which subclasses should 325 * override. 326 * 327 * @param identity the object to test for equality with this identity. 328 * 329 * @return true if the objects are considered equal, false otherwise. 330 * 331 * @see #identityEquals 332 */ 333 public final boolean equals(Object identity) { 334 335 if (identity == this) { 336 return true; 337 } 338 339 if (identity instanceof Identity) { 340 Identity i = (Identity)identity; 341 if (this.fullName().equals(i.fullName())) { 342 return true; 343 } else { 344 return identityEquals(i); 345 } 346 } 347 return false; 348 } 349 350 /** 351 * Tests for equality between the specified identity and this identity. 352 * This method should be overriden by subclasses to test for equality. 353 * The default behavior is to return true if the names and public keys 354 * are equal. 355 * 356 * @param identity the identity to test for equality with this identity. 357 * 358 * @return true if the identities are considered equal, false 359 * otherwise. 360 * 361 * @see #equals 362 */ 363 protected boolean identityEquals(Identity identity) { 364 if (!name.equalsIgnoreCase(identity.name)) 365 return false; 366 367 if ((publicKey == null) ^ (identity.publicKey == null)) 368 return false; 369 370 if (publicKey != null && identity.publicKey != null) 371 if (!publicKey.equals(identity.publicKey)) 372 return false; 373 374 return true; 375 376 } 377 378 /** 379 * Returns a parsable name for identity: identityName.scopeName 380 */ 381 String fullName() { 382 String parsable = name; 383 if (scope != null) { 384 parsable += "." + scope.getName(); 385 } 386 return parsable; 387 } 388 389 /** 390 * Returns a short string describing this identity, telling its 391 * name and its scope (if any). 392 * 393 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 394 * method is called with {@code "printIdentity"} 395 * as its argument to see if it's ok to return the string. 396 * 397 * @return information about this identity, such as its name and the 398 * name of its scope (if any). 399 * 400 * @exception SecurityException if a security manager exists and its 401 * {@code checkSecurityAccess} method doesn't allow 402 * returning a string describing this identity. 403 * 404 * @see SecurityManager#checkSecurityAccess 405 */ 406 public String toString() { 407 check("printIdentity"); 408 String printable = name; 409 if (scope != null) { 410 printable += "[" + scope.getName() + "]"; 411 } 412 return printable; 413 } 414 415 /** 416 * Returns a string representation of this identity, with 417 * optionally more details than that provided by the 418 * {@code toString} method without any arguments. 419 * 420 * <p>First, if there is a security manager, its {@code checkSecurityAccess} 421 * method is called with {@code "printIdentity"} 422 * as its argument to see if it's ok to return the string. 423 * 424 * @param detailed whether or not to provide detailed information. 425 * 426 * @return information about this identity. If {@code detailed} 427 * is true, then this method returns more information than that 428 * provided by the {@code toString} method without any arguments. 429 * 430 * @exception SecurityException if a security manager exists and its 431 * {@code checkSecurityAccess} method doesn't allow 432 * returning a string describing this identity. 433 * 434 * @see #toString 435 * @see SecurityManager#checkSecurityAccess 436 */ 437 public String toString(boolean detailed) { 438 String out = toString(); 439 if (detailed) { 440 out += "\n"; 441 out += printKeys(); 442 out += "\n" + printCertificates(); 443 if (info != null) { 444 out += "\n\t" + info; 445 } else { 446 out += "\n\tno additional information available."; 447 } 448 } 449 return out; 450 } 451 452 String printKeys() { 453 String key = ""; 454 if (publicKey != null) { 455 key = "\tpublic key initialized"; 456 } else { 457 key = "\tno public key"; 458 } 459 return key; 460 } 461 462 String printCertificates() { 463 String out = ""; 464 if (certificates == null) { 465 return "\tno certificates"; 466 } else { 467 out += "\tcertificates: \n"; 468 469 int i = 1; 470 for (Certificate cert : certificates) { 471 out += "\tcertificate " + i++ + 472 "\tfor : " + cert.getPrincipal() + "\n"; 473 out += "\t\t\tfrom : " + 474 cert.getGuarantor() + "\n"; 475 } 476 } 477 return out; 478 } 479 480 /** 481 * Returns a hashcode for this identity. 482 * 483 * @return a hashcode for this identity. 484 */ 485 public int hashCode() { 486 return name.hashCode(); 487 } 488 489 private static void check(String directive) { 490 SecurityManager security = System.getSecurityManager(); 491 if (security != null) { 492 security.checkSecurityAccess(directive); 493 } 494 } 495 }