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