1 package iaik.pkcs.pkcs11.objects; 2 3 import iaik.pkcs.pkcs11.Session; 4 import iaik.pkcs.pkcs11.TokenException; 5 import iaik.pkcs.pkcs11.wrapper.Constants; 6 import iaik.pkcs.pkcs11.wrapper.PKCS11Constants; 7 import iaik.pkcs.pkcs11.wrapper.PKCS11Exception; 8 9 import java.util.Hashtable; 10 11 /** 12 * An object of this class represents a key as defined by PKCS#11 2.11. 13 * A key is of a specific type: RSA, DSA, DH, ECDSA, EC, X9_42_DH, KEA, 14 * GENERIC_SECRET, RC2, RC4, DES, DES2, DES3, CAST, CAST3, CAST5, CAST128, 15 * RC5, IDEA, SKIPJACK, BATON, JUNIPER, CDMF, AES or VENDOR_DEFINED. 16 * If an application needs to use vendor-defined keys, it must set a 17 * VendorDefinedKeyeBuilder using the setVendorDefinedKeyBuilder method. 18 * 19 * @author Karl Scheibelhofer 20 * @version 1.0 21 * @invariants (keyType_ <> null) 22 * and (id_ <> null) 23 * and (startDate_ <> null) 24 * and (endDate_ <> null) 25 * and (derive_ <> null) 26 * and (local_ <> null) 27 * and (keyGenMechanism_ <> null) 28 */ 29 public class Key extends Storage { 30 31 /** 32 * This interface defines the available key types as defined by PKCS#11 2.11: 33 * RSA, DSA, DH, ECDSA, KEA, GENERIC_SECRET, RC2, RC4, DES, DES2, DES3, CAST, 34 * CAST3, CAST5, CAST128, RC5, IDEA, SKIPJACK, BATON, JUNIPER, CDMF, AES, 35 * EC, X9_42_DH or VENDOR_DEFINED. 36 * 37 * @author Karl Scheibelhofer 38 * @version 1.0 39 * @invariants 40 */ 41 public interface KeyType { 42 43 /** 44 * The identifier for a RSA key. 45 */ 46 static public final Long RSA = new Long(PKCS11Constants.CKK_RSA); 47 48 /** 49 * The identifier for a DSA key. 50 */ 51 static public final Long DSA = new Long(PKCS11Constants.CKK_DSA); 52 53 /** 54 * The identifier for a Diffi-Hellman key. 55 */ 56 static public final Long DH = new Long(PKCS11Constants.CKK_DH); 57 58 /** 59 * The identifier for a ECDSA key. 60 */ 61 static public final Long ECDSA = new Long(PKCS11Constants.CKK_ECDSA); 62 63 /** 64 * The identifier for a EC key. 65 */ 66 static public final Long EC = new Long(PKCS11Constants.CKK_EC); 67 68 /** 69 * The identifier for a EC key. 70 */ 71 static public final Long X9_42_DH = new Long(PKCS11Constants.CKK_X9_42_DH); 72 73 /** 74 * The identifier for a KEA key. 75 */ 76 static public final Long KEA = new Long(PKCS11Constants.CKK_KEA); 77 78 /** 79 * The identifier for a generic secret key. 80 */ 81 static public final Long GENERIC_SECRET = new Long(PKCS11Constants.CKK_GENERIC_SECRET); 82 83 /** 84 * The identifier for a RC2 key. 85 */ 86 static public final Long RC2 = new Long(PKCS11Constants.CKK_RC2); 87 88 /** 89 * The identifier for a RC4 key. 90 */ 91 static public final Long RC4 = new Long(PKCS11Constants.CKK_RC4); 92 93 /** 94 * The identifier for a DES key. 95 */ 96 static public final Long DES = new Long(PKCS11Constants.CKK_DES); 97 98 /** 99 * The identifier for a double-length DES key. 100 */ 101 static public final Long DES2 = new Long(PKCS11Constants.CKK_DES2); 102 103 /** 104 * The identifier for a trible-length DES key (Trible-DES). 105 */ 106 static public final Long DES3 = new Long(PKCS11Constants.CKK_DES3); 107 108 /** 109 * The identifier for a CAST key. 110 */ 111 static public final Long CAST = new Long(PKCS11Constants.CKK_CAST); 112 113 /** 114 * The identifier for a CAST3 key. 115 */ 116 static public final Long CAST3 = new Long(PKCS11Constants.CKK_CAST3); 117 118 /** 119 * The identifier for a CAST5 key; CAST5 is the same as CAST128. 120 */ 121 static public final Long CAST5 = new Long(PKCS11Constants.CKK_CAST5); 122 123 /** 124 * The identifier for a CAST128 key. 125 */ 126 static public final Long CAST128 = new Long(PKCS11Constants.CKK_CAST128); 127 128 /** 129 * The identifier for a RC5 key. 130 */ 131 static public final Long RC5 = new Long(PKCS11Constants.CKK_RC5); 132 133 /** 134 * The identifier for a IDEA key. 135 */ 136 static public final Long IDEA = new Long(PKCS11Constants.CKK_IDEA); 137 138 /** 139 * The identifier for a SKIPJACK key. 140 */ 141 static public final Long SKIPJACK = new Long(PKCS11Constants.CKK_SKIPJACK); 142 143 /** 144 * The identifier for a BATON key. 145 */ 146 static public final Long BATON = new Long(PKCS11Constants.CKK_BATON); 147 148 /** 149 * The identifier for a JUNIPER key. 150 */ 151 static public final Long JUNIPER = new Long(PKCS11Constants.CKK_JUNIPER); 152 153 /** 154 * The identifier for a CDMF key. 155 */ 156 static public final Long CDMF = new Long(PKCS11Constants.CKK_CDMF); 157 158 /** 159 * The identifier for a AES key. 160 */ 161 static public final Long AES = new Long(PKCS11Constants.CKK_AES); 162 163 /** 164 * The identifier for a Blowfish key. 165 */ 166 static public final Long BLOWFISH = new Long(PKCS11Constants.CKK_BLOWFISH); 167 168 /** 169 * The identifier for a Twofish key. 170 */ 171 static public final Long TWOFISH = new Long(PKCS11Constants.CKK_TWOFISH); 172 173 /** 174 * The identifier for a VENDOR_DEFINED key. Any Long object with a 175 * value bigger than this one is also a valid vendor-defined key 176 * type identifier. 177 */ 178 static public final Long VENDOR_DEFINED = new Long(PKCS11Constants.CKK_VENDOR_DEFINED); 179 180 } 181 182 /** 183 * If an application uses vendor defined keys, it must implement this 184 * interface and install such an object handler using 185 * setVendorDefinedKeyBuilder. 186 * 187 * @author Karl Scheibelhofer 188 * @version 1.0 189 * @invariants 190 */ 191 public interface VendorDefinedKeyBuilder { 192 193 /** 194 * This method should instanciate an Object of this class or of any 195 * sub-class. It can use the given handles and PKCS#11 module to retrieve 196 * attributes of the PKCS#11 object from the token. 197 * 198 * @param session The session to use for reading attributes. 199 * This session must have the appropriate rights; i.e. 200 * it must be a user-session, if it is a private object. 201 * @param objectHandle The object handle as given from the PKCS#111 module. 202 * @return The object representing the PKCS#11 object. 203 * The returned object can be casted to the 204 * according sub-class. 205 * @exception PKCS11Exception If getting the attributes failed. 206 * @preconditions (session <> null) 207 * @postconditions (result <> null) 208 */ build(Session session, long objectHandle)209 public Object build(Session session, long objectHandle) 210 throws PKCS11Exception; 211 212 } 213 214 /** 215 * The currently set vendor defined key builder, or null. 216 */ 217 protected static VendorDefinedKeyBuilder vendorKeyBuilder_; 218 219 /** 220 * A table holding string representations for all known key types. Table key 221 * is the key type as Long object. 222 */ 223 protected static Hashtable keyTypeNames_; 224 225 /** 226 * The type of this key. Its value is one of KeyType, or one that has a 227 * bigger value than VENDOR_DEFINED. 228 */ 229 protected KeyTypeAttribute keyType_; 230 231 /** 232 * The identifier (ID) of this key. 233 */ 234 protected ByteArrayAttribute id_; 235 236 /** 237 * The start date of this key's validity. 238 */ 239 protected DateAttribute startDate_; 240 241 /** 242 * The end date of this key's validity. 243 */ 244 protected DateAttribute endDate_; 245 246 /** 247 * True, if other keys can be derived from this key. 248 */ 249 protected BooleanAttribute derive_; 250 251 /** 252 * True, if this key was created (generated or copied from a different key) on 253 * the token. 254 */ 255 protected BooleanAttribute local_; 256 257 /** 258 * The mechanism used to generate the key material. 259 */ 260 protected MechanismAttribute keyGenMechanism_; 261 262 /** 263 * The list of mechanism that can be used with this key. 264 */ 265 protected MechanismArrayAttribute allowedMechanisms_; 266 267 /** 268 * The default constructor. An application use this constructor to instanciate 269 * a key that serves as a template. It may also be useful for working with 270 * vendor-defined keys. 271 * 272 * @preconditions 273 * @postconditions 274 */ Key()275 public Key() { 276 super(); 277 } 278 279 /** 280 * Called by sub-classes to create an instance of a PKCS#11 key. 281 * 282 * @param session The session to use for reading attributes. 283 * This session must have the appropriate rights; i.e. 284 * it must be a user-session, if it is a private object. 285 * @param objectHandle The object handle as given from the PKCS#111 module. 286 * @exception TokenException If getting the attributes failed. 287 * @preconditions (session <> null) 288 * @postconditions 289 */ Key(Session session, long objectHandle)290 protected Key(Session session, long objectHandle) 291 throws TokenException 292 { 293 super(session, objectHandle); 294 } 295 296 /** 297 * Set a vendor-defined key builder that should be called to create an 298 * instance of an vendor-defined PKCS#11 key; i.e. an instance of a 299 * vendor defined sub-class of this class. 300 * 301 * @param builder The vendor-defined key builder. Null to clear any 302 * previously installed vendor-defined builder. 303 * @preconditions 304 * @postconditions 305 */ setVendorDefinedKeyBuilder(VendorDefinedKeyBuilder builder)306 public static void setVendorDefinedKeyBuilder(VendorDefinedKeyBuilder builder) { 307 vendorKeyBuilder_ = builder; 308 } 309 310 /** 311 * Get the currently set vendor-defined key builder. 312 * 313 * @return The currently set vendor-defined key builder or null if 314 * none is set. 315 * @preconditions 316 * @postconditions 317 */ getVendorDefinedKeyBuilder()318 public static VendorDefinedKeyBuilder getVendorDefinedKeyBuilder() { 319 return vendorKeyBuilder_; 320 } 321 322 /** 323 * Get the given key type as string. 324 * 325 * @param keyType The key type to get as string. 326 * @return A string denoting the key type; e.g. "RSA". 327 * @preconditions (keyType <> null) 328 * @postconditions (result <> null) 329 */ getKeyTypeName(Long keyType)330 public static String getKeyTypeName(Long keyType) { 331 String keyTypeName; 332 333 if (keyType == null) { 334 throw new NullPointerException("Argument \"keyType\" must not be null."); 335 } 336 337 if ((keyType.longValue() & PKCS11Constants.CKK_VENDOR_DEFINED) != 0L) { 338 keyTypeName = "Vendor Defined"; 339 } else { 340 if (keyTypeNames_ == null) { 341 // setup key type names table 342 Hashtable keyTypeNames = new Hashtable(24); 343 keyTypeNames.put(KeyType.RSA, "RSA"); 344 keyTypeNames.put(KeyType.DSA, "DSA"); 345 keyTypeNames.put(KeyType.DH, "DH"); 346 keyTypeNames.put(KeyType.ECDSA, "ECDSA"); 347 keyTypeNames.put(KeyType.EC, "EC"); 348 keyTypeNames.put(KeyType.X9_42_DH, "X9_42_DH"); 349 keyTypeNames.put(KeyType.KEA, "KEA"); 350 keyTypeNames.put(KeyType.GENERIC_SECRET, "GENERIC_SECRET"); 351 keyTypeNames.put(KeyType.RC2, "RC2"); 352 keyTypeNames.put(KeyType.RC4, "RC4"); 353 keyTypeNames.put(KeyType.DES, "DES"); 354 keyTypeNames.put(KeyType.DES2, "DES2"); 355 keyTypeNames.put(KeyType.DES3, "DES3"); 356 keyTypeNames.put(KeyType.CAST, "CAST"); 357 keyTypeNames.put(KeyType.CAST3, "CAST3"); 358 keyTypeNames.put(KeyType.CAST5, "CAST5"); 359 keyTypeNames.put(KeyType.CAST128, "CAST128"); 360 keyTypeNames.put(KeyType.RC5, "RC5"); 361 keyTypeNames.put(KeyType.IDEA, "IDEA"); 362 keyTypeNames.put(KeyType.SKIPJACK, "SKIPJACK"); 363 keyTypeNames.put(KeyType.BATON, "BATON"); 364 keyTypeNames.put(KeyType.JUNIPER, "JUNIPER"); 365 keyTypeNames.put(KeyType.CDMF, "CDMF"); 366 keyTypeNames.put(KeyType.AES, "AES"); 367 keyTypeNames.put(KeyType.BLOWFISH, "BLOWFISH"); 368 keyTypeNames.put(KeyType.TWOFISH, "TWOFISH"); 369 keyTypeNames_ = keyTypeNames; 370 } 371 372 keyTypeName = (String) keyTypeNames_.get(keyType); 373 if (keyTypeName == null) { 374 keyTypeName = "<unknown>"; 375 } 376 } 377 378 return keyTypeName; 379 } 380 381 /** 382 * Put all attributes of the given object into the attributes table of this 383 * object. This method is only static to be able to access invoke the 384 * implementation of this method for each class separately (see use in 385 * clone()). 386 * 387 * @param object The object to handle. 388 * @preconditions (object <> null) 389 * @postconditions 390 */ putAttributesInTable(Key object)391 protected static void putAttributesInTable(Key object) { 392 if (object == null) { 393 throw new NullPointerException("Argument \"object\" must not be null."); 394 } 395 396 object.attributeTable_.put(Attribute.KEY_TYPE, object.keyType_); 397 object.attributeTable_.put(Attribute.ID, object.id_); 398 object.attributeTable_.put(Attribute.START_DATE, object.startDate_); 399 object.attributeTable_.put(Attribute.END_DATE, object.endDate_); 400 object.attributeTable_.put(Attribute.DERIVE, object.derive_); 401 object.attributeTable_.put(Attribute.LOCAL, object.local_); 402 object.attributeTable_.put(Attribute.KEY_GEN_MECHANISM, object.keyGenMechanism_); 403 object.attributeTable_.put(Attribute.ALLOWED_MECHANISMS, object.allowedMechanisms_); 404 } 405 406 /** 407 * Allocates the attribute objects for this class and adds them to the 408 * attribute table. 409 * 410 * @preconditions 411 * @postconditions 412 */ allocateAttributes()413 protected void allocateAttributes() { 414 super.allocateAttributes(); 415 416 keyType_ = new KeyTypeAttribute(); 417 id_ = new ByteArrayAttribute(Attribute.ID); 418 startDate_ = new DateAttribute(Attribute.START_DATE); 419 endDate_ = new DateAttribute(Attribute.END_DATE); 420 derive_ = new BooleanAttribute(Attribute.DERIVE); 421 local_ = new BooleanAttribute(Attribute.LOCAL); 422 keyGenMechanism_ = new MechanismAttribute(Attribute.KEY_GEN_MECHANISM); 423 allowedMechanisms_ = new MechanismArrayAttribute(Attribute.ALLOWED_MECHANISMS); 424 425 putAttributesInTable(this); 426 } 427 428 /** 429 * Create a (deep) clone of this object. 430 * 431 * @return A clone of this object. 432 * @preconditions 433 * @postconditions (result <> null) 434 * and (result instanceof Key) 435 * and (result.equals(this)) 436 */ clone()437 public java.lang.Object clone() { 438 Key clone = (Key) super.clone(); 439 440 clone.keyType_ = (KeyTypeAttribute) this.keyType_.clone(); 441 clone.id_ = (ByteArrayAttribute) this.id_.clone(); 442 clone.startDate_ = (DateAttribute) this.startDate_.clone(); 443 clone.endDate_ = (DateAttribute) this.endDate_.clone(); 444 clone.derive_ = (BooleanAttribute) this.derive_.clone(); 445 clone.local_ = (BooleanAttribute) this.local_.clone(); 446 clone.keyGenMechanism_ = (MechanismAttribute) this.keyGenMechanism_.clone(); 447 clone.allowedMechanisms_ = (MechanismArrayAttribute) this.allowedMechanisms_.clone(); 448 449 putAttributesInTable(clone); // put all cloned attributes into the new table 450 451 return clone; 452 } 453 454 /** 455 * Compares all member variables of this object with the other object. 456 * Returns only true, if all are equal in both objects. 457 * 458 * @param otherObject The other object to compare to. 459 * @return True, if other is an instance of this class and all member 460 * variables of both objects are equal. False, otherwise. 461 * @preconditions 462 * @postconditions 463 */ equals(java.lang.Object otherObject)464 public boolean equals(java.lang.Object otherObject) { 465 boolean equal = false; 466 467 if (otherObject instanceof Key) { 468 Key other = (Key) otherObject; 469 equal = (this == other) 470 || (super.equals(other) && this.keyType_.equals(other.keyType_) 471 && this.id_.equals(other.id_) && this.startDate_.equals(other.startDate_) 472 && this.endDate_.equals(other.endDate_) 473 && this.derive_.equals(other.derive_) && this.local_.equals(other.local_) 474 && this.keyGenMechanism_.equals(other.keyGenMechanism_) && this.allowedMechanisms_ 475 .equals(other.allowedMechanisms_)); 476 } 477 478 return equal; 479 } 480 481 /** 482 * Gets the key type attribute of the PKCS#11 key. Its value must 483 * be one of those defined in the KeyType interface or one with an 484 * value bigger than KeyType.VENDOR_DEFINED. 485 * 486 * @return The key type identifier. 487 * @preconditions 488 * @postconditions (result <> null) 489 */ getKeyType()490 public LongAttribute getKeyType() { 491 return keyType_; 492 } 493 494 /** 495 * Gets the ID attribute of this key. 496 * 497 * @return The key identifier attribute. 498 * @preconditions 499 * @postconditions (result <> null) 500 */ getId()501 public ByteArrayAttribute getId() { 502 return id_; 503 } 504 505 /** 506 * Gets the start date attribute of the validity of this key. 507 * 508 * @return The start date of validity. 509 * @preconditions 510 * @postconditions (result <> null) 511 */ getStartDate()512 public DateAttribute getStartDate() { 513 return startDate_; 514 } 515 516 /** 517 * Gets the end date attribute of the validity of this key. 518 * 519 * @return The end date of validity. 520 * @preconditions 521 * @postconditions (result <> null) 522 */ getEndDate()523 public DateAttribute getEndDate() { 524 return endDate_; 525 } 526 527 /** 528 * Check, if other keys can be derived from this key. 529 * 530 * @return Its value is true, if other keys can be derived from this key. 531 * @preconditions 532 * @postconditions (result <> null) 533 */ getDerive()534 public BooleanAttribute getDerive() { 535 return derive_; 536 } 537 538 /** 539 * Check, if this key is a local key; i.e. was generated on the token or 540 * created via copy from a different key on the token. 541 * 542 * @return Its value is true, if the key was created on the token. 543 * @preconditions 544 * @postconditions (result <> null) 545 */ getLocal()546 public BooleanAttribute getLocal() { 547 return local_; 548 } 549 550 /** 551 * Get the mechanism used to generate the key material for this key. 552 * 553 * @return The mechanism attribute used to generate the key material for this 554 * key. 555 * @preconditions 556 * @postconditions (result <> null) 557 */ getKeyGenMechanism()558 public MechanismAttribute getKeyGenMechanism() { 559 return keyGenMechanism_; 560 } 561 562 /** 563 * Get the list of mechanisms that are allowed to use with this key. This 564 * attribute can only be used with PKCS#11 modules supporting 565 * cryptoki version 2.20 or higher. 566 * 567 * @return The list of mechanisms that are allowed to use with this key. 568 * @preconditions 569 * @postconditions (result <> null) 570 */ getAllowedMechanisms()571 public MechanismArrayAttribute getAllowedMechanisms() { 572 return allowedMechanisms_; 573 } 574 575 /** 576 * The overriding of this method should ensure that the objects of this class 577 * work correctly in a hashtable. 578 * 579 * @return The hash code of this object. 580 * @preconditions 581 * @postconditions 582 */ hashCode()583 public int hashCode() { 584 return keyType_.hashCode() ^ id_.hashCode(); 585 } 586 587 /** 588 * Read the values of the attributes of this object from the token. 589 * 590 * @param session The session handle to use for reading attributes. 591 * This session must have the appropriate rights; i.e. 592 * it must be a user-session, if it is a private object. 593 * @exception TokenException If getting the attributes failed. 594 * @preconditions (session <> null) 595 * @postconditions 596 */ readAttributes(Session session)597 public void readAttributes(Session session) 598 throws TokenException 599 { 600 super.readAttributes(session); 601 602 // Object.getAttributeValue(session, objectHandle_, id_); 603 // Object.getAttributeValue(session, objectHandle_, startDate_); 604 // Object.getAttributeValue(session, objectHandle_, endDate_); 605 // Object.getAttributeValue(session, objectHandle_, derive_); 606 // Object.getAttributeValue(session, objectHandle_, local_); 607 // Object.getAttributeValue(session, objectHandle_, keyGenMechanism_); 608 Object.getAttributeValues(session, objectHandle_, new Attribute[] { id_, startDate_, 609 endDate_, derive_, local_, keyGenMechanism_ }); 610 Object.getAttributeValue(session, objectHandle_, allowedMechanisms_); 611 } 612 613 /** 614 * This method returns a string representation of the current object. The 615 * output is only for debugging purposes and should not be used for other 616 * purposes. 617 * 618 * @return A string presentation of this object for debugging output. 619 * @preconditions 620 * @postconditions (result <> null) 621 */ toString()622 public String toString() { 623 StringBuffer buffer = new StringBuffer(256); 624 625 buffer.append(super.toString()); 626 627 buffer.append(Constants.NEWLINE); 628 buffer.append(Constants.INDENT); 629 buffer.append("Key Type: "); 630 if (keyType_ != null) { 631 buffer.append(keyType_.toString()); 632 } else { 633 buffer.append("<unavailable>"); 634 } 635 636 buffer.append(Constants.NEWLINE); 637 buffer.append(Constants.INDENT); 638 buffer.append("ID: "); 639 buffer.append(id_.toString()); 640 641 buffer.append(Constants.NEWLINE); 642 buffer.append(Constants.INDENT); 643 buffer.append("Start Date: "); 644 buffer.append(startDate_.toString()); 645 646 buffer.append(Constants.NEWLINE); 647 buffer.append(Constants.INDENT); 648 buffer.append("End Date: "); 649 buffer.append(endDate_.toString()); 650 651 buffer.append(Constants.NEWLINE); 652 buffer.append(Constants.INDENT); 653 buffer.append("Derive: "); 654 buffer.append(derive_.toString()); 655 656 buffer.append(Constants.NEWLINE); 657 buffer.append(Constants.INDENT); 658 buffer.append("Local: "); 659 buffer.append(local_.toString()); 660 661 buffer.append(Constants.NEWLINE); 662 buffer.append(Constants.INDENT); 663 buffer.append("Key Generation Mechanism: "); 664 buffer.append(keyGenMechanism_.toString()); 665 666 buffer.append(Constants.NEWLINE); 667 buffer.append(Constants.INDENT); 668 buffer.append("Allowed Mechanisms: "); 669 buffer.append(allowedMechanisms_.toString()); 670 671 return buffer.toString(); 672 } 673 674 } 675