KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xml > internal > security > keys > KeyInfo


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */

17 package com.sun.org.apache.xml.internal.security.keys;
18
19
20
21 import java.security.PublicKey JavaDoc;
22 import java.security.cert.X509Certificate JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.List JavaDoc;
25
26 import javax.crypto.SecretKey;
27
28 import com.sun.org.apache.xml.internal.security.encryption.EncryptedKey;
29 import com.sun.org.apache.xml.internal.security.encryption.XMLCipher;
30 import com.sun.org.apache.xml.internal.security.encryption.XMLEncryptionException;
31 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
32 import com.sun.org.apache.xml.internal.security.keys.content.KeyName;
33 import com.sun.org.apache.xml.internal.security.keys.content.KeyValue;
34 import com.sun.org.apache.xml.internal.security.keys.content.MgmtData;
35 import com.sun.org.apache.xml.internal.security.keys.content.PGPData;
36 import com.sun.org.apache.xml.internal.security.keys.content.RetrievalMethod;
37 import com.sun.org.apache.xml.internal.security.keys.content.SPKIData;
38 import com.sun.org.apache.xml.internal.security.keys.content.X509Data;
39 import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.DSAKeyValue;
40 import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue;
41 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolver;
42 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
43 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
44 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
45 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
46 import com.sun.org.apache.xml.internal.security.utils.EncryptionConstants;
47 import com.sun.org.apache.xml.internal.security.utils.Constants;
48 import com.sun.org.apache.xml.internal.security.utils.IdResolver;
49 import com.sun.org.apache.xml.internal.security.utils.SignatureElementProxy;
50 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
51 import org.w3c.dom.Document JavaDoc;
52 import org.w3c.dom.Element JavaDoc;
53 import org.w3c.dom.Node JavaDoc;
54 import org.w3c.dom.NodeList JavaDoc;
55
56
57 /**
58  * This class stand for KeyInfo Element that may contain keys, names,
59  * certificates and other public key management information,
60  * such as in-band key distribution or key agreement data.
61  * <BR />
62  * KeyInfo Element has two basic functions:
63  * One is KeyResolve for getting the public key in signature validation processing.
64  * the other one is toElement for getting the element in signature generation processing.
65  * <BR />
66  * The <CODE>lengthXXX()</CODE> methods provide access to the internal Key
67  * objects:
68  * <UL>
69  * <LI>If the <CODE>KeyInfo</CODE> was constructed from an Element
70  * (Signature verification), the <CODE>lengthXXX()</CODE> methods searches
71  * for child elements of <CODE>ds:KeyInfo</CODE> for known types. </LI>
72  * <LI>If the <CODE>KeyInfo</CODE> was constructed from scratch (during
73  * Signature generation), the <CODE>lengthXXX()</CODE> methods return the number
74  * of <CODE>XXXs</CODE> objects already passed to the KeyInfo</LI>
75  * </UL>
76  * <BR />
77  * The <CODE>addXXX()</CODE> methods are used for adding Objects of the
78  * appropriate type to the <CODE>KeyInfo</CODE>. This is used during signature
79  * generation.
80  * <BR />
81  * The <CODE>itemXXX(int i)</CODE> methods return the i'th object of the
82  * corresponding type.
83  * <BR />
84  * The <CODE>containsXXX()</CODE> methods return <I>whether</I> the KeyInfo
85  * contains the corresponding type.
86  *
87  * @author $Author: raul $
88  */

89 public class KeyInfo extends SignatureElementProxy {
90
91    /** {@link java.util.logging} logging facility */
92     static java.util.logging.Logger JavaDoc log =
93         java.util.logging.Logger.getLogger(KeyInfo.class.getName());
94
95
96
97    /**
98     * Constructor KeyInfo
99     * @param doc
100     */

101    public KeyInfo(Document JavaDoc doc) {
102
103       super(doc);
104
105       XMLUtils.addReturnToElement(this._constructionElement);
106
107
108    }
109
110    /**
111     * Constructor KeyInfo
112     *
113     * @param element
114     * @param BaseURI
115     * @throws XMLSecurityException
116     */

117    public KeyInfo(Element JavaDoc element, String JavaDoc BaseURI) throws XMLSecurityException {
118
119       super(element, BaseURI);
120
121    }
122
123    /**
124     * Sets the <code>Id</code> attribute
125     *
126     * @param Id ID
127     */

128    public void setId(String JavaDoc Id) {
129
130       if ((this._state == MODE_SIGN) && (Id != null)) {
131          this._constructionElement.setAttributeNS(null, Constants._ATT_ID, Id);
132          IdResolver.registerElementById(this._constructionElement, Id);
133       }
134    }
135
136    /**
137     * Returns the <code>Id</code> attribute
138     *
139     * @return the <code>Id</code> attribute
140     */

141    public String JavaDoc getId() {
142       return this._constructionElement.getAttributeNS(null, Constants._ATT_ID);
143    }
144
145    /**
146     * Method addKeyName
147     *
148     * @param keynameString
149     */

150    public void addKeyName(String JavaDoc keynameString) {
151       this.add(new KeyName(this._doc, keynameString));
152    }
153
154    /**
155     * Method add
156     *
157     * @param keyname
158     */

159    public void add(KeyName keyname) {
160
161       if (this._state == MODE_SIGN) {
162          this._constructionElement.appendChild(keyname.getElement());
163          XMLUtils.addReturnToElement(this._constructionElement);
164       }
165    }
166
167    /**
168     * Method addKeyValue
169     *
170     * @param pk
171     */

172    public void addKeyValue(PublicKey JavaDoc pk) {
173       this.add(new KeyValue(this._doc, pk));
174    }
175
176    /**
177     * Method addKeyValue
178     *
179     * @param unknownKeyValueElement
180     */

181    public void addKeyValue(Element JavaDoc unknownKeyValueElement) {
182       this.add(new KeyValue(this._doc, unknownKeyValueElement));
183    }
184
185    /**
186     * Method add
187     *
188     * @param dsakeyvalue
189     */

190    public void add(DSAKeyValue dsakeyvalue) {
191       this.add(new KeyValue(this._doc, dsakeyvalue));
192    }
193
194    /**
195     * Method add
196     *
197     * @param rsakeyvalue
198     */

199    public void add(RSAKeyValue rsakeyvalue) {
200       this.add(new KeyValue(this._doc, rsakeyvalue));
201    }
202
203    /**
204     * Method add
205     *
206     * @param pk
207     */

208    public void add(PublicKey JavaDoc pk) {
209       this.add(new KeyValue(this._doc, pk));
210    }
211
212    /**
213     * Method add
214     *
215     * @param keyvalue
216     */

217    public void add(KeyValue keyvalue) {
218
219       if (this._state == MODE_SIGN) {
220          this._constructionElement.appendChild(keyvalue.getElement());
221          XMLUtils.addReturnToElement(this._constructionElement);
222       }
223    }
224
225    /**
226     * Method addMgmtData
227     *
228     * @param mgmtdata
229     */

230    public void addMgmtData(String JavaDoc mgmtdata) {
231       this.add(new MgmtData(this._doc, mgmtdata));
232    }
233
234    /**
235     * Method add
236     *
237     * @param mgmtdata
238     */

239    public void add(MgmtData mgmtdata) {
240
241       if (this._state == MODE_SIGN) {
242          this._constructionElement.appendChild(mgmtdata.getElement());
243          XMLUtils.addReturnToElement(this._constructionElement);
244       }
245    }
246
247    /**
248     * Method addPGPData
249     *
250     * @param pgpdata
251     */

252    public void add(PGPData pgpdata) {
253
254       if (this._state == MODE_SIGN) {
255          this._constructionElement.appendChild(pgpdata.getElement());
256          XMLUtils.addReturnToElement(this._constructionElement);
257       }
258    }
259
260    /**
261     * Method addRetrievalMethod
262     *
263     * @param URI
264     * @param transforms
265     * @param Type
266     */

267    public void addRetrievalMethod(String JavaDoc URI, Transforms transforms,
268                                   String JavaDoc Type) {
269       this.add(new RetrievalMethod(this._doc, URI, transforms, Type));
270    }
271
272    /**
273     * Method add
274     *
275     * @param retrievalmethod
276     */

277    public void add(RetrievalMethod retrievalmethod) {
278
279       if (this._state == MODE_SIGN) {
280          this._constructionElement.appendChild(retrievalmethod.getElement());
281          XMLUtils.addReturnToElement(this._constructionElement);
282       }
283    }
284
285    /**
286     * Method add
287     *
288     * @param spkidata
289     */

290    public void add(SPKIData spkidata) {
291
292       if (this._state == MODE_SIGN) {
293          this._constructionElement.appendChild(spkidata.getElement());
294          XMLUtils.addReturnToElement(this._constructionElement);
295       }
296    }
297
298    /**
299     * Method addX509Data
300     *
301     * @param x509data
302     */

303    public void add(X509Data x509data) {
304
305       if (this._state == MODE_SIGN) {
306          this._constructionElement.appendChild(x509data.getElement());
307          XMLUtils.addReturnToElement(this._constructionElement);
308       }
309    }
310
311     /**
312      * Method addEncryptedKey
313      *
314      * @param encryptedKey
315      * @throws XMLEncryptionException
316      */

317
318     public void add(EncryptedKey encryptedKey)
319         throws XMLEncryptionException {
320
321         if (this._state == MODE_SIGN) {
322             XMLCipher cipher = XMLCipher.getInstance();
323             this._constructionElement.appendChild(cipher.martial(encryptedKey));
324         }
325
326     }
327
328    /**
329     * Method addUnknownElement
330     *
331     * @param element
332     */

333    public void addUnknownElement(Element JavaDoc element) {
334
335       if (this._state == MODE_SIGN) {
336          this._constructionElement.appendChild(element);
337          XMLUtils.addReturnToElement(this._constructionElement);
338       }
339    }
340
341    /**
342     * Method lengthKeyName
343     *
344     * @return the number of the KeyName tags
345     */

346    public int lengthKeyName() {
347       return this.length(Constants.SignatureSpecNS, Constants._TAG_KEYNAME);
348    }
349
350    /**
351     * Method lengthKeyValue
352     *
353     *@return the number of the KeyValue tags
354     */

355    public int lengthKeyValue() {
356       return this.length(Constants.SignatureSpecNS, Constants._TAG_KEYVALUE);
357    }
358
359    /**
360     * Method lengthMgmtData
361     *
362     *@return the number of the MgmtData tags
363     */

364    public int lengthMgmtData() {
365       return this.length(Constants.SignatureSpecNS, Constants._TAG_MGMTDATA);
366    }
367
368    /**
369     * Method lengthPGPData
370     *
371     *@return the number of the PGPDat. tags
372     */

373    public int lengthPGPData() {
374       return this.length(Constants.SignatureSpecNS, Constants._TAG_PGPDATA);
375    }
376
377    /**
378     * Method lengthRetrievalMethod
379     *
380     *@return the number of the RetrievalMethod tags
381     */

382    public int lengthRetrievalMethod() {
383       return this.length(Constants.SignatureSpecNS,
384                          Constants._TAG_RETRIEVALMETHOD);
385    }
386
387    /**
388     * Method lengthSPKIData
389     *
390     *@return the number of the SPKIData tags
391     */

392    public int lengthSPKIData() {
393       return this.length(Constants.SignatureSpecNS, Constants._TAG_SPKIDATA);
394    }
395
396    /**
397     * Method lengthX509Data
398     *
399     *@return the number of the X509Data tags
400     */

401    public int lengthX509Data() {
402       return this.length(Constants.SignatureSpecNS, Constants._TAG_X509DATA);
403    }
404
405    /**
406     * Method lengthUnknownElement
407     * NOTE posibly buggy.
408     *@return the number of the UnknownElement tags
409     */

410    public int lengthUnknownElement() {
411
412       int res = 0;
413       NodeList JavaDoc nl = this._constructionElement.getChildNodes();
414
415       for (int i = 0; i < nl.getLength(); i++) {
416          Node JavaDoc current = nl.item(i);
417
418          /**
419           * $todo$ using this method, we don't see unknown Elements
420           * from Signature NS; revisit
421           */

422          if ((current.getNodeType() == Node.ELEMENT_NODE)
423                  && current.getNamespaceURI()
424                     .equals(Constants.SignatureSpecNS)) {
425             res++;
426          }
427       }
428
429       return res;
430    }
431
432    /**
433     * Method itemKeyName
434     *
435     * @param i
436     * @return the asked KeyName element, null if the index is too big
437     * @throws XMLSecurityException
438     */

439    public KeyName itemKeyName(int i) throws XMLSecurityException {
440
441       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
442                                                 Constants._TAG_KEYNAME,i);
443
444       if (e != null) {
445          return new KeyName(e, this._baseURI);
446       }
447       return null;
448    }
449
450    /**
451     * Method itemKeyValue
452     *
453     * @param i
454     * @return the asked KeyValue element, null if the index is too big
455     * @throws XMLSecurityException
456     */

457    public KeyValue itemKeyValue(int i) throws XMLSecurityException {
458
459       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
460                                                 Constants._TAG_KEYVALUE,i);
461
462       if (e != null) {
463          return new KeyValue(e, this._baseURI);
464       }
465       return null;
466    }
467
468    /**
469     * Method itemMgmtData
470     *
471     * @param i
472     *@return the asked MgmtData element, null if the index is too big
473     * @throws XMLSecurityException
474     */

475    public MgmtData itemMgmtData(int i) throws XMLSecurityException {
476
477       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
478                                                 Constants._TAG_MGMTDATA,i);
479
480       if (e != null) {
481          return new MgmtData(e, this._baseURI);
482       }
483        return null;
484    }
485
486    /**
487     * Method itemPGPData
488     *
489     * @param i
490     *@return the asked PGPData element, null if the index is too big
491     * @throws XMLSecurityException
492     */

493    public PGPData itemPGPData(int i) throws XMLSecurityException {
494
495       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
496                                                 Constants._TAG_PGPDATA,i);
497
498       if (e != null) {
499          return new PGPData(e, this._baseURI);
500       }
501       return null;
502    }
503
504    /**
505     * Method itemRetrievalMethod
506     *
507     * @param i
508     *@return the asked RetrievalMethod element, null if the index is too big
509     * @throws XMLSecurityException
510     */

511    public RetrievalMethod itemRetrievalMethod(int i)
512            throws XMLSecurityException {
513
514       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
515                                                 Constants._TAG_RETRIEVALMETHOD,i);
516
517       if (e != null) {
518          return new RetrievalMethod(e, this._baseURI);
519       }
520       return null;
521    }
522
523    /**
524     * Method itemSPKIData
525     *
526     * @param i
527     *@return the asked SPKIData element, null if the index is too big
528     * @throws XMLSecurityException
529     */

530    public SPKIData itemSPKIData(int i) throws XMLSecurityException {
531
532       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
533                                                 Constants._TAG_SPKIDATA,i);
534
535       if (e != null) {
536          return new SPKIData(e, this._baseURI);
537       }
538       return null;
539    }
540
541    /**
542     * Method itemX509Data
543     *@return the asked X509Data element, null if the index is too big
544     * @param i
545     *
546     * @throws XMLSecurityException
547     */

548    public X509Data itemX509Data(int i) throws XMLSecurityException {
549
550       Element JavaDoc e = XMLUtils.selectDsNode(this._constructionElement.getFirstChild(),
551                                                 Constants._TAG_X509DATA,i);
552
553       if (e != null) {
554          return new X509Data(e, this._baseURI);
555       }
556       return null;
557    }
558
559    /**
560     * Method itemEncryptedKey
561     *
562     * @param i
563     * @return the asked EncryptedKey element, null if the index is too big
564     * @throws XMLSecurityException
565     */

566
567     public EncryptedKey itemEncryptedKey(int i) throws XMLSecurityException {
568
569         Element JavaDoc e =
570             XMLUtils.selectXencNode(this._constructionElement.getFirstChild(),
571                                           EncryptionConstants._TAG_ENCRYPTEDKEY,i);
572
573         if (e != null) {
574             XMLCipher cipher = XMLCipher.getInstance();
575             cipher.init(XMLCipher.UNWRAP_MODE, null);
576             return cipher.loadEncryptedKey(e);
577         }
578         return null;
579    }
580
581    /**
582     * Method itemUnknownElement
583     *
584     * @param i index
585     * @return the element number of the unknown elemens
586     */

587    public Element JavaDoc itemUnknownElement(int i) {
588
589       NodeList JavaDoc nl = this._constructionElement.getChildNodes();
590       int res = 0;
591
592       for (int j = 0; j < nl.getLength(); j++) {
593          Node JavaDoc current = nl.item(j);
594
595          /**
596           * $todo$ using this method, we don't see unknown Elements
597           * from Signature NS; revisit
598           */

599          if ((current.getNodeType() == Node.ELEMENT_NODE)
600                  && current.getNamespaceURI()
601                     .equals(Constants.SignatureSpecNS)) {
602             res++;
603
604             if (res == i) {
605                return (Element JavaDoc) current;
606             }
607          }
608       }
609
610       return null;
611    }
612
613    /**
614     * Method isEmpty
615     *
616     * @return true if the element has no descedants.
617     */

618    public boolean isEmpty() {
619       return this._constructionElement.getFirstChild()==null;
620    }
621
622    /**
623     * Method containsKeyName
624     *
625     * @return If the KeyInfo contains a KeyName node
626     */

627    public boolean containsKeyName() {
628       return this.lengthKeyName() > 0;
629    }
630
631    /**
632     * Method containsKeyValue
633     *
634     * @return If the KeyInfo contains a KeyValue node
635     */

636    public boolean containsKeyValue() {
637       return this.lengthKeyValue() > 0;
638    }
639
640    /**
641     * Method containsMgmtData
642     *
643     * @return If the KeyInfo contains a MgmtData node
644     */

645    public boolean containsMgmtData() {
646       return this.lengthMgmtData() > 0;
647    }
648
649    /**
650     * Method containsPGPData
651     *
652     * @return If the KeyInfo contains a PGPData node
653     */

654    public boolean containsPGPData() {
655       return this.lengthPGPData() > 0;
656    }
657
658    /**
659     * Method containsRetrievalMethod
660     *
661     * @return If the KeyInfo contains a RetrievalMethod node
662     */

663    public boolean containsRetrievalMethod() {
664       return this.lengthRetrievalMethod() > 0;
665    }
666
667    /**
668     * Method containsSPKIData
669     *
670     * @return If the KeyInfo contains a SPKIData node
671     */

672    public boolean containsSPKIData() {
673       return this.lengthSPKIData() > 0;
674    }
675
676    /**
677     * Method containsUnknownElement
678     *
679     * @return If the KeyInfo contains a UnknownElement node
680     */

681    public boolean containsUnknownElement() {
682       return this.lengthUnknownElement() > 0;
683    }
684
685    /**
686     * Method containsX509Data
687     *
688     * @return If the KeyInfo contains a X509Data node
689     */

690    public boolean containsX509Data() {
691       return this.lengthX509Data() > 0;
692    }
693
694    /**
695     * This method returns the public key.
696     *
697     * @return If the KeyInfo contains a PublicKey node
698     * @throws KeyResolverException
699     */

700
701    public PublicKey JavaDoc getPublicKey() throws KeyResolverException {
702
703       PublicKey JavaDoc pk = this.getPublicKeyFromInternalResolvers();
704
705       if (pk != null) {
706          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");
707
708          return pk;
709       }
710       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");
711
712       pk = this.getPublicKeyFromStaticResolvers();
713
714       if (pk != null) {
715          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");
716
717          return pk;
718       }
719       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");
720
721       return null;
722    }
723
724    /**
725     * Searches the library wide keyresolvers for public keys
726     *
727     * @return The publick contained in this Node.
728     * @throws KeyResolverException
729     */

730    PublicKey JavaDoc getPublicKeyFromStaticResolvers() throws KeyResolverException {
731
732       for (int i = 0; i < KeyResolver.length(); i++) {
733          KeyResolver keyResolver = KeyResolver.item(i);
734          Node JavaDoc currentChild=this._constructionElement.getFirstChild();
735          while (currentChild!=null) {
736             if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
737                if (this._storageResolvers.size() == 0) {
738
739                   // if we do not have storage resolvers, we verify with null
740
StorageResolver storage = null;
741
742                   if (keyResolver.canResolve((Element JavaDoc) currentChild,
743                                              this.getBaseURI(), storage)) {
744                      PublicKey JavaDoc pk =
745                         keyResolver.resolvePublicKey((Element JavaDoc) currentChild,
746                                                      this.getBaseURI(),
747                                                      storage);
748
749                      if (pk != null) {
750                         return pk;
751                      }
752                   }
753                } else {
754                   for (int k = 0; k < this._storageResolvers.size(); k++) {
755                      StorageResolver storage =
756                         (StorageResolver) this._storageResolvers.get(k);
757
758                      if (keyResolver.canResolve((Element JavaDoc) currentChild,
759                                                 this.getBaseURI(), storage)) {
760                         PublicKey JavaDoc pk =
761                            keyResolver.resolvePublicKey((Element JavaDoc) currentChild,
762                                                         this.getBaseURI(),
763                                                         storage);
764
765                         if (pk != null) {
766                            return pk;
767                         }
768                      }
769                   }
770                }
771             }
772             currentChild=currentChild.getNextSibling();
773          }
774       }
775       return null;
776    }
777
778    /**
779     * Searches the per-KeyInfo keyresolvers for public keys
780     *
781     * @return The publick contained in this Node.
782     * @throws KeyResolverException
783     */

784    PublicKey JavaDoc getPublicKeyFromInternalResolvers() throws KeyResolverException {
785
786       for (int i = 0; i < this.lengthInternalKeyResolver(); i++) {
787          KeyResolverSpi keyResolver = this.itemInternalKeyResolver(i);
788          if (true)
789             if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Try " + keyResolver.getClass().getName());
790
791          Node JavaDoc currentChild=this._constructionElement.getFirstChild();
792          while (currentChild!=null) {
793             if (currentChild.getNodeType() == Node.ELEMENT_NODE) {
794                if (this._storageResolvers.size() == 0) {
795
796                   // if we do not have storage resolvers, we verify with null
797
StorageResolver storage = null;
798
799                   if (keyResolver.engineCanResolve((Element JavaDoc) currentChild,
800                                                    this.getBaseURI(),
801                                                    storage)) {
802                      PublicKey JavaDoc pk =
803                         keyResolver
804                            .engineResolvePublicKey((Element JavaDoc) currentChild, this
805                               .getBaseURI(), storage);
806
807                      if (pk != null) {
808                         return pk;
809                      }
810                   }
811                } else {
812                   for (int k = 0; k < this._storageResolvers.size(); k++) {
813                      StorageResolver storage =
814                         (StorageResolver) this._storageResolvers.get(k);
815
816                      if (keyResolver.engineCanResolve((Element JavaDoc) currentChild,
817                                                       this.getBaseURI(),
818                                                       storage)) {
819                         PublicKey JavaDoc pk = keyResolver
820                            .engineResolvePublicKey((Element JavaDoc) currentChild, this
821                               .getBaseURI(), storage);
822
823                         if (pk != null) {
824                            return pk;
825                         }
826                      }
827                   }
828                }
829             }
830             currentChild=currentChild.getNextSibling();
831          }
832       }
833
834       return null;
835    }
836
837    /**
838     * Method getX509Certificate
839     *
840     * @return The certificate contined in this KeyInfo
841     * @throws KeyResolverException
842     */

843    public X509Certificate JavaDoc getX509Certificate() throws KeyResolverException {
844
845       // First search using the individual resolvers from the user
846
X509Certificate JavaDoc cert = this.getX509CertificateFromInternalResolvers();
847
848       if (cert != null) {
849          if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
850             "I could find a X509Certificate using the per-KeyInfo key resolvers");
851
852          return cert;
853       }
854       if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
855             "I couldn't find a X509Certificate using the per-KeyInfo key resolvers");
856       
857
858       // Then use the system-wide Resolvers
859
cert = this.getX509CertificateFromStaticResolvers();
860
861       if (cert != null) {
862          if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
863             "I could find a X509Certificate using the system-wide key resolvers");
864
865          return cert;
866       }
867       if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE,
868             "I couldn't find a X509Certificate using the system-wide key resolvers");
869       
870
871       return null;
872    }
873
874    /**
875     * This method uses each System-wide {@link KeyResolver} to search the
876     * child elements. Each combination of {@link KeyResolver} and child element
877     * is checked against all {@link StorageResolver}s.
878     *
879     * @return The certificate contined in this KeyInfo
880     * @throws KeyResolverException
881     */

882    X509Certificate JavaDoc getX509CertificateFromStaticResolvers()
883            throws KeyResolverException {
884       if (true)
885         if (log.isLoggable(java.util.logging.Level.FINE)) log.log(java.util.logging.Level.FINE, "Start getX509CertificateFromStaticResolvers() with "
886                 + KeyResolver.length() + " resolvers");
887
888       for (int i = 0; i < KeyResolver.length(); i++) {
889          KeyResolver keyResolver = KeyResolver.item(i);
890          Node JavaDoc currentChild=this._constructionElement.getFirstChild();
891 </