xref: /trunk/main/xmlsecurity/tools/uno/XMLSecurityFrameworkController.java (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.xml.security.uno;
29 
30 import java.util.Stack;
31 import java.util.Vector;
32 
33 /* uno classes */
34 import com.sun.star.uno.UnoRuntime;
35 import com.sun.star.lang.XMultiComponentFactory;
36 import com.sun.star.lang.XInitialization;
37 import com.sun.star.uno.XComponentContext;
38 import com.sun.star.xml.sax.XDocumentHandler;
39 import com.sun.star.xml.sax.XAttributeList;
40 import com.sun.star.xml.sax.SAXException;
41 
42 import com.sun.star.xml.crypto.*;
43 import com.sun.star.xml.crypto.sax.*;
44 import com.sun.star.xml.wrapper.*;
45 
46 /*
47  * the XMLSecurityFrameworkController class is used to controll the xml security framework.
48  */
49 public class XMLSecurityFrameworkController
50     implements XDocumentHandler, XSignatureCreationResultListener, XSignatureVerifyResultListener,
51            XEncryptionResultListener, XDecryptionResultListener, XSAXEventKeeperStatusChangeListener
52 {
53     /*
54      * UNO framework component
55      */
56     private XMultiComponentFactory  m_xRemoteServiceManager;
57     private XComponentContext       m_xRemoteContext;
58 
59     /*
60      * xml security related UNO components
61      */
62     private XSecuritySAXEventKeeper m_xSAXEventKeeper;
63     private XXMLDocumentWrapper     m_xXMLDocumentWrapper;
64     private XDocumentHandler        m_xOutputHandler;
65     private XXMLSecurityContext     m_xXMLSecurityContext;
66     private XXMLSignature           m_xXMLSignature;
67     private XXMLEncryption          m_xXMLEncryption;
68 
69         /*
70          * used to reserve the current SAX ancestor path
71          */
72     private Stack  m_currentPath;
73 
74     /*
75      * maintains all SignatureEntities.
76      */
77     private Vector m_signatureList;
78 
79     /*
80      * maintains all EncryptionEntities.
81      */
82     private Vector m_encryptionList;
83 
84     /*
85      * maintains all unsolved reference Ids.
86      * These ids are strings which is the value of the id attribute
87      * of the referenced element.
88      */
89     private Vector m_vUnsolvedReferenceIds;
90 
91     /*
92      * maintains all unsolved reference keeper ids.
93      * The keeper id is used to uniquely identify a bufferred element
94      * by the SAXEventKeeper.
95      */
96     private Vector m_vUnsolvedReferencedKeeperIds;
97 
98     /*
99      * maintains the left time that each unsolved reference can be
100      * claimed.
101      */
102     private Vector m_vUnsolvedReferenceRefNum;
103 
104     /*
105      * whether exporting or importing
106      */
107     private boolean m_bIsExporting;
108 
109     /*
110      * whether java or c
111      */
112     private boolean m_bIsJavaBased;
113 
114     /*
115      * whether the SAXEventKeeper is blocking
116      */
117     private boolean m_bIsBlocking;
118 
119     /*
120      * whether it is collecting a bufferred element
121      */
122     private boolean m_bIsInsideCollectedElement;
123 
124     /*
125      * whether a SAXEventKeeper is in the SAX chain
126      */
127     private boolean m_bSAXEventKeeperIncluded;
128 
129     /*
130      * the ParsingThread used to parse the document
131      */
132     private ParsingThread m_parsingThread;
133 
134     /*
135      * the next document handler that will receives SAX events
136      * from the parsing thread.
137      * if the SAXEventKeeper is on the SAX chain, then this
138      * variable will be the SAXEventKeeper, otherwise, this
139      * variable will be the xOutputHandler.
140      */
141     private XDocumentHandler m_xExportHandler;
142 
143     /*
144      * the TestTool used to feedback information
145      */
146     private TestTool m_testTool;
147 
148     /*
149      * for encryption target
150      */
151     private boolean m_bIsEncryptionTarget;
152     private EncryptionEntity m_EncryptionForTarget;
153 
154     XMLSecurityFrameworkController(
155         TestTool testTool,
156         boolean bIsExporting,
157         boolean bIsJavaBased,
158         XDocumentHandler xOutputHandler,
159         ParsingThread parsingThread,
160         XXMLSecurityContext xXMLSecurityContext,
161         XXMLSignature xXMLSignature,
162         XXMLEncryption xXMLEncryption,
163         XMultiComponentFactory xRemoteServiceManager,
164         XComponentContext xRemoteContext)
165     {
166         m_bIsExporting = bIsExporting;
167         m_bIsJavaBased = bIsJavaBased;
168 
169         m_xOutputHandler = xOutputHandler;
170         m_xXMLSecurityContext = xXMLSecurityContext;
171         m_xXMLSignature = xXMLSignature;
172         m_xXMLEncryption = xXMLEncryption;
173         m_xRemoteServiceManager = xRemoteServiceManager;
174         m_xRemoteContext = xRemoteContext;
175 
176         m_testTool = testTool;
177         m_parsingThread = parsingThread;
178 
179         m_signatureList = new Vector();
180         m_encryptionList = new Vector();
181 
182         m_vUnsolvedReferenceIds = new Vector();
183         m_vUnsolvedReferencedKeeperIds = new Vector();
184         m_vUnsolvedReferenceRefNum = new Vector();
185 
186         m_xXMLDocumentWrapper = null;
187         m_xSAXEventKeeper = null;
188 
189         m_bSAXEventKeeperIncluded = false;
190         m_bIsBlocking = false;
191         m_bIsInsideCollectedElement = false;
192 
193         m_bIsEncryptionTarget = false;
194         m_EncryptionForTarget = null;
195 
196         changeOutput();
197 
198         m_currentPath = new Stack();
199 
200         foundSecurityRelated();
201     }
202 
203 /**************************************************************************************
204  * private methods
205  **************************************************************************************/
206 
207         /*
208          * changes the output document handler.
209          */
210         private void changeOutput()
211         {
212         if (m_bIsExporting)
213         {
214             m_parsingThread.setHandler(this);
215 
216             /*
217              * If the SAXEventKeeper is in the SAX chain, then redirects output
218              * to the SAXEventKeeper, otherwise, to the m_xOutputHandler
219              */
220             if (m_bSAXEventKeeperIncluded)
221             {
222                 m_xExportHandler = (XDocumentHandler)UnoRuntime.queryInterface(
223                             XDocumentHandler.class, m_xSAXEventKeeper);
224                 m_xSAXEventKeeper.setNextHandler(m_xOutputHandler);
225 
226                 m_testTool.updatesSAXChainInformation("XMLExporter -> SAXEventKeeper -> SAXWriter");
227             }
228             else
229             {
230                 m_xExportHandler = m_xOutputHandler;
231                 m_testTool.updatesSAXChainInformation("XMLExporter -> SAXWriter");
232             }
233         }
234         else
235         {
236             if (m_bSAXEventKeeperIncluded)
237             {
238                 m_parsingThread.setHandler(
239                     (XDocumentHandler)UnoRuntime.queryInterface(XDocumentHandler.class, m_xSAXEventKeeper));
240                 m_xSAXEventKeeper.setNextHandler(this);
241                 m_testTool.updatesSAXChainInformation("SAXParser -> SAXEventKeeper -> XMLImporter");
242             }
243             else
244             {
245                 m_parsingThread.setHandler(this);
246                 m_testTool.updatesSAXChainInformation("SAXParser -> XMLImporter");
247             }
248             m_xExportHandler = m_xOutputHandler;
249         }
250     }
251 
252         /*
253          * handles the situation when a security related element is found.
254          * if the SAXEventKeeper is not initialized, then creates a
255          * SAXEventKeeper.
256          * the return value represents whether the SAXEventKeeper is newly
257          * created.
258          */
259     private boolean foundSecurityRelated()
260     {
261         if (m_xSAXEventKeeper == null)
262         {
263             m_testTool.showMessage("Message from : "+
264                         (m_bIsExporting?"XMLExporter":"XMLImporter")+
265                         "\n\nA security related content found, a SAXEventKeeper is created.\n ");
266 
267             m_bIsBlocking = false;
268             m_bIsInsideCollectedElement = false;
269 
270             try
271             {
272                 /*
273                  * creates an XMLDocumentWrapper component.
274                  */
275                 Object xmlDocumentObj = null;
276 
277                 if (m_bIsJavaBased)
278                 {
279                     xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext(
280                         TestTool.XMLDOCUMENTWRAPPER_COMPONENT_JAVA, m_xRemoteContext);
281                 }
282                 else
283                 {
284                     xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext(
285                         TestTool.XMLDOCUMENTWRAPPER_COMPONENT_C, m_xRemoteContext);
286                 }
287 
288                 m_xXMLDocumentWrapper = (XXMLDocumentWrapper)UnoRuntime.queryInterface(
289                     XXMLDocumentWrapper.class, xmlDocumentObj);
290 
291                 /*
292                  * creates a SAXEventKeeper component.
293                  */
294                 Object saxEventKeeperObj = m_xRemoteServiceManager.createInstanceWithContext(
295                     TestTool.SAXEVENTKEEPER_COMPONENT, m_xRemoteContext);
296 
297                 m_xSAXEventKeeper =
298                     (XSecuritySAXEventKeeper)UnoRuntime.queryInterface(
299                         XSecuritySAXEventKeeper.class, saxEventKeeperObj);
300 
301                             /*
302                              * initializes the SAXEventKeeper component with the XMLDocumentWrapper component.
303                              */
304                 XInitialization xInitialization =
305                     (XInitialization)UnoRuntime.queryInterface(
306                         XInitialization.class, m_xSAXEventKeeper);
307                 Object args[]=new Object[1];
308                 args[0] = m_xXMLDocumentWrapper;
309                 xInitialization.initialize(args);
310             }
311             catch( com.sun.star.uno.Exception e)
312             {
313                 e.printStackTrace();
314             }
315 
316             /*
317              * configures the SAXEventKeeper's status change listener.
318              */
319             XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster =
320                 (XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface(
321                     XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper);
322             xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(this);
323         }
324 
325         boolean rc = !m_bSAXEventKeeperIncluded;
326 
327         /*
328          * changes the export document handler.
329          */
330         m_bSAXEventKeeperIncluded=true;
331         changeOutput();
332 
333         return rc;
334     }
335 
336     /*
337      * finds key element or referenced element for a signature.
338      */
339     private void findKeyOrReference(SecurityEntity signatureEntity, String uriStr, boolean isFindingKey)
340     {
341         int i=0;
342 
343         while (i<m_vUnsolvedReferenceIds.size())
344         {
345             String id = (String)m_vUnsolvedReferenceIds.elementAt(i);
346 
347             if (id.equals(uriStr))
348             {
349                 int refNum = ((Integer)m_vUnsolvedReferenceRefNum.elementAt(i)).intValue();
350                 int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(i)).intValue();
351 
352                 if (isFindingKey)
353                 {
354                     /*
355                      * clones a new ElementCollector for the key element.
356                      */
357                     int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector(
358                         keeperId,
359                         m_bIsExporting?
360                         (ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY));
361 
362                     /*
363                      * notifies the key keeper id.
364                      */
365                     signatureEntity.setKeyId(cloneKeeperId);
366 
367                     /*
368                      * sets the security id for the key.
369                      */
370                     m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId());
371 
372                     /*
373                      * sets the resolve listener.
374                      */
375                     XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster =
376                         (XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
377                             XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
378                     xReferenceResolvedBroadcaster.addReferenceResolvedListener(
379                         cloneKeeperId,
380                         signatureEntity.getReferenceListener());
381                 }
382                 else
383                 {
384                     /*
385                      * clones a new ElementCollector for the referenced element.
386                      */
387                     int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector(
388                         keeperId,
389                         m_bIsExporting?
390                         (ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY));
391 
392                     /*
393                      * sets the security id.
394                      */
395                     m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId());
396 
397                     /*
398                      * sets the resolve listener.
399                      */
400                     XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster =
401                         (XReferenceResolvedBroadcaster)UnoRuntime.queryInterface(
402                             XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper);
403                     xReferenceResolvedBroadcaster.addReferenceResolvedListener(cloneKeeperId,
404                         signatureEntity.getReferenceListener());
405 
406                     try{
407                         XReferenceCollector xReferenceCollector =
408                             (XReferenceCollector)UnoRuntime.queryInterface(
409                                 XReferenceCollector.class, signatureEntity.getReferenceListener());
410                         xReferenceCollector.setReferenceId(cloneKeeperId);
411                     }
412                     catch( com.sun.star.uno.Exception e)
413                     {
414                         e.printStackTrace();
415                     }
416                 }
417 
418                 /*
419                  * if this unsolved reference reaches its max reference number, remove this reference
420                  * from all vectors.
421                  */
422                 refNum--;
423                 if (refNum == 0)
424                 {
425                     m_xSAXEventKeeper.removeElementCollector(keeperId);
426                     m_vUnsolvedReferenceIds.remove(i);
427                     m_vUnsolvedReferencedKeeperIds.remove(i);
428                     m_vUnsolvedReferenceRefNum.remove(i);
429                 }
430                 else
431                 {
432                     m_vUnsolvedReferenceRefNum.setElementAt(new Integer(refNum),(i));
433                     ++i;
434                 }
435 
436                 /*
437                  * If it is find a key, then no further search is needed, one
438                  * signature has one key at most.
439                  */
440                 if (isFindingKey)
441                 {
442                     break;
443                 }
444             }
445             else
446             {
447                 ++i;
448             }
449         }
450     }
451 
452     /*
453      * checks whether a startElement event represents any security related information.
454      * return true if this event can't be forwarded into the SAX chain.
455      */
456     private boolean checkSecurityElement(String localName, com.sun.star.xml.sax.XAttributeList xattribs)
457     {
458         boolean rc = false;
459 
460         if (localName.equals("Signature"))
461         /*
462          * this element is a Signature element.
463          */
464         {
465             SignatureEntity signatureEntity = new SignatureEntity(
466                 m_xSAXEventKeeper,
467                 m_bIsExporting,
468                 this,
469                 m_xXMLSecurityContext,
470                 m_xXMLSignature,
471                 m_xXMLEncryption,
472                 m_xRemoteServiceManager,
473                 m_xRemoteContext);
474 
475             m_signatureList.add(signatureEntity);
476             m_currentPath.push(signatureEntity);
477         }
478         else if(localName.equals("Reference"))
479         {
480             if (!m_currentPath.empty())
481             {
482                 Object signedInfo = m_currentPath.pop();
483 
484                 if (!m_currentPath.empty())
485                 {
486                     Object objSignature = m_currentPath.peek();
487 
488                     if ((objSignature instanceof SignatureEntity) && signedInfo.toString().equals("SignedInfo"))
489                     /*
490                      * this element is a Reference element in a signature.
491                      */
492                     {
493                         String uriStr = xattribs.getValueByName("URI");
494 
495                         if (uriStr.charAt(0) == '#')
496                         {
497                             uriStr = uriStr.substring(1);
498                             SignatureEntity signatureEntity = (SignatureEntity)objSignature;
499 
500                             if (uriStr != null && uriStr.length()>0)
501                             {
502                                 signatureEntity.addReferenceId(uriStr);
503                                 findKeyOrReference(signatureEntity, uriStr, false);
504                             }
505                         }
506                     }
507                 }
508                 m_currentPath.push(signedInfo);
509             }
510             m_currentPath.push(localName);
511         }
512         else if(localName.equals("KeyValue") ||
513                 localName.equals("KeyName") ||
514                 localName.equals("X509Data") ||
515                 localName.equals("EncryptedKey"))
516         {
517             if (!m_currentPath.empty())
518             {
519                 Object keyInfo = m_currentPath.pop();
520 
521                 if (!m_currentPath.empty())
522                 {
523                     Object objSorE = m_currentPath.peek();
524 
525                     if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo"))
526                     /*
527                      * this element is the key element of a signature.
528                      */
529                     {
530                         SignatureEntity signatureEntity = (SignatureEntity)objSorE;
531                         signatureEntity.setKeyId(0);
532                     }
533                     else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo"))
534                     /*
535                      * this element is the key element of an encryption.
536                      */
537                     {
538                         EncryptionEntity theEncryption = (EncryptionEntity)objSorE;
539                         theEncryption.setKeyId(0);
540                     }
541                 }
542                 m_currentPath.push(keyInfo);
543             }
544 
545             m_currentPath.push(localName);
546         }
547         else if(localName.equals("RetrievalMethod"))
548         {
549             if (!m_currentPath.empty())
550             {
551                 Object keyInfo = m_currentPath.pop();
552 
553                 if (!m_currentPath.empty())
554                 {
555                     Object objSorE = m_currentPath.peek();
556 
557                     if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo"))
558                     /*
559                      * this element is the RetrievalMethod element in a signature,
560                      * which will include the key uri of this signature.
561                      */
562                     {
563                         String uriStr = xattribs.getValueByName("URI");
564                         SignatureEntity signatureEntity = (SignatureEntity)objSorE;
565 
566                         if (uriStr != null && uriStr.length()>0)
567                         {
568                             signatureEntity.setKeyURI(uriStr);
569                             findKeyOrReference(signatureEntity,uriStr, true);
570                         }
571                     }
572                     else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo"))
573                     /*
574                      * this element is the RetrievalMethod element in an encryption,
575                      * which will include the key uri of this encryption.
576                      */
577                     {
578                         String uriStr = xattribs.getValueByName("URI");
579                         EncryptionEntity theEncryption = (EncryptionEntity)objSorE;
580 
581                         if (uriStr != null && uriStr.length()>0)
582                         {
583                             theEncryption.setKeyURI(uriStr);
584                             findKeyOrReference(theEncryption, uriStr, true);
585                         }
586                     }
587                 }
588                 m_currentPath.push(keyInfo);
589             }
590             m_currentPath.push(localName);
591         }
592         else if (localName.equals("EncryptedData")) /* || localName.equals("EncryptedKey")) */
593         /*
594          * this element is an Encryption element.
595          */
596         {
597             EncryptionEntity theEncryption = new EncryptionEntity(
598                 m_xSAXEventKeeper,
599                 m_bIsExporting,
600                 this,
601                 m_xXMLSecurityContext,
602                 m_xXMLSignature,
603                 m_xXMLEncryption,
604                 m_xRemoteServiceManager,
605                 m_xRemoteContext);
606 
607             m_encryptionList.add(theEncryption);
608 
609             if (m_bIsExporting)
610             {
611                 m_currentPath.push(theEncryption);
612             }
613             else
614             {
615                 String uriStr = xattribs.getValueByName("keyURI");
616                 if (uriStr != null && uriStr.length()>0)
617                 {
618                     theEncryption.setKeyURI(uriStr);
619                     findKeyOrReference(theEncryption,uriStr, true);
620                 }
621                 else
622                 {
623                     theEncryption.setKeyId(0);
624                 }
625 
626                 rc = true;
627             }
628         }
629         else
630         /*
631          * not a security related element.
632          */
633         {
634             m_currentPath.push(localName);
635         }
636 
637         return rc;
638     }
639 
640     /*
641      * checks whether a startElement event is referenced by any security entity.
642      */
643     private void checkReference(String localName, com.sun.star.xml.sax.XAttributeList xattribs, String id)
644     {
645         String refNumStr = xattribs.getValueByName("refNum");
646 
647         if ( m_bIsEncryptionTarget )
648         {
649             m_EncryptionForTarget.setReference(m_bIsExporting);
650             m_bIsEncryptionTarget = false;
651         }
652 
653         if (id != null && id.length()>0 )
654         /*
655          * only if this element has id attribute, then it can be referenced by
656          * a security entity.
657          */
658         {
659             /*
660              * if this element has an "refNum" attribute, then the value will be
661              * the max referencing number on this element, otherwise, set the max
662              * referencing number to 999.
663              */
664             int refNum = 999;
665 
666             if (refNumStr != null && refNumStr.length()>0 )
667             {
668                 refNum = new Integer(refNumStr).intValue();
669             }
670 
671             int length;
672 
673             /*
674              * searches the signature list to check whether any sigture has
675              * reference on this element.
676              */
677             length = m_signatureList.size();
678             for (int i=0; i<length; ++i)
679             {
680                 SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(i);
681 
682                 if (signatureEntity.setReference(id, m_bIsExporting))
683                 {
684                     refNum--;
685                 }
686 
687                 if (signatureEntity.setKey(id, m_bIsExporting))
688                 {
689                     refNum--;
690                 }
691             }
692 
693             /*
694              * searches the encryption list for reference.
695              */
696             length = m_encryptionList.size();
697             for (int i=0; i<length; ++i)
698             {
699                 EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(i);
700 
701                 if (theEncryption.setKey(id, m_bIsExporting))
702                 {
703                     refNum--;
704                 }
705             }
706 
707             /*
708              * if the max referencing number is not reached, then add this element
709              * into the unsolved reference list.
710              */
711             if (refNum>0)
712             {
713                 int keeperId;
714 
715                 if (localName.equals("EncryptedKey"))
716                 {
717                     keeperId = m_xSAXEventKeeper.addSecurityElementCollector(
718                         m_bIsExporting?
719                         (ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY),
720                         true);
721                 }
722                 else
723                 {
724                     keeperId = m_xSAXEventKeeper.addSecurityElementCollector(
725                         m_bIsExporting?
726                         (ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY),
727                         false);
728                 }
729 
730                 m_vUnsolvedReferenceIds.add(id);
731                 m_vUnsolvedReferencedKeeperIds.add(new Integer(keeperId));
732                 m_vUnsolvedReferenceRefNum.add(new Integer(refNum));
733             }
734         }
735     }
736 
737     /*
738      * configures the output handler.
739      */
740     private void setOutputHandler(XDocumentHandler handler)
741     {
742         m_xOutputHandler = handler;
743         changeOutput();
744     }
745 
746 
747 /**************************************************************************************
748  * protected methods
749  **************************************************************************************/
750 
751         /*
752          * methods used to transfer unsolved reference information.
753          */
754     protected Vector getUnsolvedReferenceIds()
755     {
756         return m_vUnsolvedReferenceIds;
757     }
758 
759     protected Vector getUnsolvedReferenceKeeperIds()
760     {
761         return m_vUnsolvedReferencedKeeperIds;
762     }
763 
764     protected Vector getUnsolvedReferenceRefNum()
765     {
766         return m_vUnsolvedReferenceRefNum;
767     }
768 
769     protected String getBufferNodeTreeInformation()
770     {
771         if (m_xSAXEventKeeper != null)
772         {
773             return m_xSAXEventKeeper.printBufferNodeTree();
774         }
775         else
776         {
777             return null;
778         }
779     }
780 
781     protected void getDocument(XDocumentHandler handler)
782     {
783         if (m_xXMLDocumentWrapper != null)
784         {
785             try
786             {
787                 m_xXMLDocumentWrapper.getTree(handler);
788             }
789             catch(SAXException e)
790             {
791                 e.printStackTrace();
792             }
793         }
794     }
795 
796     protected void endMission()
797     {
798         while (m_signatureList.size()>0 || m_encryptionList.size()>0)
799         {
800             if (m_signatureList.size()>0)
801             {
802                 SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(0);
803                 m_signatureList.remove(0);
804                 signatureEntity.endMission();
805             }
806             else if (m_encryptionList.size()>0)
807             {
808                 EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(0);
809                 m_encryptionList.remove(0);
810                 theEncryption.endMission();
811             }
812         }
813 
814         while (m_vUnsolvedReferenceIds.size()>0)
815         {
816             int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(0)).intValue();
817             m_xSAXEventKeeper.removeElementCollector(keeperId);
818             m_vUnsolvedReferenceIds.remove(0);
819             m_vUnsolvedReferencedKeeperIds.remove(0);
820             m_vUnsolvedReferenceRefNum.remove(0);
821         }
822 
823         m_xSAXEventKeeper.setNextHandler(null);
824 
825         XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster =
826             (XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface(
827                 XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper);
828         xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(null);
829 
830         m_xSAXEventKeeper = null;
831         m_xXMLDocumentWrapper = null;
832         m_xOutputHandler = null;
833         m_xXMLSecurityContext = null;
834         m_xXMLSignature = null;
835         m_xXMLEncryption = null;
836 
837         m_xExportHandler = null;
838         m_parsingThread.setHandler(null);
839     }
840 
841 /**************************************************************************************
842  * public methods
843  **************************************************************************************/
844 
845     /*
846      * XDocumentHandler
847      */
848         public void startDocument()
849     {
850         try{
851             m_xExportHandler.startDocument();
852         }
853         catch( com.sun.star.xml.sax.SAXException e)
854         {
855             e.printStackTrace();
856         }
857 
858     }
859 
860         public void endDocument()
861     {
862         try{
863             m_xExportHandler.endDocument();
864         }
865         catch( com.sun.star.xml.sax.SAXException e)
866         {
867             e.printStackTrace();
868         }
869     }
870 
871     public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs)
872     {
873         try{
874             String idAttr = xattribs.getValueByName("id");
875             if (idAttr == null)
876             {
877                 idAttr = xattribs.getValueByName("Id");
878             }
879 
880             boolean hasIdAttr = (idAttr != null && idAttr.length()>0 );
881             boolean needResend = false;
882 
883             if (hasIdAttr ||
884                 (str.equals("Signature")||str.equals("EncryptedData")))/* || str.equals("EncryptedKey"))) */
885             {
886                 if (foundSecurityRelated() && !m_bIsExporting)
887                 {
888                     needResend = true;
889                 }
890             }
891 
892             boolean suppressToNext = checkSecurityElement(str, xattribs);
893 
894             checkReference(str, xattribs, idAttr);
895 
896             if (needResend)
897             {
898                 m_xSAXEventKeeper.setNextHandler(null);
899 
900                 XDocumentHandler saxEventKeeperHandler =
901                     (XDocumentHandler)UnoRuntime.queryInterface(
902                         XDocumentHandler.class, m_xSAXEventKeeper);
903                 saxEventKeeperHandler.startElement(str, xattribs);
904                 m_xSAXEventKeeper.setNextHandler((XDocumentHandler)this);
905             }
906 
907             if (!suppressToNext)
908             {
909                 m_xExportHandler.startElement(str, xattribs);
910             }
911         }
912         catch( com.sun.star.xml.sax.SAXException e)
913         {
914             e.printStackTrace();
915         }
916     }
917 
918     public void endElement(String str)
919     {
920         if (!m_currentPath.empty())
921         {
922                 Object obj = m_currentPath.pop();
923 
924                 if (obj.toString().equals("SignedInfo"))
925                 {
926                 if (!m_currentPath.empty())
927                 {
928                         Object objSignature = m_currentPath.peek();
929                         if (objSignature != null && objSignature instanceof SignatureEntity)
930                         {
931                             ((SignatureEntity)objSignature).setReferenceNumber();
932                         }
933                     }
934                 }
935                 else if (obj instanceof EncryptionEntity)
936                 {
937                     m_bIsEncryptionTarget = true;
938                 m_EncryptionForTarget = (EncryptionEntity)obj;
939 
940                 }
941             }
942 
943         try{
944             m_xExportHandler.endElement(str);
945         }
946         catch( com.sun.star.xml.sax.SAXException e)
947         {
948             e.printStackTrace();
949         }
950     }
951 
952     public void characters(String str)
953     {
954         try{
955                 m_xExportHandler.characters(str);
956         }
957         catch( com.sun.star.xml.sax.SAXException e)
958         {
959             e.printStackTrace();
960         }
961     }
962 
963     public void ignorableWhitespace(String str)
964     {
965     }
966 
967     public void processingInstruction(String aTarget, String aData)
968     {
969         try{
970             m_xExportHandler.processingInstruction(aTarget, aData);
971         }
972         catch( com.sun.star.xml.sax.SAXException e)
973         {
974             e.printStackTrace();
975         }
976     }
977 
978     public void setDocumentLocator (com.sun.star.xml.sax.XLocator xLocator )
979         throws com.sun.star.xml.sax.SAXException
980     {
981     }
982 
983 
984     /*
985      * XSignatureCreationResultListener
986      */
987     public void signatureCreated(int securityId, SecurityOperationStatus creationResult)
988     {
989         String message = new String();
990         message += "A Signature is created:";
991         message += "\nSecurity Id = "+securityId;
992         message += "\nCreation result = "+((creationResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
993 
994         m_testTool.showMessage("Message from : SignatureCreator\n\n"+message+"\n ");
995     }
996 
997     /*
998      * XSignatureVerifyResultListener
999      */
1000     public void signatureVerified(int securityId, SecurityOperationStatus verifyResult)
1001     {
1002         String message = new String();
1003         message += "A Signature is verified:";
1004         message += "\nSecurity Id = "+securityId;
1005         message += "\nVerify result = "+((verifyResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
1006 
1007         m_testTool.showMessage("Message from : SignatureVerifier\n\n"+message+"\n ");
1008     }
1009 
1010     /*
1011      * XEncryptionResultListener
1012      */
1013     public void encrypted(int securityId, SecurityOperationStatus encryptionResult)
1014     {
1015         String message = new String();
1016         message += "An EncryptedData is encrypted:";
1017         message += "\nSecurity Id = "+securityId;
1018         message += "\nEncrypt result = "+((encryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
1019 
1020         m_testTool.showMessage("Message from : Encryptor\n\n"+message+"\n ");
1021     }
1022 
1023     /*
1024      * XDecryptionResultListener methods
1025      */
1026     public void decrypted(int securityId, SecurityOperationStatus decryptionResult)
1027     {
1028         String message = new String();
1029         message += "An EncryptedData is decrypted:";
1030         message += "\nSecurity Id = "+securityId;
1031         message += "\nDecrypt result = "+((decryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail");
1032 
1033         m_testTool.showMessage("Message from : Decryptor\n\n"+message+"\n ");
1034     }
1035 
1036     /*
1037      * XSAXEventKeeperStatusChangeListener methods
1038      */
1039     public void blockingStatusChanged(boolean isBlocking)
1040     {
1041         m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
1042                     (isBlocking?"The SAX event stream is blocked.":"The SAX event stream is unblocked.")+
1043                     "\n ");
1044 
1045         this.m_bIsBlocking = isBlocking;
1046     }
1047 
1048     public void collectionStatusChanged(boolean isInsideCollectedElement)
1049     {
1050         m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
1051                     (isInsideCollectedElement?"Begin to buffer data ...":"End of data bufferring.")+
1052                     "\n ");
1053 
1054         /*
1055         this.m_bIsInsideCollectedElement = isInsideCollectedElement;
1056 
1057         if ( !m_bIsInsideCollectedElement && !m_bIsBlocking)
1058         {
1059             m_bSAXEventKeeperIncluded = false;
1060         }
1061         else
1062         {
1063             m_bSAXEventKeeperIncluded = true;
1064         }
1065         changeOutput();
1066         */
1067     }
1068 
1069     public void bufferStatusChanged(boolean isBufferEmpty)
1070     {
1071         m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+
1072                     (isBufferEmpty?"All bufferred data are released, the SAXEventKeeper is destroyed.":"buffer data appears.")+
1073                     "\n ");
1074         /*
1075         if (isBufferEmpty)
1076         {
1077             m_xXMLDocumentWrapper = null;
1078             m_xSAXEventKeeper = null;
1079             m_bSAXEventKeeperIncluded = false;
1080             changeOutput();
1081         }
1082         */
1083     }
1084 }
1085 
1086