1/* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5/** 6 * Licensed to the Apache Software Foundation (ASF) under one 7 * or more contributor license agreements. See the NOTICE file 8 * distributed with this work for additional information 9 * regarding copyright ownership. The ASF licenses this file 10 * to you under the Apache License, Version 2.0 (the 11 * "License"); you may not use this file except in compliance 12 * with the License. You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, 17 * software distributed under the License is distributed on an 18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 19 * KIND, either express or implied. See the License for the 20 * specific language governing permissions and limitations 21 * under the License. 22 */ 23package com.sun.org.apache.xml.internal.security.keys; 24 25import java.security.PrivateKey; 26import java.security.PublicKey; 27import java.security.cert.X509Certificate; 28import java.util.ArrayList; 29import java.util.Iterator; 30import java.util.List; 31 32import javax.crypto.SecretKey; 33 34import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey; 35import com.sun.org.apache.xml.internal.security.encryption.XMLCipher; 36import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException; 37import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException; 38import com.sun.org.apache.xml.internal.security.keys.content.DEREncodedKeyValue; 39import com.sun.org.apache.xml.internal.security.keys.content.KeyInfoReference; 40import com.sun.org.apache.xml.internal.security.keys.content.KeyName; 41import com.sun.org.apache.xml.internal.security.keys.content.KeyValue; 42import com.sun.org.apache.xml.internal.security.keys.content.MgmtData; 43import com.sun.org.apache.xml.internal.security.keys.content.PGPData; 44import com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod; 45import com.sun.org.apache.xml.internal.security.keys.content.SPKIData; 46import com.sun.org.apache.xml.internal.security.keys.content.X509Data; 47import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.DSAKeyValue; 48import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue; 49import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver; 50import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException; 51import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi; 52import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver; 53import com.sun.org.apache.xml.internal.security.transforms.Transforms; 54import com.sun.org.apache.xml.internal.security.utils.Constants; 55import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants; 56import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy; 57import com.sun.org.apache.xml.internal.security.utils.XMLUtils; 58import org.w3c.dom.Attr; 59import org.w3c.dom.Document; 60import org.w3c.dom.Element; 61import org.w3c.dom.Node; 62import org.w3c.dom.NodeList; 63 64/** 65 * This class stand for KeyInfo Element that may contain keys, names, 66 * certificates and other public key management information, 67 * such as in-band key distribution or key agreement data. 68 * <BR /> 69 * KeyInfo Element has two basic functions: 70 * One is KeyResolve for getting the public key in signature validation processing. 71 * the other one is toElement for getting the element in signature generation processing. 72 * <BR /> 73 * The <CODE>lengthXXX()</CODE> methods provide access to the internal Key 74 * objects: 75 * <UL> 76 * <LI>If the <CODE>KeyInfo</CODE> was constructed from an Element 77 * (Signature verification), the <CODE>lengthXXX()</CODE> methods searches 78 * for child elements of <CODE>ds:KeyInfo</CODE> for known types. </LI> 79 * <LI>If the <CODE>KeyInfo</CODE> was constructed from scratch (during 80 * Signature generation), the <CODE>lengthXXX()</CODE> methods return the number 81 * of <CODE>XXXs</CODE> objects already passed to the KeyInfo</LI> 82 * </UL> 83 * <BR /> 84 * The <CODE>addXXX()</CODE> methods are used for adding Objects of the 85 * appropriate type to the <CODE>KeyInfo</CODE>. This is used during signature 86 * generation. 87 * <BR /> 88 * The <CODE>itemXXX(int i)</CODE> methods return the i'th object of the 89 * corresponding type. 90 * <BR /> 91 * The <CODE>containsXXX()</CODE> methods return <I>whether</I> the KeyInfo 92 * contains the corresponding type. 93 * 94 */ 95public class KeyInfo extends SignatureElementProxy { 96 97 /** {@link org.apache.commons.logging} logging facility */ 98 private static java.util.logging.Logger log = 99 java.util.logging.Logger.getLogger(KeyInfo.class.getName()); 100 101 // We need at least one StorageResolver otherwise 102 // the KeyResolvers would not be called. 103 // The default StorageResolver is null. 104 105 private List<X509Data> x509Datas = null; 106 private List<EncryptedKey> encryptedKeys = null; 107 108 private static final List<StorageResolver> nullList; 109 static { 110 List<StorageResolver> list = new ArrayList<StorageResolver>(1); 111 list.add(null); 112 nullList = java.util.Collections.unmodifiableList(list); 113 } 114 115 /** Field storageResolvers */ 116 private List<StorageResolver> storageResolvers = nullList; 117 118 /** 119 * Stores the individual (per-KeyInfo) {@link KeyResolverSpi}s 120 */ 121 private List<KeyResolverSpi> internalKeyResolvers = new ArrayList<KeyResolverSpi>(); 122 123 private boolean secureValidation; 124 125 /** 126 * Constructor KeyInfo 127 * @param doc 128 */ 129 public KeyInfo(Document doc) { 130 super(doc); 131 132 XMLUtils.addReturnToElement(this.constructionElement); 133 } 134 135 /** 136 * Constructor KeyInfo 137 * 138 * @param element 139 * @param baseURI 140 * @throws XMLSecurityException 141 */ 142 public KeyInfo(Element element, String baseURI) throws XMLSecurityException { 143 super(element, baseURI); 144 145 Attr attr = element.getAttributeNodeNS(null, "Id"); 146 if (attr != null) { 147 element.setIdAttributeNode(attr, true); 148 } 149 } 150 151 /** 152 * Set whether secure processing is enabled or not. The default is false. 153 */ 154 public void setSecureValidation(boolean secureValidation) { 155 this.secureValidation = secureValidation; 156 } 157 158 /** 159 * Sets the <code>Id</code> attribute 160 * 161 * @param Id ID 162 */ 163 public void setId(String id) { 164 if (id != null) { 165 this.constructionElement.setAttributeNS(null, Constants._ATT_ID, id); 166 this.constructionElement.setIdAttributeNS(null, Constants._ATT_ID, true); 167 } 168 } 169 170 /** 171 * Returns the <code>Id</code> attribute 172 * 173 * @return the <code>Id</code> attribute 174 */ 175 public String getId() { 176 return this.constructionElement.getAttributeNS(null, Constants._ATT_ID); 177 } 178 179 /** 180 * Method addKeyName 181 * 182 * @param keynameString 183 */ 184 public void addKeyName(String keynameString) { 185 this.add(new KeyName(this.doc, keynameString)); 186 } 187 188 /** 189 * Method add 190 * 191 * @param keyname 192 */ 193 public void add(KeyName keyname) { 194 this.constructionElement.appendChild(keyname.getElement()); 195 XMLUtils.addReturnToElement(this.constructionElement); 196 } 197 198 /** 199 * Method addKeyValue 200 * 201 * @param pk 202 */ 203 public void addKeyValue(PublicKey pk) { 204 this.add(new KeyValue(this.doc, pk)); 205 } 206 207 /** 208 * Method addKeyValue 209 * 210 * @param unknownKeyValueElement 211 */ 212 public void addKeyValue(Element unknownKeyValueElement) { 213 this.add(new KeyValue(this.doc, unknownKeyValueElement)); 214 } 215 216 /** 217 * Method add 218 * 219 * @param dsakeyvalue 220 */ 221 public void add(DSAKeyValue dsakeyvalue) { 222 this.add(new KeyValue(this.doc, dsakeyvalue)); 223 } 224 225 /** 226 * Method add 227 * 228 * @param rsakeyvalue 229 */ 230 public void add(RSAKeyValue rsakeyvalue) { 231 this.add(new KeyValue(this.doc, rsakeyvalue)); 232 } 233 234 /** 235 * Method add 236 * 237 * @param pk 238 */ 239 public void add(PublicKey pk) { 240 this.add(new KeyValue(this.doc, pk)); 241 } 242 243 /** 244 * Method add 245 * 246 * @param keyvalue 247 */ 248 public void add(KeyValue keyvalue) { 249 this.constructionElement.appendChild(keyvalue.getElement()); 250 XMLUtils.addReturnToElement(this.constructionElement); 251 } 252 253 /** 254 * Method addMgmtData 255 * 256 * @param mgmtdata 257 */ 258 public void addMgmtData(String mgmtdata) { 259 this.add(new MgmtData(this.doc, mgmtdata)); 260 } 261 262 /** 263 * Method add 264 * 265 * @param mgmtdata 266 */ 267 public void add(MgmtData mgmtdata) { 268 this.constructionElement.appendChild(mgmtdata.getElement()); 269 XMLUtils.addReturnToElement(this.constructionElement); 270 } 271 272 /** 273 * Method addPGPData 274 * 275 * @param pgpdata 276 */ 277 public void add(PGPData pgpdata) { 278 this.constructionElement.appendChild(pgpdata.getElement()); 279 XMLUtils.addReturnToElement(this.constructionElement); 280 } 281 282 /** 283 * Method addRetrievalMethod 284 * 285 * @param uri 286 * @param transforms 287 * @param Type 288 */ 289 public void addRetrievalMethod(String uri, Transforms transforms, String Type) { 290 this.add(new RetrievalMethod(this.doc, uri, transforms, Type)); 291 } 292 293 /** 294 * Method add 295 * 296 * @param retrievalmethod 297 */ 298 public void add(RetrievalMethod retrievalmethod) { 299 this.constructionElement.appendChild(retrievalmethod.getElement()); 300 XMLUtils.addReturnToElement(this.constructionElement); 301 } 302 303 /** 304 * Method add 305 * 306 * @param spkidata 307 */ 308 public void add(SPKIData spkidata) { 309 this.constructionElement.appendChild(spkidata.getElement()); 310 XMLUtils.addReturnToElement(this.constructionElement); 311 } 312 313 /** 314 * Method addX509Data 315 * 316 * @param x509data 317 */ 318 public void add(X509Data x509data) { 319 if (x509Datas == null) { 320 x509Datas = new ArrayList<X509Data>(); 321 } 322 x509Datas.add(x509data); 323 this.constructionElement.appendChild(x509data.getElement()); 324 XMLUtils.addReturnToElement(this.constructionElement); 325 } 326 327 /** 328 * Method addEncryptedKey 329 * 330 * @param encryptedKey 331 * @throws XMLEncryptionException 332 */ 333 334 public void add(EncryptedKey encryptedKey) throws XMLEncryptionException { 335 if (encryptedKeys == null) { 336 encryptedKeys = new ArrayList<EncryptedKey>(); 337 } 338 encryptedKeys.add(encryptedKey); 339 XMLCipher cipher = XMLCipher.getInstance(); 340 this.constructionElement.appendChild(cipher.martial(encryptedKey)); 341 } 342 343 /** 344 * Method addDEREncodedKeyValue 345 * 346 * @param pk 347 * @throws XMLSecurityException 348 */ 349 public void addDEREncodedKeyValue(PublicKey pk) throws XMLSecurityException { 350 this.add(new DEREncodedKeyValue(this.doc, pk)); 351 } 352 353 /** 354 * Method add 355 * 356 * @param derEncodedKeyValue 357 */ 358 public void add(DEREncodedKeyValue derEncodedKeyValue) { 359 this.constructionElement.appendChild(derEncodedKeyValue.getElement()); 360 XMLUtils.addReturnToElement(this.constructionElement); 361 } 362 363 /** 364 * Method addKeyInfoReference 365 * 366 * @param URI 367 * @throws XMLSecurityException 368 */ 369 public void addKeyInfoReference(String URI) throws XMLSecurityException { 370 this.add(new KeyInfoReference(this.doc, URI)); 371 } 372 373 /** 374 * Method add 375 * 376 * @param keyInfoReference 377 */ 378 public void add(KeyInfoReference keyInfoReference) { 379 this.constructionElement.appendChild(keyInfoReference.getElement()); 380 XMLUtils.addReturnToElement(this.constructionElement); 381 } 382 383 /** 384 * Method addUnknownElement 385 * 386 * @param element 387 */ 388 public void addUnknownElement(Element element) { 389 this.constructionElement.appendChild(element); 390 XMLUtils.addReturnToElement(this.constructionElement); 391 } 392 393 /** 394 * Method lengthKeyName 395 * 396 * @return the number of the KeyName tags 397 */ 398 public int lengthKeyName() { 399 return this.length(Constants.SignatureSpecNS, Constants._TAG_KEYNAME); 400 } 401 402 /** 403 * Method lengthKeyValue 404 * 405 *@return the number of the KeyValue tags 406 */ 407 public int lengthKeyValue() { 408 return this.length(Constants.SignatureSpecNS, Constants._TAG_KEYVALUE); 409 } 410 411 /** 412 * Method lengthMgmtData 413 * 414 *@return the number of the MgmtData tags 415 */ 416 public int lengthMgmtData() { 417 return this.length(Constants.SignatureSpecNS, Constants._TAG_MGMTDATA); 418 } 419 420 /** 421 * Method lengthPGPData 422 * 423 *@return the number of the PGPDat. tags 424 */ 425 public int lengthPGPData() { 426 return this.length(Constants.SignatureSpecNS, Constants._TAG_PGPDATA); 427 } 428 429 /** 430 * Method lengthRetrievalMethod 431 * 432 *@return the number of the RetrievalMethod tags 433 */ 434 public int lengthRetrievalMethod() { 435 return this.length(Constants.SignatureSpecNS, Constants._TAG_RETRIEVALMETHOD); 436 } 437 438 /** 439 * Method lengthSPKIData 440 * 441 *@return the number of the SPKIData tags 442 */ 443 public int lengthSPKIData() { 444 return this.length(Constants.SignatureSpecNS, Constants._TAG_SPKIDATA); 445 } 446 447 /** 448 * Method lengthX509Data 449 * 450 *@return the number of the X509Data tags 451 */ 452 public int lengthX509Data() { 453 if (x509Datas != null) { 454 return x509Datas.size(); 455 } 456 return this.length(Constants.SignatureSpecNS, Constants._TAG_X509DATA); 457 } 458 459 /** 460 * Method lengthDEREncodedKeyValue 461 * 462 *@return the number of the DEREncodedKeyValue tags 463 */ 464 public int lengthDEREncodedKeyValue() { 465 return this.length(Constants.SignatureSpec11NS, Constants._TAG_DERENCODEDKEYVALUE); 466 } 467 468 /** 469 * Method lengthKeyInfoReference 470 * 471 *@return the number of the KeyInfoReference tags 472 */ 473 public int lengthKeyInfoReference() { 474 return this.length(Constants.SignatureSpec11NS, Constants._TAG_KEYINFOREFERENCE); 475 } 476 477 /** 478 * Method lengthUnknownElement 479 * NOTE possibly buggy. 480 * @return the number of the UnknownElement tags 481 */ 482 public int lengthUnknownElement() { 483 int res = 0; 484 NodeList nl = this.constructionElement.getChildNodes(); 485 486 for (int i = 0; i < nl.getLength(); i++) { 487 Node current = nl.item(i); 488 489 /** 490 * $todo$ using this method, we don't see unknown Elements 491 * from Signature NS; revisit 492 */ 493 if ((current.getNodeType() == Node.ELEMENT_NODE) 494 && current.getNamespaceURI().equals(Constants.SignatureSpecNS)) { 495 res++; 496 } 497 } 498 499 return res; 500 } 501 502 /** 503 * Method itemKeyName 504 * 505 * @param i 506 * @return the asked KeyName element, null if the index is too big 507 * @throws XMLSecurityException 508 */ 509 public KeyName itemKeyName(int i) throws XMLSecurityException { 510 Element e = 511 XMLUtils.selectDsNode( 512 this.constructionElement.getFirstChild(), Constants._TAG_KEYNAME, i); 513 514 if (e != null) { 515 return new KeyName(e, this.baseURI); 516 } 517 return null; 518 } 519 520 /** 521 * Method itemKeyValue 522 * 523 * @param i 524 * @return the asked KeyValue element, null if the index is too big 525 * @throws XMLSecurityException 526 */ 527 public KeyValue itemKeyValue(int i) throws XMLSecurityException { 528 Element e = 529 XMLUtils.selectDsNode( 530 this.constructionElement.getFirstChild(), Constants._TAG_KEYVALUE, i); 531 532 if (e != null) { 533 return new KeyValue(e, this.baseURI); 534 } 535 return null; 536 } 537 538 /** 539 * Method itemMgmtData 540 * 541 * @param i 542 * @return the asked MgmtData element, null if the index is too big 543 * @throws XMLSecurityException 544 */ 545 public MgmtData itemMgmtData(int i) throws XMLSecurityException { 546 Element e = 547 XMLUtils.selectDsNode( 548 this.constructionElement.getFirstChild(), Constants._TAG_MGMTDATA, i); 549 550 if (e != null) { 551 return new MgmtData(e, this.baseURI); 552 } 553 return null; 554 } 555 556 /** 557 * Method itemPGPData 558 * 559 * @param i 560 * @return the asked PGPData element, null if the index is too big 561 * @throws XMLSecurityException 562 */ 563 public PGPData itemPGPData(int i) throws XMLSecurityException { 564 Element e = 565 XMLUtils.selectDsNode( 566 this.constructionElement.getFirstChild(), Constants._TAG_PGPDATA, i); 567 568 if (e != null) { 569 return new PGPData(e, this.baseURI); 570 } 571 return null; 572 } 573 574 /** 575 * Method itemRetrievalMethod 576 * 577 * @param i 578 *@return the asked RetrievalMethod element, null if the index is too big 579 * @throws XMLSecurityException 580 */ 581 public RetrievalMethod itemRetrievalMethod(int i) throws XMLSecurityException { 582 Element e = 583 XMLUtils.selectDsNode( 584 this.constructionElement.getFirstChild(), Constants._TAG_RETRIEVALMETHOD, i); 585 586 if (e != null) { 587 return new RetrievalMethod(e, this.baseURI); 588 } 589 return null; 590 } 591 592 /** 593 * Method itemSPKIData 594 * 595 * @param i 596 * @return the asked SPKIData element, null if the index is too big 597 * @throws XMLSecurityException 598 */ 599 public SPKIData itemSPKIData(int i) throws XMLSecurityException { 600 Element e = 601 XMLUtils.selectDsNode( 602 this.constructionElement.getFirstChild(), Constants._TAG_SPKIDATA, i); 603 604 if (e != null) { 605 return new SPKIData(e, this.baseURI); 606 } 607 return null; 608 } 609 610 /** 611 * Method itemX509Data 612 * 613 * @param i 614 * @return the asked X509Data element, null if the index is too big 615 * @throws XMLSecurityException 616 */ 617 public X509Data itemX509Data(int i) throws XMLSecurityException { 618 if (x509Datas != null) { 619 return x509Datas.get(i); 620 } 621 Element e = 622 XMLUtils.selectDsNode( 623 this.constructionElement.getFirstChild(), Constants._TAG_X509DATA, i); 624 625 if (e != null) { 626 return new X509Data(e, this.baseURI); 627 } 628 return null; 629 } 630 631 /** 632 * Method itemEncryptedKey 633 * 634 * @param i 635 * @return the asked EncryptedKey element, null if the index is too big 636 * @throws XMLSecurityException 637 */ 638 public EncryptedKey itemEncryptedKey(int i) throws XMLSecurityException { 639 if (encryptedKeys != null) { 640 return encryptedKeys.get(i); 641 } 642 Element e = 643 XMLUtils.selectXencNode( 644 this.constructionElement.getFirstChild(), EncryptionConstants._TAG_ENCRYPTEDKEY, i); 645 646 if (e != null) { 647 XMLCipher cipher = XMLCipher.getInstance(); 648 cipher.init(XMLCipher.UNWRAP_MODE, null); 649 return cipher.loadEncryptedKey(e); 650 } 651 return null; 652 } 653 654 /** 655 * Method itemDEREncodedKeyValue 656 * 657 * @param i 658 * @return the asked DEREncodedKeyValue element, null if the index is too big 659 * @throws XMLSecurityException 660 */ 661 public DEREncodedKeyValue itemDEREncodedKeyValue(int i) throws XMLSecurityException { 662 Element e = 663 XMLUtils.selectDs11Node( 664 this.constructionElement.getFirstChild(), Constants._TAG_DERENCODEDKEYVALUE, i); 665 666 if (e != null) { 667 return new DEREncodedKeyValue(e, this.baseURI); 668 } 669 return null; 670 } 671 672 /** 673 * Method itemKeyInfoReference 674 * 675 * @param i 676 * @return the asked KeyInfoReference element, null if the index is too big 677 * @throws XMLSecurityException 678 */ 679 public KeyInfoReference itemKeyInfoReference(int i) throws XMLSecurityException { 680 Element e = 681 XMLUtils.selectDs11Node( 682 this.constructionElement.getFirstChild(), Constants._TAG_KEYINFOREFERENCE, i); 683 684 if (e != null) { 685 return new KeyInfoReference(e, this.baseURI); 686 } 687 return null; 688 } 689 690 /** 691 * Method itemUnknownElement 692 * 693 * @param i index 694 * @return the element number of the unknown elements 695 */ 696 public Element itemUnknownElement(int i) { 697 NodeList nl = this.constructionElement.getChildNodes(); 698 int res = 0; 699 700 for (int j = 0; j < nl.getLength(); j++) { 701 Node current = nl.item(j); 702 703 /** 704 * $todo$ using this method, we don't see unknown Elements 705 * from Signature NS; revisit 706 */ 707 if ((current.getNodeType() == Node.ELEMENT_NODE) 708 && current.getNamespaceURI().equals(Constants.SignatureSpecNS)) { 709 res++; 710 711 if (res == i) { 712 return (Element) current; 713 } 714 } 715 } 716 717 return null; 718 } 719 720 /** 721 * Method isEmpty 722 * 723 * @return true if the element has no descendants. 724 */ 725 public boolean isEmpty() { 726 return this.constructionElement.getFirstChild() == null; 727 } 728 729 /** 730 * Method containsKeyName 731 * 732 * @return If the KeyInfo contains a KeyName node 733 */ 734 public boolean containsKeyName() { 735 return this.lengthKeyName() > 0; 736 } 737 738 /** 739 * Method containsKeyValue 740 * 741 * @return If the KeyInfo contains a KeyValue node 742 */ 743 public boolean containsKeyValue() { 744 return this.lengthKeyValue() > 0; 745 } 746 747 /** 748 * Method containsMgmtData 749 * 750 * @return If the KeyInfo contains a MgmtData node 751 */ 752 public boolean containsMgmtData() { 753 return this.lengthMgmtData() > 0; 754 } 755 756 /** 757 * Method containsPGPData 758 * 759 * @return If the KeyInfo contains a PGPData node 760 */ 761 public boolean containsPGPData() { 762 return this.lengthPGPData() > 0; 763 } 764 765 /** 766 * Method containsRetrievalMethod 767 * 768 * @return If the KeyInfo contains a RetrievalMethod node 769 */ 770 public boolean containsRetrievalMethod() { 771 return this.lengthRetrievalMethod() > 0; 772 } 773 774 /** 775 * Method containsSPKIData 776 * 777 * @return If the KeyInfo contains a SPKIData node 778 */ 779 public boolean containsSPKIData() { 780 return this.lengthSPKIData() > 0; 781 } 782 783 /** 784 * Method containsUnknownElement 785 * 786 * @return If the KeyInfo contains a UnknownElement node 787 */ 788 public boolean containsUnknownElement() { 789 return this.lengthUnknownElement() > 0; 790 } 791 792 /** 793 * Method containsX509Data 794 * 795 * @return If the KeyInfo contains a X509Data node 796 */ 797 public boolean containsX509Data() { 798 return this.lengthX509Data() > 0; 799 } 800 801 /** 802 * Method containsDEREncodedKeyValue 803 * 804 * @return If the KeyInfo contains a DEREncodedKeyValue node 805 */ 806 public boolean containsDEREncodedKeyValue() { 807 return this.lengthDEREncodedKeyValue() > 0; 808 } 809 810 /** 811 * Method containsKeyInfoReference 812 * 813 * @return If the KeyInfo contains a KeyInfoReference node 814 */ 815 public boolean containsKeyInfoReference() { 816 return this.lengthKeyInfoReference() > 0; 817 } 818 819 /** 820 * This method returns the public key. 821 * 822 * @return If the KeyInfo contains a PublicKey node 823 * @throws KeyResolverException 824 */ 825 public PublicKey getPublicKey() throws KeyResolverException { 826 PublicKey pk = this.getPublicKeyFromInternalResolvers(); 827 828 if (pk != null) { 829 if (log.isLoggable(java.util.logging.Level.FINE)) { 830 log.log(java.util.logging.Level.FINE, "I could find a key using the per-KeyInfo key resolvers"); 831 } 832 833 return pk; 834 } 835 if (log.isLoggable(java.util.logging.Level.FINE)) { 836 log.log(java.util.logging.Level.FINE, "I couldn't find a key using the per-KeyInfo key resolvers"); 837 } 838 839 pk = this.getPublicKeyFromStaticResolvers(); 840 841 if (pk != null) { 842 if (log.isLoggable(java.util.logging.Level.FINE)) { 843 log.log(java.util.logging.Level.FINE, "I could find a key using the system-wide key resolvers"); 844 } 845 846 return pk; 847 } 848 if (log.isLoggable(java.util.logging.Level.FINE)) { 849 log.log(java.util.logging.Level.FINE, "I couldn't find a key using the system-wide key resolvers"); 850 } 851 852 return null; 853 } 854 855 /** 856 * Searches the library wide KeyResolvers for public keys 857 * 858 * @return The public key contained in this Node. 859 * @throws KeyResolverException 860 */ 861 PublicKey getPublicKeyFromStaticResolvers() throws KeyResolverException { 862 Iterator<KeyResolverSpi> it = KeyResolver.iterator(); 863 while (it.hasNext()) { 864 KeyResolverSpi keyResolver = it.next(); 865 keyResolver.setSecureValidation(secureValidation); 866 Node currentChild = this.constructionElement.getFirstChild(); 867 String uri = this.getBaseURI(); 868 while (currentChild != null) { 869 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 870 for (StorageResolver storage : storageResolvers) { 871 PublicKey pk = 872 keyResolver.engineLookupAndResolvePublicKey( 873 (Element) currentChild, uri, storage 874 ); 875 876 if (pk != null) { 877 return pk; 878 } 879 } 880 } 881 currentChild = currentChild.getNextSibling(); 882 } 883 } 884 return null; 885 } 886 887 /** 888 * Searches the per-KeyInfo KeyResolvers for public keys 889 * 890 * @return The public key contained in this Node. 891 * @throws KeyResolverException 892 */ 893 PublicKey getPublicKeyFromInternalResolvers() throws KeyResolverException { 894 for (KeyResolverSpi keyResolver : internalKeyResolvers) { 895 if (log.isLoggable(java.util.logging.Level.FINE)) { 896 log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); 897 } 898 keyResolver.setSecureValidation(secureValidation); 899 Node currentChild = this.constructionElement.getFirstChild(); 900 String uri = this.getBaseURI(); 901 while (currentChild != null) { 902 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 903 for (StorageResolver storage : storageResolvers) { 904 PublicKey pk = 905 keyResolver.engineLookupAndResolvePublicKey( 906 (Element) currentChild, uri, storage 907 ); 908 909 if (pk != null) { 910 return pk; 911 } 912 } 913 } 914 currentChild = currentChild.getNextSibling(); 915 } 916 } 917 918 return null; 919 } 920 921 /** 922 * Method getX509Certificate 923 * 924 * @return The certificate contained in this KeyInfo 925 * @throws KeyResolverException 926 */ 927 public X509Certificate getX509Certificate() throws KeyResolverException { 928 // First search using the individual resolvers from the user 929 X509Certificate cert = this.getX509CertificateFromInternalResolvers(); 930 931 if (cert != null) { 932 if (log.isLoggable(java.util.logging.Level.FINE)) { 933 log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the per-KeyInfo key resolvers"); 934 } 935 936 return cert; 937 } 938 if (log.isLoggable(java.util.logging.Level.FINE)) { 939 log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the per-KeyInfo key resolvers"); 940 } 941 942 // Then use the system-wide Resolvers 943 cert = this.getX509CertificateFromStaticResolvers(); 944 945 if (cert != null) { 946 if (log.isLoggable(java.util.logging.Level.FINE)) { 947 log.log(java.util.logging.Level.FINE, "I could find a X509Certificate using the system-wide key resolvers"); 948 } 949 950 return cert; 951 } 952 if (log.isLoggable(java.util.logging.Level.FINE)) { 953 log.log(java.util.logging.Level.FINE, "I couldn't find a X509Certificate using the system-wide key resolvers"); 954 } 955 956 return null; 957 } 958 959 /** 960 * This method uses each System-wide {@link KeyResolver} to search the 961 * child elements. Each combination of {@link KeyResolver} and child element 962 * is checked against all {@link StorageResolver}s. 963 * 964 * @return The certificate contained in this KeyInfo 965 * @throws KeyResolverException 966 */ 967 X509Certificate getX509CertificateFromStaticResolvers() 968 throws KeyResolverException { 969 if (log.isLoggable(java.util.logging.Level.FINE)) { 970 log.log(java.util.logging.Level.FINE, 971 "Start getX509CertificateFromStaticResolvers() with " + KeyResolver.length() 972 + " resolvers" 973 ); 974 } 975 String uri = this.getBaseURI(); 976 Iterator<KeyResolverSpi> it = KeyResolver.iterator(); 977 while (it.hasNext()) { 978 KeyResolverSpi keyResolver = it.next(); 979 keyResolver.setSecureValidation(secureValidation); 980 X509Certificate cert = applyCurrentResolver(uri, keyResolver); 981 if (cert != null) { 982 return cert; 983 } 984 } 985 return null; 986 } 987 988 private X509Certificate applyCurrentResolver( 989 String uri, KeyResolverSpi keyResolver 990 ) throws KeyResolverException { 991 Node currentChild = this.constructionElement.getFirstChild(); 992 while (currentChild != null) { 993 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 994 for (StorageResolver storage : storageResolvers) { 995 X509Certificate cert = 996 keyResolver.engineLookupResolveX509Certificate( 997 (Element) currentChild, uri, storage 998 ); 999 1000 if (cert != null) { 1001 return cert; 1002 } 1003 } 1004 } 1005 currentChild = currentChild.getNextSibling(); 1006 } 1007 return null; 1008 } 1009 1010 /** 1011 * Method getX509CertificateFromInternalResolvers 1012 * 1013 * @return The certificate contained in this KeyInfo 1014 * @throws KeyResolverException 1015 */ 1016 X509Certificate getX509CertificateFromInternalResolvers() 1017 throws KeyResolverException { 1018 if (log.isLoggable(java.util.logging.Level.FINE)) { 1019 log.log(java.util.logging.Level.FINE, 1020 "Start getX509CertificateFromInternalResolvers() with " 1021 + this.lengthInternalKeyResolver() + " resolvers" 1022 ); 1023 } 1024 String uri = this.getBaseURI(); 1025 for (KeyResolverSpi keyResolver : internalKeyResolvers) { 1026 if (log.isLoggable(java.util.logging.Level.FINE)) { 1027 log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); 1028 } 1029 keyResolver.setSecureValidation(secureValidation); 1030 X509Certificate cert = applyCurrentResolver(uri, keyResolver); 1031 if (cert != null) { 1032 return cert; 1033 } 1034 } 1035 1036 return null; 1037 } 1038 1039 /** 1040 * This method returns a secret (symmetric) key. This is for XML Encryption. 1041 * @return the secret key contained in this KeyInfo 1042 * @throws KeyResolverException 1043 */ 1044 public SecretKey getSecretKey() throws KeyResolverException { 1045 SecretKey sk = this.getSecretKeyFromInternalResolvers(); 1046 1047 if (sk != null) { 1048 if (log.isLoggable(java.util.logging.Level.FINE)) { 1049 log.log(java.util.logging.Level.FINE, "I could find a secret key using the per-KeyInfo key resolvers"); 1050 } 1051 1052 return sk; 1053 } 1054 if (log.isLoggable(java.util.logging.Level.FINE)) { 1055 log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the per-KeyInfo key resolvers"); 1056 } 1057 1058 sk = this.getSecretKeyFromStaticResolvers(); 1059 1060 if (sk != null) { 1061 if (log.isLoggable(java.util.logging.Level.FINE)) { 1062 log.log(java.util.logging.Level.FINE, "I could find a secret key using the system-wide key resolvers"); 1063 } 1064 1065 return sk; 1066 } 1067 if (log.isLoggable(java.util.logging.Level.FINE)) { 1068 log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the system-wide key resolvers"); 1069 } 1070 1071 return null; 1072 } 1073 1074 /** 1075 * Searches the library wide KeyResolvers for Secret keys 1076 * 1077 * @return the secret key contained in this KeyInfo 1078 * @throws KeyResolverException 1079 */ 1080 SecretKey getSecretKeyFromStaticResolvers() throws KeyResolverException { 1081 Iterator<KeyResolverSpi> it = KeyResolver.iterator(); 1082 while (it.hasNext()) { 1083 KeyResolverSpi keyResolver = it.next(); 1084 keyResolver.setSecureValidation(secureValidation); 1085 1086 Node currentChild = this.constructionElement.getFirstChild(); 1087 String uri = this.getBaseURI(); 1088 while (currentChild != null) { 1089 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 1090 for (StorageResolver storage : storageResolvers) { 1091 SecretKey sk = 1092 keyResolver.engineLookupAndResolveSecretKey( 1093 (Element) currentChild, uri, storage 1094 ); 1095 1096 if (sk != null) { 1097 return sk; 1098 } 1099 } 1100 } 1101 currentChild = currentChild.getNextSibling(); 1102 } 1103 } 1104 return null; 1105 } 1106 1107 /** 1108 * Searches the per-KeyInfo KeyResolvers for secret keys 1109 * 1110 * @return the secret key contained in this KeyInfo 1111 * @throws KeyResolverException 1112 */ 1113 1114 SecretKey getSecretKeyFromInternalResolvers() throws KeyResolverException { 1115 for (KeyResolverSpi keyResolver : internalKeyResolvers) { 1116 if (log.isLoggable(java.util.logging.Level.FINE)) { 1117 log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); 1118 } 1119 keyResolver.setSecureValidation(secureValidation); 1120 Node currentChild = this.constructionElement.getFirstChild(); 1121 String uri = this.getBaseURI(); 1122 while (currentChild != null) { 1123 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 1124 for (StorageResolver storage : storageResolvers) { 1125 SecretKey sk = 1126 keyResolver.engineLookupAndResolveSecretKey( 1127 (Element) currentChild, uri, storage 1128 ); 1129 1130 if (sk != null) { 1131 return sk; 1132 } 1133 } 1134 } 1135 currentChild = currentChild.getNextSibling(); 1136 } 1137 } 1138 1139 return null; 1140 } 1141 1142 /** 1143 * This method returns a private key. This is for Key Transport in XML Encryption. 1144 * @return the private key contained in this KeyInfo 1145 * @throws KeyResolverException 1146 */ 1147 public PrivateKey getPrivateKey() throws KeyResolverException { 1148 PrivateKey pk = this.getPrivateKeyFromInternalResolvers(); 1149 1150 if (pk != null) { 1151 if (log.isLoggable(java.util.logging.Level.FINE)) { 1152 log.log(java.util.logging.Level.FINE, "I could find a private key using the per-KeyInfo key resolvers"); 1153 } 1154 return pk; 1155 } 1156 if (log.isLoggable(java.util.logging.Level.FINE)) { 1157 log.log(java.util.logging.Level.FINE, "I couldn't find a secret key using the per-KeyInfo key resolvers"); 1158 } 1159 1160 pk = this.getPrivateKeyFromStaticResolvers(); 1161 if (pk != null) { 1162 if (log.isLoggable(java.util.logging.Level.FINE)) { 1163 log.log(java.util.logging.Level.FINE, "I could find a private key using the system-wide key resolvers"); 1164 } 1165 return pk; 1166 } 1167 if (log.isLoggable(java.util.logging.Level.FINE)) { 1168 log.log(java.util.logging.Level.FINE, "I couldn't find a private key using the system-wide key resolvers"); 1169 } 1170 1171 return null; 1172 } 1173 1174 /** 1175 * Searches the library wide KeyResolvers for Private keys 1176 * 1177 * @return the private key contained in this KeyInfo 1178 * @throws KeyResolverException 1179 */ 1180 PrivateKey getPrivateKeyFromStaticResolvers() throws KeyResolverException { 1181 Iterator<KeyResolverSpi> it = KeyResolver.iterator(); 1182 while (it.hasNext()) { 1183 KeyResolverSpi keyResolver = it.next(); 1184 keyResolver.setSecureValidation(secureValidation); 1185 1186 Node currentChild = this.constructionElement.getFirstChild(); 1187 String uri = this.getBaseURI(); 1188 while (currentChild != null) { 1189 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 1190 // not using StorageResolvers at the moment 1191 // since they cannot return private keys 1192 PrivateKey pk = 1193 keyResolver.engineLookupAndResolvePrivateKey( 1194 (Element) currentChild, uri, null 1195 ); 1196 1197 if (pk != null) { 1198 return pk; 1199 } 1200 } 1201 currentChild = currentChild.getNextSibling(); 1202 } 1203 } 1204 return null; 1205 } 1206 1207 /** 1208 * Searches the per-KeyInfo KeyResolvers for private keys 1209 * 1210 * @return the private key contained in this KeyInfo 1211 * @throws KeyResolverException 1212 */ 1213 PrivateKey getPrivateKeyFromInternalResolvers() throws KeyResolverException { 1214 for (KeyResolverSpi keyResolver : internalKeyResolvers) { 1215 if (log.isLoggable(java.util.logging.Level.FINE)) { 1216 log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName()); 1217 } 1218 keyResolver.setSecureValidation(secureValidation); 1219 Node currentChild = this.constructionElement.getFirstChild(); 1220 String uri = this.getBaseURI(); 1221 while (currentChild != null) { 1222 if (currentChild.getNodeType() == Node.ELEMENT_NODE) { 1223 // not using StorageResolvers at the moment 1224 // since they cannot return private keys 1225 PrivateKey pk = 1226 keyResolver.engineLookupAndResolvePrivateKey( 1227 (Element) currentChild, uri, null 1228 ); 1229 1230 if (pk != null) { 1231 return pk; 1232 } 1233 } 1234 currentChild = currentChild.getNextSibling(); 1235 } 1236 } 1237 1238 return null; 1239 } 1240 1241 /** 1242 * This method is used to add a custom {@link KeyResolverSpi} to a KeyInfo 1243 * object. 1244 * 1245 * @param realKeyResolver 1246 */ 1247 public void registerInternalKeyResolver(KeyResolverSpi realKeyResolver) { 1248 this.internalKeyResolvers.add(realKeyResolver); 1249 } 1250 1251 /** 1252 * Method lengthInternalKeyResolver 1253 * @return the length of the key 1254 */ 1255 int lengthInternalKeyResolver() { 1256 return this.internalKeyResolvers.size(); 1257 } 1258 1259 /** 1260 * Method itemInternalKeyResolver 1261 * 1262 * @param i the index 1263 * @return the KeyResolverSpi for the index. 1264 */ 1265 KeyResolverSpi itemInternalKeyResolver(int i) { 1266 return this.internalKeyResolvers.get(i); 1267 } 1268 1269 /** 1270 * Method addStorageResolver 1271 * 1272 * @param storageResolver 1273 */ 1274 public void addStorageResolver(StorageResolver storageResolver) { 1275 if (storageResolvers == nullList) { 1276 // Replace the default null StorageResolver 1277 storageResolvers = new ArrayList<StorageResolver>(); 1278 } 1279 this.storageResolvers.add(storageResolver); 1280 } 1281 1282 1283 /** @inheritDoc */ 1284 public String getBaseLocalName() { 1285 return Constants._TAG_KEYINFO; 1286 } 1287} 1288