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