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