/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: xsecctl.cxx,v $ * $Revision: 1.11 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmlsecurity.hxx" #include #include #include #include #include #include #include #include #include #include #include namespace cssu = com::sun::star::uno; namespace cssl = com::sun::star::lang; namespace cssxc = com::sun::star::xml::crypto; namespace cssxs = com::sun::star::xml::sax; namespace cssxw = com::sun::star::xml::wrapper; namespace cssb = com::sun::star::beans; const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11; const sal_Int8 XML_MAXDIGITSCOUNT_DATETIME = 6; /* bridge component names */ #define XMLSIGNATURE_COMPONENT "com.sun.star.xml.crypto.XMLSignature" #define XMLDOCUMENTWRAPPER_COMPONENT "com.sun.star.xml.wrapper.XMLDocumentWrapper" /* xml security framework components */ #define SAXEVENTKEEPER_COMPONENT "com.sun.star.xml.crypto.sax.SAXEventKeeper" /* string for package protocol */ #define PACKAGEPROTOCOL "vnd.sun.star.Package:" XSecController::XSecController( ) :m_nNextSecurityId(1), m_bIsSAXEventKeeperConnected(false), m_nStatusOfSecurityComponents(UNINITIALIZED), m_bIsSAXEventKeeperSticky(false), m_pErrorMessage(NULL), m_pXSecParser(NULL) { } XSecController::~XSecController() { } /* * private methods */ /** convert string to number with optional min and max values */ sal_Bool XSecController::convertNumber( sal_Int32& rValue, const rtl::OUString& rString, sal_Int32 /*nMin*/, sal_Int32 /*nMax*/ ) { sal_Bool bNeg = sal_False; rValue = 0; sal_Int32 nPos = 0L; sal_Int32 nLen = rString.getLength(); // skip white space while( nPos < nLen && sal_Unicode(' ') == rString[nPos] ) nPos++; if( nPos < nLen && sal_Unicode('-') == rString[nPos] ) { bNeg = sal_True; nPos++; } // get number while( nPos < nLen && sal_Unicode('0') <= rString[nPos] && sal_Unicode('9') >= rString[nPos] ) { // TODO: check overflow! rValue *= 10; rValue += (rString[nPos] - sal_Unicode('0')); nPos++; } if( bNeg ) rValue *= -1; return nPos == nLen; } /** convert util::DateTime to ISO Date String */ void XSecController::convertDateTime( ::rtl::OUStringBuffer& rBuffer, const com::sun::star::util::DateTime& rDateTime ) { String aString( String::CreateFromInt32( rDateTime.Year ) ); aString += '-'; if( rDateTime.Month < 10 ) aString += '0'; aString += String::CreateFromInt32( rDateTime.Month ); aString += '-'; if( rDateTime.Day < 10 ) aString += '0'; aString += String::CreateFromInt32( rDateTime.Day ); if( rDateTime.Seconds != 0 || rDateTime.Minutes != 0 || rDateTime.Hours != 0 ) { aString += 'T'; if( rDateTime.Hours < 10 ) aString += '0'; aString += String::CreateFromInt32( rDateTime.Hours ); aString += ':'; if( rDateTime.Minutes < 10 ) aString += '0'; aString += String::CreateFromInt32( rDateTime.Minutes ); aString += ':'; if( rDateTime.Seconds < 10 ) aString += '0'; aString += String::CreateFromInt32( rDateTime.Seconds ); if ( rDateTime.HundredthSeconds > 0) { aString += ','; if (rDateTime.HundredthSeconds < 10) aString += '0'; aString += String::CreateFromInt32( rDateTime.HundredthSeconds ); } } rBuffer.append( aString ); } /** convert ISO Date String to util::DateTime */ sal_Bool XSecController::convertDateTime( com::sun::star::util::DateTime& rDateTime, const ::rtl::OUString& rString ) { sal_Bool bSuccess = sal_True; rtl::OUString aDateStr, aTimeStr, sHundredth; sal_Int32 nPos = rString.indexOf( (sal_Unicode) 'T' ); sal_Int32 nPos2 = rString.indexOf( (sal_Unicode) ',' ); if ( nPos >= 0 ) { aDateStr = rString.copy( 0, nPos ); if ( nPos2 >= 0 ) { aTimeStr = rString.copy( nPos + 1, nPos2 - nPos - 1 ); //Get the fraction of a second with the accuracy of one hundreds second. //The fraction part of the date could have different accuracies. To calculate //the count of a hundredth units one could form a fractional number by appending //the value of the time string to 0. Then multiply it by 100 and use only the whole number. //For example: 5:27:46,1 -> 0,1 * 100 = 10 //5:27:46,01 -> 0,01 * 100 = 1 //5:27:46,001 -> 0,001 * 100 = 0 //Due to the inaccuracy of floating point numbers the result may not be the same on different //platforms. We had the case where we had a value of 24 hundredth of second, which converted to //23 on Linux and 24 on Solaris and Windows. //we only support a hundredth second //make ,1 -> 10 ,01 -> 1 ,001 -> only use first two diggits sHundredth = rString.copy(nPos2 + 1); sal_Int32 len = sHundredth.getLength(); if (len == 1) sHundredth += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0")); if (len > 2) sHundredth = sHundredth.copy(0, 2); } else { aTimeStr = rString.copy(nPos + 1); sHundredth = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0")); } } else aDateStr = rString; // no separator: only date part sal_Int32 nYear = 1899; sal_Int32 nMonth = 12; sal_Int32 nDay = 30; sal_Int32 nHour = 0; sal_Int32 nMin = 0; sal_Int32 nSec = 0; const sal_Unicode* pStr = aDateStr.getStr(); sal_Int32 nDateTokens = 1; while ( *pStr ) { if ( *pStr == '-' ) nDateTokens++; pStr++; } if ( nDateTokens > 3 || aDateStr.getLength() == 0 ) bSuccess = sal_False; else { sal_Int32 n = 0; if ( !convertNumber( nYear, aDateStr.getToken( 0, '-', n ), 0, 9999 ) ) bSuccess = sal_False; if ( nDateTokens >= 2 ) if ( !convertNumber( nMonth, aDateStr.getToken( 0, '-', n ), 0, 12 ) ) bSuccess = sal_False; if ( nDateTokens >= 3 ) if ( !convertNumber( nDay, aDateStr.getToken( 0, '-', n ), 0, 31 ) ) bSuccess = sal_False; } if ( aTimeStr.getLength() > 0 ) // time is optional { pStr = aTimeStr.getStr(); sal_Int32 nTimeTokens = 1; while ( *pStr ) { if ( *pStr == ':' ) nTimeTokens++; pStr++; } if ( nTimeTokens > 3 ) bSuccess = sal_False; else { sal_Int32 n = 0; if ( !convertNumber( nHour, aTimeStr.getToken( 0, ':', n ), 0, 23 ) ) bSuccess = sal_False; if ( nTimeTokens >= 2 ) if ( !convertNumber( nMin, aTimeStr.getToken( 0, ':', n ), 0, 59 ) ) bSuccess = sal_False; if ( nTimeTokens >= 3 ) if ( !convertNumber( nSec, aTimeStr.getToken( 0, ':', n ), 0, 59 ) ) bSuccess = sal_False; } } if (bSuccess) { rDateTime.Year = (sal_uInt16)nYear; rDateTime.Month = (sal_uInt16)nMonth; rDateTime.Day = (sal_uInt16)nDay; rDateTime.Hours = (sal_uInt16)nHour; rDateTime.Minutes = (sal_uInt16)nMin; rDateTime.Seconds = (sal_uInt16)nSec; // rDateTime.HundredthSeconds = sDoubleStr.toDouble() * 100; rDateTime.HundredthSeconds = static_cast(sHundredth.toInt32()); } return bSuccess; } int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const /****** XSecController/findSignatureInfor ************************************* * * NAME * findSignatureInfor -- find SignatureInformation struct for a particular * signature * * SYNOPSIS * index = findSignatureInfor( nSecurityId ); * * FUNCTION * see NAME. * * INPUTS * nSecurityId - the signature's id * * RESULT * index - the index of the signature, or -1 when no such signature * existing * * HISTORY * 08.05.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { int i; int size = m_vInternalSignatureInformations.size(); for (i=0; i( mxMSF->createInstance( sXMLSignature ), cssu::UNO_QUERY ); bool bSuccess = (0!=m_xXMLSignature.is()); if ( bSuccess ) /* * XMLSignature created successfully. */ { m_xXMLDocumentWrapper = cssu::Reference< cssxw::XXMLDocumentWrapper >( mxMSF->createInstance( sXMLDocument ), cssu::UNO_QUERY ); } bSuccess &= (0!=m_xXMLDocumentWrapper.is()); if ( bSuccess ) /* * XMLDocumentWrapper created successfully. */ { m_xSAXEventKeeper = cssu::Reference< cssxc::sax::XSecuritySAXEventKeeper >( mxMSF->createInstance( sSAXEventKeeper ), cssu::UNO_QUERY ); } bSuccess &= (0!=m_xSAXEventKeeper.is()); if (bSuccess) /* * SAXEventKeeper created successfully. */ { cssu::Reference< cssl::XInitialization > xInitialization(m_xSAXEventKeeper, cssu::UNO_QUERY); cssu::Sequence arg(1); arg[0] = cssu::makeAny(m_xXMLDocumentWrapper); xInitialization->initialize(arg); cssu::Reference xSAXEventKeeperStatusChangeBroadcaster(m_xSAXEventKeeper, cssu::UNO_QUERY); cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener > xStatusChangeListener = this; xSAXEventKeeperStatusChangeBroadcaster ->addSAXEventKeeperStatusChangeListener( xStatusChangeListener ); m_nStatusOfSecurityComponents = INITIALIZED; } } bool XSecController::chainOn( bool bRetrievingLastEvent ) /****** XSecController/chainOn ************************************************ * * NAME * chainOn -- tyies to connect the SAXEventKeeper with the SAX chain. * * SYNOPSIS * bJustChainingOn = chainOn( bRetrievingLastEvent ); * * FUNCTION * First, checks whether the SAXEventKeeper is on the SAX chain. If not, * creates xml security components, and chains the SAXEventKeeper into * the SAX chain. * Before being chained in, the SAXEventKeeper needs to receive all * missed key SAX events, which can promise the DOM tree bufferred by the * SAXEventKeeper has the same structure with the original document. * * INPUTS * bRetrievingLastEvent - whether to retrieve the last key SAX event from * the ElementStackKeeper. * * RESULT * bJustChainingOn - whether the SAXEventKeeper is just chained into the * SAX chain. * * NOTES * Sometimes, the last key SAX event can't be transferred to the * SAXEventKeeper together. * For instance, at the time an referenced element is detected, the * startElement event has already been reserved by the ElementStackKeeper. * Meanwhile, an ElementCollector needs to be created before the * SAXEventKeeper receives that startElement event. * So for the SAXEventKeeper, it needs to receive all missed key SAX * events except that startElement event, then adds a new * ElementCollector, then receives that startElement event. * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { bool rc = false; if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected) { if ( m_nStatusOfSecurityComponents == UNINITIALIZED ) { createXSecComponent(); } if ( m_nStatusOfSecurityComponents == INITIALIZED ) /* * if all security components are ready, chains on the SAXEventKeeper */ { /* * disconnect the SAXEventKeeper with its current output handler, * to make sure no SAX event is forwarded during the connecting * phase. */ m_xSAXEventKeeper->setNextHandler( NULL ); cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY); /* * connects the previous document handler on the SAX chain */ if ( m_xPreviousNodeOnSAXChain.is() ) { if ( m_bIsPreviousNodeInitializable ) { cssu::Reference< cssl::XInitialization > xInitialization (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY); cssu::Sequence aArgs( 1 ); aArgs[0] <<= xSEKHandler; xInitialization->initialize(aArgs); } else { cssu::Reference< cssxs::XParser > xParser (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY); xParser->setDocumentHandler( xSEKHandler ); } } /* * get missed key SAX events */ if (m_xElementStackKeeper.is()) { m_xElementStackKeeper->retrieve(xSEKHandler, bRetrievingLastEvent); /* * now the ElementStackKeeper can stop its work, because the * SAXEventKeeper is on the SAX chain, no SAX events will be * missed. */ m_xElementStackKeeper->stop(); } /* * connects the next document handler on the SAX chain */ m_xSAXEventKeeper->setNextHandler( m_xNextNodeOnSAXChain ); m_bIsSAXEventKeeperConnected = true; rc = true; } } return rc; } void XSecController::chainOff() /****** XSecController/chainOff *********************************************** * * NAME * chainOff -- disconnects the SAXEventKeeper from the SAX chain. * * SYNOPSIS * chainOff( ); * * FUNCTION * See NAME. * * INPUTS * empty * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { if (!m_bIsSAXEventKeeperSticky ) { if (m_bIsSAXEventKeeperConnected) { m_xSAXEventKeeper->setNextHandler( NULL ); if ( m_xPreviousNodeOnSAXChain.is() ) { if ( m_bIsPreviousNodeInitializable ) { cssu::Reference< cssl::XInitialization > xInitialization (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY); cssu::Sequence aArgs( 1 ); aArgs[0] <<= m_xNextNodeOnSAXChain; xInitialization->initialize(aArgs); } else { cssu::Reference< cssxs::XParser > xParser(m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY); xParser->setDocumentHandler( m_xNextNodeOnSAXChain ); } } if (m_xElementStackKeeper.is()) { /* * start the ElementStackKeeper to reserve any possible * missed key SAX events */ m_xElementStackKeeper->start(); } m_bIsSAXEventKeeperConnected = false; } } } void XSecController::checkChainingStatus() /****** XSecController/checkChainingStatus ************************************ * * NAME * checkChainingStatus -- connects or disconnects the SAXEventKeeper * according to the current situation. * * SYNOPSIS * checkChainingStatus( ); * * FUNCTION * The SAXEventKeeper is chained into the SAX chain, when: * 1. some element is being collected, or * 2. the SAX event stream is blocking. * Otherwise, chain off the SAXEventKeeper. * * INPUTS * empty * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { if ( m_bIsCollectingElement || m_bIsBlocking ) { chainOn(true); } else { chainOff(); } } void XSecController::initializeSAXChain() /****** XSecController/initializeSAXChain ************************************* * * NAME * initializeSAXChain -- initializes the SAX chain according to the * current setting. * * SYNOPSIS * initializeSAXChain( ); * * FUNCTION * Initializes the SAX chain, if the SAXEventKeeper is asked to be always * on the SAX chain, chains it on. Otherwise, starts the * ElementStackKeeper to reserve key SAX events. * * INPUTS * empty * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { m_bIsSAXEventKeeperConnected = false; m_bIsCollectingElement = false; m_bIsBlocking = false; if (m_xElementStackKeeper.is()) { /* * starts the ElementStackKeeper */ m_xElementStackKeeper->start(); } chainOff(); } cssu::Reference< com::sun::star::io::XInputStream > XSecController::getObjectInputStream( const rtl::OUString& objectURL ) /****** XSecController/getObjectInputStream ************************************ * * NAME * getObjectInputStream -- get a XInputStream interface from a SvStorage * * SYNOPSIS * xInputStream = getObjectInputStream( objectURL ); * * FUNCTION * See NAME. * * INPUTS * objectURL - the object uri * * RESULT * xInputStream - the XInputStream interface * * HISTORY * 15.04.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream; DBG_ASSERT( m_xUriBinding.is(), "Need XUriBinding!" ); xObjectInputStream = m_xUriBinding->getUriBinding(objectURL); return xObjectInputStream; } #if 0 sal_Int32 XSecController::getFastPropertyIndex(sal_Int32 nHandle) const /****** XSecController/getFastPropertyIndex *********************************** * * NAME * getFastPropertyIndex -- gets the index of a particular fast property * * SYNOPSIS * nIndex = getFastPropertyIndex( nHandle ); * * FUNCTION * See NAME. * * INPUTS * nHandle - the key for the fast property * * RESULT * nIndex - the index of the fast property, or -1 * if the key is not found. * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { std::vector< sal_Int32 >::const_iterator ii = m_vFastPropertyIndexs.begin(); sal_Int32 nIndex = 0; bool bFound = false; for( ; ii != m_vFastPropertyIndexs.end(); ++ii,++nIndex ) { if ( nHandle == (*ii)) { bFound = true; break; } } if (!bFound) { nIndex = -1; } return nIndex; } #endif /* * public methods */ void XSecController::setFactory( const cssu::Reference& rxMSF) /****** XSecController/setFactory ********************************************* * * NAME * setFactory -- configures the service factory component. * * SYNOPSIS * setFactory( rxMSF ); * * FUNCTION * See NAME. * * INPUTS * rxMSF - the service factory component * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { mxMSF = rxMSF; } #if 0 void XSecController::setSignatureCreationResultListener( const cssu::Reference< cssxc::sax::XSignatureCreationResultListener >& xSignatureCreationResultListener) { m_xSignatureCreationResultListener = xSignatureCreationResultListener; } void XSecController::setSignatureVerifyResultListener( const cssu::Reference< cssxc::sax::XSignatureVerifyResultListener >& xSignatureVerifyResultListener) { m_xSignatureVerifyResultListener = xSignatureVerifyResultListener; } #endif sal_Int32 XSecController::getNewSecurityId( ) { sal_Int32 nId = m_nNextSecurityId; m_nNextSecurityId++; return nId; } void XSecController::startMission( const cssu::Reference< cssxc::XUriBinding >& xUriBinding, const cssu::Reference< cssxc::XXMLSecurityContext >& xSecurityContext ) /****** XSecController/startMission ******************************************* * * NAME * startMission -- starts a new security mission. * * SYNOPSIS * startMission( xUriBinding, xSecurityContect ); * * FUNCTION * get ready for a new mission. * * INPUTS * xUriBinding - the Uri binding that provide maps between uris and * XInputStreams * xSecurityContext - the security context component which can provide * cryptoken * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { m_xUriBinding = xUriBinding; m_nStatusOfSecurityComponents = UNINITIALIZED; m_xSecurityContext = xSecurityContext; m_pErrorMessage = NULL; m_vInternalSignatureInformations.clear(); m_bVerifyCurrentSignature = false; } void XSecController::setSAXChainConnector( const cssu::Reference< cssl::XInitialization >& xInitialization, const cssu::Reference< cssxs::XDocumentHandler >& xDocumentHandler, const cssu::Reference< cssxc::sax::XElementStackKeeper >& xElementStackKeeper) /****** XSecController/setSAXChainConnector *********************************** * * NAME * setSAXChainConnector -- configures the components which will * collaborate with the SAXEventKeeper on the SAX chain. * * SYNOPSIS * setSAXChainConnector( xInitialization, * xDocumentHandler, * xElementStackKeeper ); * * FUNCTION * See NAME. * * INPUTS * xInitialization - the previous node on the SAX chain * xDocumentHandler - the next node on the SAX chain * xElementStackKeeper - the ElementStackKeeper component which reserves * missed key SAX events for the SAXEventKeeper * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { m_bIsPreviousNodeInitializable = true; m_xPreviousNodeOnSAXChain = xInitialization; m_xNextNodeOnSAXChain = xDocumentHandler; m_xElementStackKeeper = xElementStackKeeper; initializeSAXChain( ); } void XSecController::setSAXChainConnector( const cssu::Reference< cssxs::XParser >& xParser, const cssu::Reference< cssxs::XDocumentHandler >& xDocumentHandler, const cssu::Reference< cssxc::sax::XElementStackKeeper >& xElementStackKeeper) /****** XSecController/setSAXChainConnector *********************************** * * NAME * setSAXChainConnector -- configures the components which will * collaborate with the SAXEventKeeper on the SAX chain. * * SYNOPSIS * setSAXChainConnector( xParser, xDocumentHandler, xElementStackKeeper ); * * FUNCTION * See NAME. * * INPUTS * xParser - the previous node on the SAX chain * xDocumentHandler - the next node on the SAX chain * xElementStackKeeper -the ElementStackKeeper component which reserves * missed key SAX events for the SAXEventKeeper * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { m_bIsPreviousNodeInitializable = false; m_xPreviousNodeOnSAXChain = xParser; m_xNextNodeOnSAXChain = xDocumentHandler; m_xElementStackKeeper = xElementStackKeeper; initializeSAXChain( ); } void XSecController::clearSAXChainConnector() /****** XSecController/clearSAXChainConnector ********************************* * * NAME * clearSAXChainConnector -- resets the collaborating components. * * SYNOPSIS * clearSAXChainConnector( ); * * FUNCTION * See NAME. * * INPUTS * empty * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { /* * before reseting, if the ElementStackKeeper has kept something, then * those kept key SAX events must be transferred to the SAXEventKeeper * first. This is to promise the next node to the SAXEventKeeper on the * SAX chain always receives a complete document. */ if (m_xElementStackKeeper.is() && m_xSAXEventKeeper.is()) { cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY); m_xElementStackKeeper->retrieve(xSEKHandler, sal_True); } chainOff(); m_xPreviousNodeOnSAXChain = NULL; m_xNextNodeOnSAXChain = NULL; m_xElementStackKeeper = NULL; } void XSecController::endMission() /****** XSecController/endMission ********************************************* * * NAME * endMission -- forces to end all missions * * SYNOPSIS * endMission( ); * * FUNCTION * Deletes all signature information and forces all missions to an end. * * INPUTS * empty * * RESULT * empty * * HISTORY * 05.01.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { sal_Int32 size = m_vInternalSignatureInformations.size(); for (int i=0; i xMissionTaker ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, cssu::UNO_QUERY ); /* * askes the SignatureCreator/SignatureVerifier to release * all resouces it uses. */ xMissionTaker->endMission(); } } m_xUriBinding = NULL; m_xSecurityContext = NULL; /* * free the status change listener reference to this object */ if (m_xSAXEventKeeper.is()) { cssu::Reference xSAXEventKeeperStatusChangeBroadcaster(m_xSAXEventKeeper, cssu::UNO_QUERY); xSAXEventKeeperStatusChangeBroadcaster ->addSAXEventKeeperStatusChangeListener( NULL ); } } const char* XSecController::getErrorMessage() /****** XSecController/getErrorMessage **************************************** * * NAME * getErrorMessage -- get the last error message * * SYNOPSIS * pErrorMessage = getErrorMessage( ); * * FUNCTION * see NAME. * * INPUTS * empty * * RESULT * empty * * HISTORY * 22.04.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { return m_pErrorMessage; } void XSecController::exportSignature( const cssu::Reference& xDocumentHandler, const SignatureInformation& signatureInfo ) /****** XSecController/exportSignature **************************************** * * NAME * exportSignature -- export a signature structure to an XDocumentHandler * * SYNOPSIS * exportSignature( xDocumentHandler, signatureInfo); * * FUNCTION * see NAME. * * INPUTS * xDocumentHandler - the document handler to receive the signature * signatureInfo - signature to be exported * * RESULT * empty * * HISTORY * 26.05.2004 - implemented * * AUTHOR * Michael Mi * Email: michael.mi@sun.com ******************************************************************************/ { /* * defines all element tags in Signature element. */ rtl::OUString tag_Signature(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNATURE)); rtl::OUString tag_SignedInfo(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNEDINFO)); rtl::OUString tag_CanonicalizationMethod(RTL_CONSTASCII_USTRINGPARAM(TAG_CANONICALIZATIONMETHOD)); rtl::OUString tag_SignatureMethod(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNATUREMETHOD)); rtl::OUString tag_Reference(RTL_CONSTASCII_USTRINGPARAM(TAG_REFERENCE)); rtl::OUString tag_Transforms(RTL_CONSTASCII_USTRINGPARAM(TAG_TRANSFORMS)); rtl::OUString tag_Transform(RTL_CONSTASCII_USTRINGPARAM(TAG_TRANSFORM)); rtl::OUString tag_DigestMethod(RTL_CONSTASCII_USTRINGPARAM(TAG_DIGESTMETHOD)); rtl::OUString tag_DigestValue(RTL_CONSTASCII_USTRINGPARAM(TAG_DIGESTVALUE)); rtl::OUString tag_SignatureValue(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNATUREVALUE)); rtl::OUString tag_KeyInfo(RTL_CONSTASCII_USTRINGPARAM(TAG_KEYINFO)); rtl::OUString tag_X509Data(RTL_CONSTASCII_USTRINGPARAM(TAG_X509DATA)); rtl::OUString tag_X509IssuerSerial(RTL_CONSTASCII_USTRINGPARAM(TAG_X509ISSUERSERIAL)); rtl::OUString tag_X509IssuerName(RTL_CONSTASCII_USTRINGPARAM(TAG_X509ISSUERNAME)); rtl::OUString tag_X509SerialNumber(RTL_CONSTASCII_USTRINGPARAM(TAG_X509SERIALNUMBER)); rtl::OUString tag_X509Certificate(RTL_CONSTASCII_USTRINGPARAM(TAG_X509CERTIFICATE)); rtl::OUString tag_Object(RTL_CONSTASCII_USTRINGPARAM(TAG_OBJECT)); rtl::OUString tag_SignatureProperties(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNATUREPROPERTIES)); rtl::OUString tag_SignatureProperty(RTL_CONSTASCII_USTRINGPARAM(TAG_SIGNATUREPROPERTY)); rtl::OUString tag_Date(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)); #if 0 rtl::OUString tag_Timestamp(RTL_CONSTASCII_USTRINGPARAM(TAG_TIMESTAMP)); rtl::OUString tag_Date(RTL_CONSTASCII_USTRINGPARAM(TAG_DATE)); rtl::OUString tag_Time(RTL_CONSTASCII_USTRINGPARAM(TAG_TIME)); #endif const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors; SvXMLAttributeList *pAttributeList; /* * Write Signature element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_XMLDSIG))); if (signatureInfo.ouSignatureId.getLength()>0) { pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ID)), rtl::OUString(signatureInfo.ouSignatureId)); } xDocumentHandler->startElement( tag_Signature, cssu::Reference< cssxs::XAttributeList > (pAttributeList)); { /* Write SignedInfo element */ xDocumentHandler->startElement( tag_SignedInfo, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write CanonicalizationMethod element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ALGORITHM)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ALGO_C14N))); xDocumentHandler->startElement( tag_CanonicalizationMethod, cssu::Reference< cssxs::XAttributeList > (pAttributeList) ); xDocumentHandler->endElement( tag_CanonicalizationMethod ); /* Write SignatureMethod element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ALGORITHM)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ALGO_RSASHA1))); xDocumentHandler->startElement( tag_SignatureMethod, cssu::Reference< cssxs::XAttributeList > (pAttributeList) ); xDocumentHandler->endElement( tag_SignatureMethod ); /* Write Reference element */ int j; int refNum = vReferenceInfors.size(); for(j=0; jAddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_URI)), refInfor.ouURI); } else /* * same-document reference */ { pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_URI)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_FRAGMENT))+refInfor.ouURI); } xDocumentHandler->startElement( tag_Reference, cssu::Reference< cssxs::XAttributeList > (pAttributeList) ); { /* Write Transforms element */ if (refInfor.nType == TYPE_XMLSTREAM_REFERENCE) /* * xml stream, so c14n transform is needed */ { xDocumentHandler->startElement( tag_Transforms, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ALGORITHM)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ALGO_C14N))); xDocumentHandler->startElement( tag_Transform, cssu::Reference< cssxs::XAttributeList > (pAttributeList) ); xDocumentHandler->endElement( tag_Transform ); } xDocumentHandler->endElement( tag_Transforms ); } /* Write DigestMethod element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ALGORITHM)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ALGO_XMLDSIGSHA1))); xDocumentHandler->startElement( tag_DigestMethod, cssu::Reference< cssxs::XAttributeList > (pAttributeList) ); xDocumentHandler->endElement( tag_DigestMethod ); /* Write DigestValue element */ xDocumentHandler->startElement( tag_DigestValue, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); xDocumentHandler->characters( refInfor.ouDigestValue ); xDocumentHandler->endElement( tag_DigestValue ); } xDocumentHandler->endElement( tag_Reference ); } } xDocumentHandler->endElement( tag_SignedInfo ); /* Write SignatureValue element */ xDocumentHandler->startElement( tag_SignatureValue, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); xDocumentHandler->characters( signatureInfo.ouSignatureValue ); xDocumentHandler->endElement( tag_SignatureValue ); /* Write KeyInfo element */ xDocumentHandler->startElement( tag_KeyInfo, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write X509Data element */ xDocumentHandler->startElement( tag_X509Data, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write X509IssuerSerial element */ xDocumentHandler->startElement( tag_X509IssuerSerial, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write X509IssuerName element */ xDocumentHandler->startElement( tag_X509IssuerName, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); xDocumentHandler->characters( signatureInfo.ouX509IssuerName ); xDocumentHandler->endElement( tag_X509IssuerName ); /* Write X509SerialNumber element */ xDocumentHandler->startElement( tag_X509SerialNumber, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); xDocumentHandler->characters( signatureInfo.ouX509SerialNumber ); xDocumentHandler->endElement( tag_X509SerialNumber ); } xDocumentHandler->endElement( tag_X509IssuerSerial ); /* Write X509Certificate element */ if (signatureInfo.ouX509Certificate.getLength()>0) { xDocumentHandler->startElement( tag_X509Certificate, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); xDocumentHandler->characters( signatureInfo.ouX509Certificate ); xDocumentHandler->endElement( tag_X509Certificate ); } } xDocumentHandler->endElement( tag_X509Data ); } xDocumentHandler->endElement( tag_KeyInfo ); /* Write Object element */ xDocumentHandler->startElement( tag_Object, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write SignatureProperties element */ xDocumentHandler->startElement( tag_SignatureProperties, cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList())); { /* Write SignatureProperty element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_ID)), signatureInfo.ouPropertyId); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_TARGET)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_FRAGMENT))+signatureInfo.ouSignatureId); xDocumentHandler->startElement( tag_SignatureProperty, cssu::Reference< cssxs::XAttributeList > (pAttributeList)); { /* Write timestamp element */ pAttributeList = new SvXMLAttributeList(); pAttributeList->AddAttribute( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS)) +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":")) +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC)), rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DC))); xDocumentHandler->startElement( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC)) +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":")) +tag_Date, cssu::Reference< cssxs::XAttributeList > (pAttributeList)); ::rtl::OUStringBuffer buffer; //If the xml signature was already contained in the document, //then we use the original date and time string, rather then the //converted one. When the original string is converted to the DateTime //structure then information may be lost because it only holds a fractional //of a second with a accuracy of one hundredth of second. If the string contains //milli seconds (document was signed by an application other than OOo) //and the converted time is written back, then the string looks different //and the signature is broken. if (signatureInfo.ouDateTime.getLength() > 0) buffer = signatureInfo.ouDateTime; else convertDateTime( buffer, signatureInfo.stDateTime ); xDocumentHandler->characters( buffer.makeStringAndClear() ); xDocumentHandler->endElement( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NSTAG_DC)) +rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(":")) +tag_Date); } xDocumentHandler->endElement( tag_SignatureProperty ); } xDocumentHandler->endElement( tag_SignatureProperties ); } xDocumentHandler->endElement( tag_Object ); } xDocumentHandler->endElement( tag_Signature ); } SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const { SignatureInformation aInf( 0 ); int nIndex = findSignatureInfor(nSecurityId); DBG_ASSERT( nIndex != -1, "getSignatureInformation - SecurityId is invalid!" ); if ( nIndex != -1) { aInf = m_vInternalSignatureInformations[nIndex].signatureInfor; } return aInf; } SignatureInformations XSecController::getSignatureInformations() const { SignatureInformations vInfors; int sigNum = m_vInternalSignatureInformations.size(); for (int i=0; i TRUE": "Blocking Status => FALSE")), rtl::OUString::createFromAscii("SAXEventKeeper Status")); */ this->m_bIsBlocking = isBlocking; checkChainingStatus(); } void SAL_CALL XSecController::collectionStatusChanged( sal_Bool isInsideCollectedElement ) throw (cssu::RuntimeException) { /* showMessageBox( rtl::OUString::createFromAscii((isInsideCollectedElement? "Collection Status => TRUE": "Collection Status => FALSE")), rtl::OUString::createFromAscii("SAXEventKeeper Status")); */ this->m_bIsCollectingElement = isInsideCollectedElement; checkChainingStatus(); } void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/) throw (cssu::RuntimeException) { /* showMessageBox( rtl::OUString::createFromAscii((isBufferEmpty? "Buffer Empty => TRUE": "Buffer Empty => FALSE")), rtl::OUString::createFromAscii("SAXEventKeeper Status")); */ } /* * XSignatureCreationResultListener */ void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult ) throw (com::sun::star::uno::RuntimeException) { int index = findSignatureInfor(securityId); DBG_ASSERT( index != -1, "Signature Not Found!" ); SignatureInformation& signatureInfor = m_vInternalSignatureInformations[index].signatureInfor; /* if (nResult == cssxc::sax::SignatureCreationResult_CREATIONSUCCEED) { signatureInfor.nStatus = STATUS_CREATION_SUCCEED; } else { signatureInfor.nStatus = STATUS_CREATION_FAIL; } */ signatureInfor.nStatus = nResult; } /* * XSignatureVerifyResultListener */ void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult ) throw (com::sun::star::uno::RuntimeException) { int index = findSignatureInfor(securityId); DBG_ASSERT( index != -1, "Signature Not Found!" ); SignatureInformation& signatureInfor = m_vInternalSignatureInformations[index].signatureInfor; /* if (nResult == cssxc::sax::SignatureVerifyResult_VERIFYSUCCEED) { signatureInfor.nStatus = STATUS_VERIFY_SUCCEED; } else { signatureInfor.nStatus = STATUS_VERIFY_FAIL; } */ signatureInfor.nStatus = nResult; }