| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| package com.sun.star.xml.security.uno; |
| |
| import java.util.Stack; |
| import java.util.Vector; |
| |
| /* uno classes */ |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.lang.XMultiComponentFactory; |
| import com.sun.star.lang.XInitialization; |
| import com.sun.star.uno.XComponentContext; |
| import com.sun.star.xml.sax.XDocumentHandler; |
| import com.sun.star.xml.sax.XAttributeList; |
| import com.sun.star.xml.sax.SAXException; |
| |
| import com.sun.star.xml.crypto.*; |
| import com.sun.star.xml.crypto.sax.*; |
| import com.sun.star.xml.wrapper.*; |
| |
| /* |
| * the XMLSecurityFrameworkController class is used to controll the xml security framework. |
| */ |
| public class XMLSecurityFrameworkController |
| implements XDocumentHandler, XSignatureCreationResultListener, XSignatureVerifyResultListener, |
| XEncryptionResultListener, XDecryptionResultListener, XSAXEventKeeperStatusChangeListener |
| { |
| /* |
| * UNO framework component |
| */ |
| private XMultiComponentFactory m_xRemoteServiceManager; |
| private XComponentContext m_xRemoteContext; |
| |
| /* |
| * xml security related UNO components |
| */ |
| private XSecuritySAXEventKeeper m_xSAXEventKeeper; |
| private XXMLDocumentWrapper m_xXMLDocumentWrapper; |
| private XDocumentHandler m_xOutputHandler; |
| private XXMLSecurityContext m_xXMLSecurityContext; |
| private XXMLSignature m_xXMLSignature; |
| private XXMLEncryption m_xXMLEncryption; |
| |
| /* |
| * used to reserve the current SAX ancestor path |
| */ |
| private Stack m_currentPath; |
| |
| /* |
| * maintains all SignatureEntities. |
| */ |
| private Vector m_signatureList; |
| |
| /* |
| * maintains all EncryptionEntities. |
| */ |
| private Vector m_encryptionList; |
| |
| /* |
| * maintains all unsolved reference Ids. |
| * These ids are strings which is the value of the id attribute |
| * of the referenced element. |
| */ |
| private Vector m_vUnsolvedReferenceIds; |
| |
| /* |
| * maintains all unsolved reference keeper ids. |
| * The keeper id is used to uniquely identify a bufferred element |
| * by the SAXEventKeeper. |
| */ |
| private Vector m_vUnsolvedReferencedKeeperIds; |
| |
| /* |
| * maintains the left time that each unsolved reference can be |
| * claimed. |
| */ |
| private Vector m_vUnsolvedReferenceRefNum; |
| |
| /* |
| * whether exporting or importing |
| */ |
| private boolean m_bIsExporting; |
| |
| /* |
| * whether java or c |
| */ |
| private boolean m_bIsJavaBased; |
| |
| /* |
| * whether the SAXEventKeeper is blocking |
| */ |
| private boolean m_bIsBlocking; |
| |
| /* |
| * whether it is collecting a bufferred element |
| */ |
| private boolean m_bIsInsideCollectedElement; |
| |
| /* |
| * whether a SAXEventKeeper is in the SAX chain |
| */ |
| private boolean m_bSAXEventKeeperIncluded; |
| |
| /* |
| * the ParsingThread used to parse the document |
| */ |
| private ParsingThread m_parsingThread; |
| |
| /* |
| * the next document handler that will receives SAX events |
| * from the parsing thread. |
| * if the SAXEventKeeper is on the SAX chain, then this |
| * variable will be the SAXEventKeeper, otherwise, this |
| * variable will be the xOutputHandler. |
| */ |
| private XDocumentHandler m_xExportHandler; |
| |
| /* |
| * the TestTool used to feedback information |
| */ |
| private TestTool m_testTool; |
| |
| /* |
| * for encryption target |
| */ |
| private boolean m_bIsEncryptionTarget; |
| private EncryptionEntity m_EncryptionForTarget; |
| |
| XMLSecurityFrameworkController( |
| TestTool testTool, |
| boolean bIsExporting, |
| boolean bIsJavaBased, |
| XDocumentHandler xOutputHandler, |
| ParsingThread parsingThread, |
| XXMLSecurityContext xXMLSecurityContext, |
| XXMLSignature xXMLSignature, |
| XXMLEncryption xXMLEncryption, |
| XMultiComponentFactory xRemoteServiceManager, |
| XComponentContext xRemoteContext) |
| { |
| m_bIsExporting = bIsExporting; |
| m_bIsJavaBased = bIsJavaBased; |
| |
| m_xOutputHandler = xOutputHandler; |
| m_xXMLSecurityContext = xXMLSecurityContext; |
| m_xXMLSignature = xXMLSignature; |
| m_xXMLEncryption = xXMLEncryption; |
| m_xRemoteServiceManager = xRemoteServiceManager; |
| m_xRemoteContext = xRemoteContext; |
| |
| m_testTool = testTool; |
| m_parsingThread = parsingThread; |
| |
| m_signatureList = new Vector(); |
| m_encryptionList = new Vector(); |
| |
| m_vUnsolvedReferenceIds = new Vector(); |
| m_vUnsolvedReferencedKeeperIds = new Vector(); |
| m_vUnsolvedReferenceRefNum = new Vector(); |
| |
| m_xXMLDocumentWrapper = null; |
| m_xSAXEventKeeper = null; |
| |
| m_bSAXEventKeeperIncluded = false; |
| m_bIsBlocking = false; |
| m_bIsInsideCollectedElement = false; |
| |
| m_bIsEncryptionTarget = false; |
| m_EncryptionForTarget = null; |
| |
| changeOutput(); |
| |
| m_currentPath = new Stack(); |
| |
| foundSecurityRelated(); |
| } |
| |
| /************************************************************************************** |
| * private methods |
| **************************************************************************************/ |
| |
| /* |
| * changes the output document handler. |
| */ |
| private void changeOutput() |
| { |
| if (m_bIsExporting) |
| { |
| m_parsingThread.setHandler(this); |
| |
| /* |
| * If the SAXEventKeeper is in the SAX chain, then redirects output |
| * to the SAXEventKeeper, otherwise, to the m_xOutputHandler |
| */ |
| if (m_bSAXEventKeeperIncluded) |
| { |
| m_xExportHandler = (XDocumentHandler)UnoRuntime.queryInterface( |
| XDocumentHandler.class, m_xSAXEventKeeper); |
| m_xSAXEventKeeper.setNextHandler(m_xOutputHandler); |
| |
| m_testTool.updatesSAXChainInformation("XMLExporter -> SAXEventKeeper -> SAXWriter"); |
| } |
| else |
| { |
| m_xExportHandler = m_xOutputHandler; |
| m_testTool.updatesSAXChainInformation("XMLExporter -> SAXWriter"); |
| } |
| } |
| else |
| { |
| if (m_bSAXEventKeeperIncluded) |
| { |
| m_parsingThread.setHandler( |
| (XDocumentHandler)UnoRuntime.queryInterface(XDocumentHandler.class, m_xSAXEventKeeper)); |
| m_xSAXEventKeeper.setNextHandler(this); |
| m_testTool.updatesSAXChainInformation("SAXParser -> SAXEventKeeper -> XMLImporter"); |
| } |
| else |
| { |
| m_parsingThread.setHandler(this); |
| m_testTool.updatesSAXChainInformation("SAXParser -> XMLImporter"); |
| } |
| m_xExportHandler = m_xOutputHandler; |
| } |
| } |
| |
| /* |
| * handles the situation when a security related element is found. |
| * if the SAXEventKeeper is not initialized, then creates a |
| * SAXEventKeeper. |
| * the return value represents whether the SAXEventKeeper is newly |
| * created. |
| */ |
| private boolean foundSecurityRelated() |
| { |
| if (m_xSAXEventKeeper == null) |
| { |
| m_testTool.showMessage("Message from : "+ |
| (m_bIsExporting?"XMLExporter":"XMLImporter")+ |
| "\n\nA security related content found, a SAXEventKeeper is created.\n "); |
| |
| m_bIsBlocking = false; |
| m_bIsInsideCollectedElement = false; |
| |
| try |
| { |
| /* |
| * creates an XMLDocumentWrapper component. |
| */ |
| Object xmlDocumentObj = null; |
| |
| if (m_bIsJavaBased) |
| { |
| xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext( |
| TestTool.XMLDOCUMENTWRAPPER_COMPONENT_JAVA, m_xRemoteContext); |
| } |
| else |
| { |
| xmlDocumentObj = m_xRemoteServiceManager.createInstanceWithContext( |
| TestTool.XMLDOCUMENTWRAPPER_COMPONENT_C, m_xRemoteContext); |
| } |
| |
| m_xXMLDocumentWrapper = (XXMLDocumentWrapper)UnoRuntime.queryInterface( |
| XXMLDocumentWrapper.class, xmlDocumentObj); |
| |
| /* |
| * creates a SAXEventKeeper component. |
| */ |
| Object saxEventKeeperObj = m_xRemoteServiceManager.createInstanceWithContext( |
| TestTool.SAXEVENTKEEPER_COMPONENT, m_xRemoteContext); |
| |
| m_xSAXEventKeeper = |
| (XSecuritySAXEventKeeper)UnoRuntime.queryInterface( |
| XSecuritySAXEventKeeper.class, saxEventKeeperObj); |
| |
| /* |
| * initializes the SAXEventKeeper component with the XMLDocumentWrapper component. |
| */ |
| XInitialization xInitialization = |
| (XInitialization)UnoRuntime.queryInterface( |
| XInitialization.class, m_xSAXEventKeeper); |
| Object args[]=new Object[1]; |
| args[0] = m_xXMLDocumentWrapper; |
| xInitialization.initialize(args); |
| } |
| catch( com.sun.star.uno.Exception e) |
| { |
| e.printStackTrace(); |
| } |
| |
| /* |
| * configures the SAXEventKeeper's status change listener. |
| */ |
| XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster = |
| (XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface( |
| XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper); |
| xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(this); |
| } |
| |
| boolean rc = !m_bSAXEventKeeperIncluded; |
| |
| /* |
| * changes the export document handler. |
| */ |
| m_bSAXEventKeeperIncluded=true; |
| changeOutput(); |
| |
| return rc; |
| } |
| |
| /* |
| * finds key element or referenced element for a signature. |
| */ |
| private void findKeyOrReference(SecurityEntity signatureEntity, String uriStr, boolean isFindingKey) |
| { |
| int i=0; |
| |
| while (i<m_vUnsolvedReferenceIds.size()) |
| { |
| String id = (String)m_vUnsolvedReferenceIds.elementAt(i); |
| |
| if (id.equals(uriStr)) |
| { |
| int refNum = ((Integer)m_vUnsolvedReferenceRefNum.elementAt(i)).intValue(); |
| int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(i)).intValue(); |
| |
| if (isFindingKey) |
| { |
| /* |
| * clones a new ElementCollector for the key element. |
| */ |
| int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector( |
| keeperId, |
| m_bIsExporting? |
| (ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY)); |
| |
| /* |
| * notifies the key keeper id. |
| */ |
| signatureEntity.setKeyId(cloneKeeperId); |
| |
| /* |
| * sets the security id for the key. |
| */ |
| m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId()); |
| |
| /* |
| * sets the resolve listener. |
| */ |
| XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster = |
| (XReferenceResolvedBroadcaster)UnoRuntime.queryInterface( |
| XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper); |
| xReferenceResolvedBroadcaster.addReferenceResolvedListener( |
| cloneKeeperId, |
| signatureEntity.getReferenceListener()); |
| } |
| else |
| { |
| /* |
| * clones a new ElementCollector for the referenced element. |
| */ |
| int cloneKeeperId = m_xSAXEventKeeper.cloneElementCollector( |
| keeperId, |
| m_bIsExporting? |
| (ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY)); |
| |
| /* |
| * sets the security id. |
| */ |
| m_xSAXEventKeeper.setSecurityId(cloneKeeperId, signatureEntity.getSecurityId()); |
| |
| /* |
| * sets the resolve listener. |
| */ |
| XReferenceResolvedBroadcaster xReferenceResolvedBroadcaster = |
| (XReferenceResolvedBroadcaster)UnoRuntime.queryInterface( |
| XReferenceResolvedBroadcaster.class, m_xSAXEventKeeper); |
| xReferenceResolvedBroadcaster.addReferenceResolvedListener(cloneKeeperId, |
| signatureEntity.getReferenceListener()); |
| |
| try{ |
| XReferenceCollector xReferenceCollector = |
| (XReferenceCollector)UnoRuntime.queryInterface( |
| XReferenceCollector.class, signatureEntity.getReferenceListener()); |
| xReferenceCollector.setReferenceId(cloneKeeperId); |
| } |
| catch( com.sun.star.uno.Exception e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| /* |
| * if this unsolved reference reaches its max reference number, remove this reference |
| * from all vectors. |
| */ |
| refNum--; |
| if (refNum == 0) |
| { |
| m_xSAXEventKeeper.removeElementCollector(keeperId); |
| m_vUnsolvedReferenceIds.remove(i); |
| m_vUnsolvedReferencedKeeperIds.remove(i); |
| m_vUnsolvedReferenceRefNum.remove(i); |
| } |
| else |
| { |
| m_vUnsolvedReferenceRefNum.setElementAt(new Integer(refNum),(i)); |
| ++i; |
| } |
| |
| /* |
| * If it is find a key, then no further search is needed, one |
| * signature has one key at most. |
| */ |
| if (isFindingKey) |
| { |
| break; |
| } |
| } |
| else |
| { |
| ++i; |
| } |
| } |
| } |
| |
| /* |
| * checks whether a startElement event represents any security related information. |
| * return true if this event can't be forwarded into the SAX chain. |
| */ |
| private boolean checkSecurityElement(String localName, com.sun.star.xml.sax.XAttributeList xattribs) |
| { |
| boolean rc = false; |
| |
| if (localName.equals("Signature")) |
| /* |
| * this element is a Signature element. |
| */ |
| { |
| SignatureEntity signatureEntity = new SignatureEntity( |
| m_xSAXEventKeeper, |
| m_bIsExporting, |
| this, |
| m_xXMLSecurityContext, |
| m_xXMLSignature, |
| m_xXMLEncryption, |
| m_xRemoteServiceManager, |
| m_xRemoteContext); |
| |
| m_signatureList.add(signatureEntity); |
| m_currentPath.push(signatureEntity); |
| } |
| else if(localName.equals("Reference")) |
| { |
| if (!m_currentPath.empty()) |
| { |
| Object signedInfo = m_currentPath.pop(); |
| |
| if (!m_currentPath.empty()) |
| { |
| Object objSignature = m_currentPath.peek(); |
| |
| if ((objSignature instanceof SignatureEntity) && signedInfo.toString().equals("SignedInfo")) |
| /* |
| * this element is a Reference element in a signature. |
| */ |
| { |
| String uriStr = xattribs.getValueByName("URI"); |
| |
| if (uriStr.charAt(0) == '#') |
| { |
| uriStr = uriStr.substring(1); |
| SignatureEntity signatureEntity = (SignatureEntity)objSignature; |
| |
| if (uriStr != null && uriStr.length()>0) |
| { |
| signatureEntity.addReferenceId(uriStr); |
| findKeyOrReference(signatureEntity, uriStr, false); |
| } |
| } |
| } |
| } |
| m_currentPath.push(signedInfo); |
| } |
| m_currentPath.push(localName); |
| } |
| else if(localName.equals("KeyValue") || |
| localName.equals("KeyName") || |
| localName.equals("X509Data") || |
| localName.equals("EncryptedKey")) |
| { |
| if (!m_currentPath.empty()) |
| { |
| Object keyInfo = m_currentPath.pop(); |
| |
| if (!m_currentPath.empty()) |
| { |
| Object objSorE = m_currentPath.peek(); |
| |
| if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo")) |
| /* |
| * this element is the key element of a signature. |
| */ |
| { |
| SignatureEntity signatureEntity = (SignatureEntity)objSorE; |
| signatureEntity.setKeyId(0); |
| } |
| else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo")) |
| /* |
| * this element is the key element of an encryption. |
| */ |
| { |
| EncryptionEntity theEncryption = (EncryptionEntity)objSorE; |
| theEncryption.setKeyId(0); |
| } |
| } |
| m_currentPath.push(keyInfo); |
| } |
| |
| m_currentPath.push(localName); |
| } |
| else if(localName.equals("RetrievalMethod")) |
| { |
| if (!m_currentPath.empty()) |
| { |
| Object keyInfo = m_currentPath.pop(); |
| |
| if (!m_currentPath.empty()) |
| { |
| Object objSorE = m_currentPath.peek(); |
| |
| if ((objSorE instanceof SignatureEntity) && keyInfo.toString().equals("KeyInfo")) |
| /* |
| * this element is the RetrievalMethod element in a signature, |
| * which will include the key uri of this signature. |
| */ |
| { |
| String uriStr = xattribs.getValueByName("URI"); |
| SignatureEntity signatureEntity = (SignatureEntity)objSorE; |
| |
| if (uriStr != null && uriStr.length()>0) |
| { |
| signatureEntity.setKeyURI(uriStr); |
| findKeyOrReference(signatureEntity,uriStr, true); |
| } |
| } |
| else if ((objSorE instanceof EncryptionEntity) && keyInfo.toString().equals("KeyInfo")) |
| /* |
| * this element is the RetrievalMethod element in an encryption, |
| * which will include the key uri of this encryption. |
| */ |
| { |
| String uriStr = xattribs.getValueByName("URI"); |
| EncryptionEntity theEncryption = (EncryptionEntity)objSorE; |
| |
| if (uriStr != null && uriStr.length()>0) |
| { |
| theEncryption.setKeyURI(uriStr); |
| findKeyOrReference(theEncryption, uriStr, true); |
| } |
| } |
| } |
| m_currentPath.push(keyInfo); |
| } |
| m_currentPath.push(localName); |
| } |
| else if (localName.equals("EncryptedData")) /* || localName.equals("EncryptedKey")) */ |
| /* |
| * this element is an Encryption element. |
| */ |
| { |
| EncryptionEntity theEncryption = new EncryptionEntity( |
| m_xSAXEventKeeper, |
| m_bIsExporting, |
| this, |
| m_xXMLSecurityContext, |
| m_xXMLSignature, |
| m_xXMLEncryption, |
| m_xRemoteServiceManager, |
| m_xRemoteContext); |
| |
| m_encryptionList.add(theEncryption); |
| |
| if (m_bIsExporting) |
| { |
| m_currentPath.push(theEncryption); |
| } |
| else |
| { |
| String uriStr = xattribs.getValueByName("keyURI"); |
| if (uriStr != null && uriStr.length()>0) |
| { |
| theEncryption.setKeyURI(uriStr); |
| findKeyOrReference(theEncryption,uriStr, true); |
| } |
| else |
| { |
| theEncryption.setKeyId(0); |
| } |
| |
| rc = true; |
| } |
| } |
| else |
| /* |
| * not a security related element. |
| */ |
| { |
| m_currentPath.push(localName); |
| } |
| |
| return rc; |
| } |
| |
| /* |
| * checks whether a startElement event is referenced by any security entity. |
| */ |
| private void checkReference(String localName, com.sun.star.xml.sax.XAttributeList xattribs, String id) |
| { |
| String refNumStr = xattribs.getValueByName("refNum"); |
| |
| if ( m_bIsEncryptionTarget ) |
| { |
| m_EncryptionForTarget.setReference(m_bIsExporting); |
| m_bIsEncryptionTarget = false; |
| } |
| |
| if (id != null && id.length()>0 ) |
| /* |
| * only if this element has id attribute, then it can be referenced by |
| * a security entity. |
| */ |
| { |
| /* |
| * if this element has an "refNum" attribute, then the value will be |
| * the max referencing number on this element, otherwise, set the max |
| * referencing number to 999. |
| */ |
| int refNum = 999; |
| |
| if (refNumStr != null && refNumStr.length()>0 ) |
| { |
| refNum = new Integer(refNumStr).intValue(); |
| } |
| |
| int length; |
| |
| /* |
| * searches the signature list to check whether any sigture has |
| * reference on this element. |
| */ |
| length = m_signatureList.size(); |
| for (int i=0; i<length; ++i) |
| { |
| SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(i); |
| |
| if (signatureEntity.setReference(id, m_bIsExporting)) |
| { |
| refNum--; |
| } |
| |
| if (signatureEntity.setKey(id, m_bIsExporting)) |
| { |
| refNum--; |
| } |
| } |
| |
| /* |
| * searches the encryption list for reference. |
| */ |
| length = m_encryptionList.size(); |
| for (int i=0; i<length; ++i) |
| { |
| EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(i); |
| |
| if (theEncryption.setKey(id, m_bIsExporting)) |
| { |
| refNum--; |
| } |
| } |
| |
| /* |
| * if the max referencing number is not reached, then add this element |
| * into the unsolved reference list. |
| */ |
| if (refNum>0) |
| { |
| int keeperId; |
| |
| if (localName.equals("EncryptedKey")) |
| { |
| keeperId = m_xSAXEventKeeper.addSecurityElementCollector( |
| m_bIsExporting? |
| (ElementMarkPriority.BEFOREMODIFY):(ElementMarkPriority.AFTERMODIFY), |
| true); |
| } |
| else |
| { |
| keeperId = m_xSAXEventKeeper.addSecurityElementCollector( |
| m_bIsExporting? |
| (ElementMarkPriority.AFTERMODIFY):(ElementMarkPriority.BEFOREMODIFY), |
| false); |
| } |
| |
| m_vUnsolvedReferenceIds.add(id); |
| m_vUnsolvedReferencedKeeperIds.add(new Integer(keeperId)); |
| m_vUnsolvedReferenceRefNum.add(new Integer(refNum)); |
| } |
| } |
| } |
| |
| /* |
| * configures the output handler. |
| */ |
| private void setOutputHandler(XDocumentHandler handler) |
| { |
| m_xOutputHandler = handler; |
| changeOutput(); |
| } |
| |
| |
| /************************************************************************************** |
| * protected methods |
| **************************************************************************************/ |
| |
| /* |
| * methods used to transfer unsolved reference information. |
| */ |
| protected Vector getUnsolvedReferenceIds() |
| { |
| return m_vUnsolvedReferenceIds; |
| } |
| |
| protected Vector getUnsolvedReferenceKeeperIds() |
| { |
| return m_vUnsolvedReferencedKeeperIds; |
| } |
| |
| protected Vector getUnsolvedReferenceRefNum() |
| { |
| return m_vUnsolvedReferenceRefNum; |
| } |
| |
| protected String getBufferNodeTreeInformation() |
| { |
| if (m_xSAXEventKeeper != null) |
| { |
| return m_xSAXEventKeeper.printBufferNodeTree(); |
| } |
| else |
| { |
| return null; |
| } |
| } |
| |
| protected void getDocument(XDocumentHandler handler) |
| { |
| if (m_xXMLDocumentWrapper != null) |
| { |
| try |
| { |
| m_xXMLDocumentWrapper.getTree(handler); |
| } |
| catch(SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| protected void endMission() |
| { |
| while (m_signatureList.size()>0 || m_encryptionList.size()>0) |
| { |
| if (m_signatureList.size()>0) |
| { |
| SignatureEntity signatureEntity = (SignatureEntity)m_signatureList.elementAt(0); |
| m_signatureList.remove(0); |
| signatureEntity.endMission(); |
| } |
| else if (m_encryptionList.size()>0) |
| { |
| EncryptionEntity theEncryption = (EncryptionEntity)m_encryptionList.elementAt(0); |
| m_encryptionList.remove(0); |
| theEncryption.endMission(); |
| } |
| } |
| |
| while (m_vUnsolvedReferenceIds.size()>0) |
| { |
| int keeperId = ((Integer)m_vUnsolvedReferencedKeeperIds.elementAt(0)).intValue(); |
| m_xSAXEventKeeper.removeElementCollector(keeperId); |
| m_vUnsolvedReferenceIds.remove(0); |
| m_vUnsolvedReferencedKeeperIds.remove(0); |
| m_vUnsolvedReferenceRefNum.remove(0); |
| } |
| |
| m_xSAXEventKeeper.setNextHandler(null); |
| |
| XSAXEventKeeperStatusChangeBroadcaster xSaxEventKeeperStatusChangeBroadcaster = |
| (XSAXEventKeeperStatusChangeBroadcaster)UnoRuntime.queryInterface( |
| XSAXEventKeeperStatusChangeBroadcaster.class, m_xSAXEventKeeper); |
| xSaxEventKeeperStatusChangeBroadcaster.addSAXEventKeeperStatusChangeListener(null); |
| |
| m_xSAXEventKeeper = null; |
| m_xXMLDocumentWrapper = null; |
| m_xOutputHandler = null; |
| m_xXMLSecurityContext = null; |
| m_xXMLSignature = null; |
| m_xXMLEncryption = null; |
| |
| m_xExportHandler = null; |
| m_parsingThread.setHandler(null); |
| } |
| |
| /************************************************************************************** |
| * public methods |
| **************************************************************************************/ |
| |
| /* |
| * XDocumentHandler |
| */ |
| public void startDocument() |
| { |
| try{ |
| m_xExportHandler.startDocument(); |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| |
| } |
| |
| public void endDocument() |
| { |
| try{ |
| m_xExportHandler.endDocument(); |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs) |
| { |
| try{ |
| String idAttr = xattribs.getValueByName("id"); |
| if (idAttr == null) |
| { |
| idAttr = xattribs.getValueByName("Id"); |
| } |
| |
| boolean hasIdAttr = (idAttr != null && idAttr.length()>0 ); |
| boolean needResend = false; |
| |
| if (hasIdAttr || |
| (str.equals("Signature")||str.equals("EncryptedData")))/* || str.equals("EncryptedKey"))) */ |
| { |
| if (foundSecurityRelated() && !m_bIsExporting) |
| { |
| needResend = true; |
| } |
| } |
| |
| boolean suppressToNext = checkSecurityElement(str, xattribs); |
| |
| checkReference(str, xattribs, idAttr); |
| |
| if (needResend) |
| { |
| m_xSAXEventKeeper.setNextHandler(null); |
| |
| XDocumentHandler saxEventKeeperHandler = |
| (XDocumentHandler)UnoRuntime.queryInterface( |
| XDocumentHandler.class, m_xSAXEventKeeper); |
| saxEventKeeperHandler.startElement(str, xattribs); |
| m_xSAXEventKeeper.setNextHandler((XDocumentHandler)this); |
| } |
| |
| if (!suppressToNext) |
| { |
| m_xExportHandler.startElement(str, xattribs); |
| } |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void endElement(String str) |
| { |
| if (!m_currentPath.empty()) |
| { |
| Object obj = m_currentPath.pop(); |
| |
| if (obj.toString().equals("SignedInfo")) |
| { |
| if (!m_currentPath.empty()) |
| { |
| Object objSignature = m_currentPath.peek(); |
| if (objSignature != null && objSignature instanceof SignatureEntity) |
| { |
| ((SignatureEntity)objSignature).setReferenceNumber(); |
| } |
| } |
| } |
| else if (obj instanceof EncryptionEntity) |
| { |
| m_bIsEncryptionTarget = true; |
| m_EncryptionForTarget = (EncryptionEntity)obj; |
| |
| } |
| } |
| |
| try{ |
| m_xExportHandler.endElement(str); |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void characters(String str) |
| { |
| try{ |
| m_xExportHandler.characters(str); |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void ignorableWhitespace(String str) |
| { |
| } |
| |
| public void processingInstruction(String aTarget, String aData) |
| { |
| try{ |
| m_xExportHandler.processingInstruction(aTarget, aData); |
| } |
| catch( com.sun.star.xml.sax.SAXException e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| public void setDocumentLocator (com.sun.star.xml.sax.XLocator xLocator ) |
| throws com.sun.star.xml.sax.SAXException |
| { |
| } |
| |
| |
| /* |
| * XSignatureCreationResultListener |
| */ |
| public void signatureCreated(int securityId, SecurityOperationStatus creationResult) |
| { |
| String message = new String(); |
| message += "A Signature is created:"; |
| message += "\nSecurity Id = "+securityId; |
| message += "\nCreation result = "+((creationResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail"); |
| |
| m_testTool.showMessage("Message from : SignatureCreator\n\n"+message+"\n "); |
| } |
| |
| /* |
| * XSignatureVerifyResultListener |
| */ |
| public void signatureVerified(int securityId, SecurityOperationStatus verifyResult) |
| { |
| String message = new String(); |
| message += "A Signature is verified:"; |
| message += "\nSecurity Id = "+securityId; |
| message += "\nVerify result = "+((verifyResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail"); |
| |
| m_testTool.showMessage("Message from : SignatureVerifier\n\n"+message+"\n "); |
| } |
| |
| /* |
| * XEncryptionResultListener |
| */ |
| public void encrypted(int securityId, SecurityOperationStatus encryptionResult) |
| { |
| String message = new String(); |
| message += "An EncryptedData is encrypted:"; |
| message += "\nSecurity Id = "+securityId; |
| message += "\nEncrypt result = "+((encryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail"); |
| |
| m_testTool.showMessage("Message from : Encryptor\n\n"+message+"\n "); |
| } |
| |
| /* |
| * XDecryptionResultListener methods |
| */ |
| public void decrypted(int securityId, SecurityOperationStatus decryptionResult) |
| { |
| String message = new String(); |
| message += "An EncryptedData is decrypted:"; |
| message += "\nSecurity Id = "+securityId; |
| message += "\nDecrypt result = "+((decryptionResult==SecurityOperationStatus.OPERATION_SUCCEEDED)?"Succeed":"Fail"); |
| |
| m_testTool.showMessage("Message from : Decryptor\n\n"+message+"\n "); |
| } |
| |
| /* |
| * XSAXEventKeeperStatusChangeListener methods |
| */ |
| public void blockingStatusChanged(boolean isBlocking) |
| { |
| m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+ |
| (isBlocking?"The SAX event stream is blocked.":"The SAX event stream is unblocked.")+ |
| "\n "); |
| |
| this.m_bIsBlocking = isBlocking; |
| } |
| |
| public void collectionStatusChanged(boolean isInsideCollectedElement) |
| { |
| m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+ |
| (isInsideCollectedElement?"Begin to buffer data ...":"End of data bufferring.")+ |
| "\n "); |
| |
| /* |
| this.m_bIsInsideCollectedElement = isInsideCollectedElement; |
| |
| if ( !m_bIsInsideCollectedElement && !m_bIsBlocking) |
| { |
| m_bSAXEventKeeperIncluded = false; |
| } |
| else |
| { |
| m_bSAXEventKeeperIncluded = true; |
| } |
| changeOutput(); |
| */ |
| } |
| |
| public void bufferStatusChanged(boolean isBufferEmpty) |
| { |
| m_testTool.showMessage("Message from : SAXEventKeeper\n\n"+ |
| (isBufferEmpty?"All bufferred data are released, the SAXEventKeeper is destroyed.":"buffer data appears.")+ |
| "\n "); |
| /* |
| if (isBufferEmpty) |
| { |
| m_xXMLDocumentWrapper = null; |
| m_xSAXEventKeeper = null; |
| m_bSAXEventKeeperIncluded = false; |
| changeOutput(); |
| } |
| */ |
| } |
| } |
| |