xref: /AOO41X/main/xmlsecurity/tools/uno/XMLSecurityFrameworkController.java (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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