| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_xmlsecurity.hxx" |
| |
| #include <xmlsecurity/xmlsignaturehelper.hxx> |
| #include <xmlsecurity/documentsignaturehelper.hxx> |
| #include <xsecctl.hxx> |
| |
| #include <xmlsignaturehelper2.hxx> |
| |
| #include <tools/stream.hxx> |
| #include <tools/debug.hxx> |
| |
| #include <xmloff/attrlist.hxx> |
| |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/io/XInputStream.hpp> |
| #include <com/sun/star/io/XActiveDataSource.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/security/SerialNumberAdapter.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| |
| #include <tools/date.hxx> |
| #include <tools/time.hxx> |
| |
| //MM : search for the default profile |
| //#include <unotools/streamhelper.hxx> |
| //MM : end |
| |
| /* SEInitializer component */ |
| #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer" |
| |
| #define TAG_DOCUMENTSIGNATURES "document-signatures" |
| #define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures" |
| #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0" |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| |
| XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx) |
| : mxCtx(rxCtx), mbODFPre1_2(false) |
| { |
| mpXSecController = new XSecController(rxCtx); |
| mxSecurityController = mpXSecController; |
| mbError = false; |
| } |
| |
| XMLSignatureHelper::~XMLSignatureHelper() |
| { |
| } |
| |
| bool XMLSignatureHelper::Init() |
| { |
| DBG_ASSERT( !mxSEInitializer.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" ); |
| DBG_ASSERT( !mxSecurityContext.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" ); |
| |
| ImplCreateSEInitializer(); |
| |
| if ( mxSEInitializer.is() ) |
| mxSecurityContext = mxSEInitializer->createSecurityContext( ::rtl::OUString() ); |
| |
| return mxSecurityContext.is(); |
| } |
| |
| void XMLSignatureHelper::ImplCreateSEInitializer() |
| { |
| rtl::OUString sSEInitializer(rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT )); |
| uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); |
| mxSEInitializer = uno::Reference< com::sun::star::xml::crypto::XSEInitializer > ( |
| xMCF->createInstanceWithContext( sSEInitializer, mxCtx ), uno::UNO_QUERY ); |
| } |
| |
| void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding >& rxUriBinding ) |
| { |
| mxUriBinding = rxUriBinding; |
| } |
| |
| com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > XMLSignatureHelper::GetUriBinding() const |
| { |
| return mxUriBinding; |
| } |
| |
| void XMLSignatureHelper::SetStorage( |
| const Reference < css::embed::XStorage >& rxStorage, |
| ::rtl::OUString sODFVersion) |
| { |
| DBG_ASSERT( !mxUriBinding.is(), "SetStorage - UriBinding already set!" ); |
| mxUriBinding = new UriBindingHelper( rxStorage ); |
| DBG_ASSERT(rxStorage.is(), "SetStorage - empty storage!"); |
| mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion); |
| } |
| |
| |
| void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link& rLink ) |
| { |
| maStartVerifySignatureHdl = rLink; |
| } |
| |
| |
| void XMLSignatureHelper::StartMission() |
| { |
| if ( !mxUriBinding.is() ) |
| mxUriBinding = new UriBindingHelper(); |
| |
| mpXSecController->startMission( mxUriBinding, mxSecurityContext ); |
| } |
| |
| void XMLSignatureHelper::EndMission() |
| { |
| mpXSecController->endMission(); |
| } |
| |
| sal_Int32 XMLSignatureHelper::GetNewSecurityId() |
| { |
| return mpXSecController->getNewSecurityId(); |
| } |
| |
| void XMLSignatureHelper::SetX509Certificate( |
| sal_Int32 nSecurityId, |
| const rtl::OUString& ouX509IssuerName, |
| const rtl::OUString& ouX509SerialNumber, |
| const rtl::OUString& ouX509Cert) |
| { |
| mpXSecController->setX509Certificate( |
| nSecurityId, |
| ouX509IssuerName, |
| ouX509SerialNumber, |
| ouX509Cert); |
| } |
| |
| void XMLSignatureHelper::SetX509Certificate( |
| sal_Int32 nSecurityId, |
| sal_Int32 nSecurityEnvironmentIndex, |
| const rtl::OUString& ouX509IssuerName, |
| const rtl::OUString& ouX509SerialNumber, |
| const rtl::OUString& ouX509Cert) |
| { |
| mpXSecController->setX509Certificate( |
| nSecurityId, |
| nSecurityEnvironmentIndex, |
| ouX509IssuerName, |
| ouX509SerialNumber, |
| ouX509Cert); |
| } |
| |
| void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const Time& rTime ) |
| { |
| /* |
| rtl::OUString aDate = String::CreateFromInt32( rDate.GetDate() ); |
| rtl::OUString aTime = String::CreateFromInt32( rTime.GetTime() ); |
| mpXSecController->setDateTime( nSecurityId, aDate, aTime ); |
| */ |
| ::com::sun::star::util::DateTime stDateTime; |
| stDateTime.HundredthSeconds = (::sal_uInt16)rTime.Get100Sec(); |
| stDateTime.Seconds = (::sal_uInt16)rTime.GetSec(); |
| stDateTime.Minutes = (::sal_uInt16)rTime.GetMin(); |
| stDateTime.Hours = (::sal_uInt16)rTime.GetHour(); |
| stDateTime.Day = (::sal_uInt16)rDate.GetDay(); |
| stDateTime.Month = (::sal_uInt16)rDate.GetMonth(); |
| stDateTime.Year = (::sal_uInt16)rDate.GetYear(); |
| mpXSecController->setDate( nSecurityId, stDateTime ); |
| } |
| |
| void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool bBinary ) |
| { |
| mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary ); |
| } |
| |
| |
| uno::Reference<xml::sax::XDocumentHandler> XMLSignatureHelper::CreateDocumentHandlerWithHeader( |
| const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream ) |
| { |
| /* |
| * get SAX writer component |
| */ |
| uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); |
| uno::Reference< io::XActiveDataSource > xSaxWriter( |
| xMCF->createInstanceWithContext(rtl::OUString::createFromAscii( |
| "com.sun.star.xml.sax.Writer"), mxCtx ), uno::UNO_QUERY ); |
| |
| DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" ); |
| |
| /* |
| * connect XML writer to output stream |
| */ |
| xSaxWriter->setOutputStream( xOutputStream ); |
| |
| /* |
| * prepare document handler |
| */ |
| uno::Reference<xml::sax::XDocumentHandler> |
| xDocHandler( xSaxWriter,uno::UNO_QUERY); |
| |
| /* |
| * write the xml context for signatures |
| */ |
| rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES)); |
| |
| SvXMLAttributeList *pAttributeList = new SvXMLAttributeList(); |
| rtl::OUString sNamespace; |
| if (mbODFPre1_2) |
| sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES)); |
| else |
| sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES_ODF_1_2)); |
| |
| pAttributeList->AddAttribute( |
| rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS)), |
| sNamespace); |
| |
| xDocHandler->startDocument(); |
| xDocHandler->startElement( |
| tag_AllSignatures, |
| uno::Reference< com::sun::star::xml::sax::XAttributeList > (pAttributeList)); |
| |
| return xDocHandler; |
| } |
| |
| void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler ) |
| { |
| rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES)); |
| xDocumentHandler->endElement( tag_AllSignatures ); |
| xDocumentHandler->endDocument(); |
| } |
| |
| void XMLSignatureHelper::ExportSignature( |
| const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler, |
| const SignatureInformation& signatureInfo ) |
| { |
| mpXSecController->exportSignature(xDocumentHandler, signatureInfo); |
| } |
| |
| bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler ) |
| { |
| mbError = false; |
| |
| /* |
| * create a signature listener |
| */ |
| /* |
| ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener( |
| LINK( this, XMLSignatureHelper, SignatureCreationResultListener ), |
| LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ), |
| LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) ); |
| */ |
| /* |
| * configure the signature creation listener |
| */ |
| //mpXSecController->setSignatureCreationResultListener( pSignatureListener ); |
| |
| /* |
| * write signatures |
| */ |
| if ( !mpXSecController->WriteSignature( xDocumentHandler ) ) |
| { |
| mbError = true; |
| } |
| |
| /* |
| * clear up the signature creation listener |
| */ |
| //mpXSecController->setSignatureCreationResultListener( NULL ); |
| |
| return !mbError; |
| } |
| |
| bool XMLSignatureHelper::CreateAndWriteSignature( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream ) |
| { |
| uno::Reference<xml::sax::XDocumentHandler> xDocHandler |
| = CreateDocumentHandlerWithHeader(xOutputStream); |
| |
| bool rc = CreateAndWriteSignature( xDocHandler ); |
| |
| CloseDocumentHandler(xDocHandler); |
| |
| return rc; |
| } |
| |
| bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream ) |
| { |
| mbError = false; |
| |
| DBG_ASSERT(xInputStream.is(), "input stream missing"); |
| |
| /* |
| * prepare ParserInputSrouce |
| */ |
| xml::sax::InputSource aParserInput; |
| // aParserInput.sSystemId = ouName; |
| aParserInput.aInputStream = xInputStream; |
| |
| /* |
| * get SAX parser component |
| */ |
| uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); |
| uno::Reference< xml::sax::XParser > xParser( |
| xMCF->createInstanceWithContext( |
| rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser"), mxCtx ), |
| uno::UNO_QUERY ); |
| |
| DBG_ASSERT( xParser.is(), "Can't create parser" ); |
| |
| /* |
| * create a signature reader |
| */ |
| uno::Reference< xml::sax::XDocumentHandler > xHandler |
| = mpXSecController->createSignatureReader( ); |
| |
| /* |
| * create a signature listener |
| */ |
| ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener( |
| LINK( this, XMLSignatureHelper, SignatureCreationResultListener ), |
| LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ), |
| LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) ); |
| |
| /* |
| * configure the signature verify listener |
| */ |
| //mpXSecController->setSignatureVerifyResultListener( pSignatureListener ); |
| |
| /* |
| * setup the connection: |
| * Parser -> SignatureListener -> SignatureReader |
| */ |
| pSignatureListener->setNextHandler(xHandler); |
| xParser->setDocumentHandler( pSignatureListener ); |
| |
| /* |
| * parser the stream |
| */ |
| try |
| { |
| xParser->parseStream( aParserInput ); |
| } |
| catch( xml::sax::SAXParseException& ) |
| { |
| mbError = true; |
| } |
| catch( xml::sax::SAXException& ) |
| { |
| mbError = true; |
| } |
| catch( com::sun::star::io::IOException& ) |
| { |
| mbError = true; |
| } |
| catch( uno::Exception& ) |
| { |
| mbError = true; |
| } |
| |
| /* |
| * clear up the connection |
| */ |
| pSignatureListener->setNextHandler( NULL ); |
| |
| /* |
| * clear up the signature verify listener |
| */ |
| //mpXSecController->setSignatureVerifyResultListener( NULL ); |
| |
| /* |
| * release the signature reader |
| */ |
| mpXSecController->releaseSignatureReader( ); |
| |
| return !mbError; |
| } |
| |
| SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const |
| { |
| return mpXSecController->getSignatureInformation( nSecurityId ); |
| } |
| |
| SignatureInformations XMLSignatureHelper::GetSignatureInformations() const |
| { |
| return mpXSecController->getSignatureInformations(); |
| } |
| |
| uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironment() |
| { |
| return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironment()): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >()); |
| } |
| |
| uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironmentByIndex(sal_Int32 nId) |
| { |
| return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentByIndex(nId)): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >()); |
| } |
| |
| sal_Int32 XMLSignatureHelper::GetSecurityEnvironmentNumber() |
| { |
| return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentNumber()): 0); |
| } |
| |
| IMPL_LINK( XMLSignatureHelper, SignatureCreationResultListener, XMLSignatureCreationResult*, pResult ) |
| { |
| maCreationResults.insert( maCreationResults.begin() + maCreationResults.size(), *pResult ); |
| if ( pResult->nSignatureCreationResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED ) |
| mbError = true; |
| return 0; |
| } |
| |
| IMPL_LINK( XMLSignatureHelper, SignatureVerifyResultListener, XMLSignatureVerifyResult*, pResult ) |
| { |
| maVerifyResults.insert( maVerifyResults.begin() + maVerifyResults.size(), *pResult ); |
| if ( pResult->nSignatureVerifyResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED ) |
| mbError = true; |
| return 0; |
| } |
| |
| IMPL_LINK( XMLSignatureHelper, StartVerifySignatureElement, const uno::Reference< com::sun::star::xml::sax::XAttributeList >*, pAttrs ) |
| { |
| if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call( (void*)pAttrs ) ) |
| { |
| sal_Int32 nSignatureId = mpXSecController->getNewSecurityId(); |
| mpXSecController->addSignature( nSignatureId ); |
| } |
| |
| return 0; |
| } |