1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
30 
31 #include <xmlsecurity/xmlsignaturehelper.hxx>
32 #include <xmlsignaturehelper2.hxx>
33 
34 #include <tools/solar.h>
35 #include <unotools/streamhelper.hxx>
36 
37 #include <com/sun/star/embed/XStorage.hpp>
38 #include <com/sun/star/embed/XStorageRawAccess.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include "rtl/uri.hxx"
42 
43 using namespace com::sun::star;
44 
45 ImplXMLSignatureListener::ImplXMLSignatureListener( const Link& rCreationResultListenerListener, const Link rVerifyResultListenerListener, const Link rStartSignatureElement )
46 {
47     maCreationResultListenerListener = rCreationResultListenerListener;
48     maVerifyResultListenerListener = rVerifyResultListenerListener;
49     maStartVerifySignatureElementListener = rStartSignatureElement;
50 
51 }
52 ImplXMLSignatureListener::~ImplXMLSignatureListener()
53 {
54 }
55 
56 void ImplXMLSignatureListener::setNextHandler(
57 	uno::Reference< xml::sax::XDocumentHandler > xNextHandler)
58 {
59 	m_xNextHandler = xNextHandler;
60 }
61 
62 void SAL_CALL ImplXMLSignatureListener::signatureCreated( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
63 		throw (com::sun::star::uno::RuntimeException)
64 {
65     XMLSignatureCreationResult aResult( securityId, nResult );
66     maCreationResultListenerListener.Call( &aResult );
67 }
68 
69 void SAL_CALL ImplXMLSignatureListener::signatureVerified( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
70 		throw (com::sun::star::uno::RuntimeException)
71 {
72     XMLSignatureVerifyResult aResult( securityId, nResult );
73     maVerifyResultListenerListener.Call( &aResult );
74 }
75 
76 // ---------------------------------------------------------------------------------
77 // XDocumentHandler
78 // ---------------------------------------------------------------------------------
79 void SAL_CALL ImplXMLSignatureListener::startDocument(  )
80 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
81 {
82 	if (m_xNextHandler.is())
83 	{
84 		m_xNextHandler->startDocument();
85 	}
86 }
87 
88 void SAL_CALL ImplXMLSignatureListener::endDocument(  )
89 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
90 {
91 	if (m_xNextHandler.is())
92 	{
93 		m_xNextHandler->endDocument();
94 	}
95 }
96 
97 void SAL_CALL ImplXMLSignatureListener::startElement( const rtl::OUString& aName, const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList >& xAttribs )
98 		throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
99 {
100 	if ( aName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Signature")) )
101 	{
102         	maStartVerifySignatureElementListener.Call( (void*)&xAttribs );
103 	}
104 
105 	if (m_xNextHandler.is())
106 	{
107 		m_xNextHandler->startElement( aName, xAttribs );
108 	}
109 }
110 
111 void SAL_CALL ImplXMLSignatureListener::endElement( const rtl::OUString& aName )
112 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
113 {
114 	if (m_xNextHandler.is())
115 	{
116 		m_xNextHandler->endElement( aName );
117 	}
118 }
119 
120 void SAL_CALL ImplXMLSignatureListener::characters( const rtl::OUString& aChars )
121 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
122 {
123 	if (m_xNextHandler.is())
124 	{
125 		m_xNextHandler->characters( aChars );
126 	}
127 }
128 
129 void SAL_CALL ImplXMLSignatureListener::ignorableWhitespace( const rtl::OUString& aWhitespaces )
130 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
131 {
132 	if (m_xNextHandler.is())
133 	{
134 		m_xNextHandler->ignorableWhitespace( aWhitespaces );
135 	}
136 }
137 
138 void SAL_CALL ImplXMLSignatureListener::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
139 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
140 {
141 	if (m_xNextHandler.is())
142 	{
143 		m_xNextHandler->processingInstruction( aTarget, aData );
144 	}
145 }
146 
147 void SAL_CALL ImplXMLSignatureListener::setDocumentLocator( const com::sun::star::uno::Reference< com::sun::star::xml::sax::XLocator >& xLocator )
148 	throw (com::sun::star::xml::sax::SAXException, com::sun::star::uno::RuntimeException)
149 {
150 	if (m_xNextHandler.is())
151 	{
152 		m_xNextHandler->setDocumentLocator( xLocator );
153 	}
154 }
155 
156 // ---------------------------------------------------------------------------------
157 // XUriBinding
158 // ---------------------------------------------------------------------------------
159 
160 UriBindingHelper::UriBindingHelper()
161 {
162 }
163 
164 UriBindingHelper::UriBindingHelper( const com::sun::star::uno::Reference < com::sun::star::embed::XStorage >& rxStorage )
165 {
166     mxStorage = rxStorage;
167 }
168 
169 
170 void SAL_CALL UriBindingHelper::setUriBinding( const rtl::OUString& /*uri*/, const uno::Reference< io::XInputStream >&)
171     throw (uno::Exception, uno::RuntimeException)
172 {
173 }
174 
175 uno::Reference< io::XInputStream > SAL_CALL UriBindingHelper::getUriBinding( const rtl::OUString& uri )
176 	throw (uno::Exception, uno::RuntimeException)
177 {
178     uno::Reference< io::XInputStream > xInputStream;
179     if ( mxStorage.is() )
180     {
181         xInputStream = OpenInputStream( mxStorage, uri );
182     }
183     else
184     {
185         SvFileStream* pStream = new SvFileStream( uri, STREAM_READ );
186         pStream->Seek( STREAM_SEEK_TO_END );
187         sal_uLong nBytes = pStream->Tell();
188         pStream->Seek( STREAM_SEEK_TO_BEGIN );
189         SvLockBytesRef xLockBytes = new SvLockBytes( pStream, sal_True );
190         xInputStream = new utl::OInputStreamHelper( xLockBytes, nBytes );
191     }
192     return xInputStream;
193 }
194 
195 uno::Reference < io::XInputStream > UriBindingHelper::OpenInputStream( const uno::Reference < embed::XStorage >& rxStore, const rtl::OUString& rURI )
196 {
197     OSL_ASSERT(rURI.getLength());
198     uno::Reference < io::XInputStream > xInStream;
199 
200     sal_Int32 nSepPos = rURI.indexOf( '/' );
201     if ( nSepPos == -1 )
202     {
203         // Cloning because of I can't keep all storage references open
204         // MBA with think about a better API...
205         const ::rtl::OUString sName = ::rtl::Uri::decode(
206             rURI, rtl_UriDecodeStrict, rtl_UriCharClassRelSegment);
207         if (sName.getLength() == 0 && rURI.getLength() != 0)
208             throw uno::Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
209             "Could not decode URI for stream element.")), 0);
210 
211         uno::Reference< io::XStream > xStream;
212         xStream = rxStore->cloneStreamElement( sName );
213         if ( !xStream.is() )
214             throw uno::RuntimeException();
215         xInStream = xStream->getInputStream();
216     }
217     else
218     {
219         const rtl::OUString aStoreName = ::rtl::Uri::decode(
220             rURI.copy( 0, nSepPos ), rtl_UriDecodeStrict, rtl_UriCharClassRelSegment);
221         if (aStoreName.getLength() == 0 && rURI.getLength() != 0)
222             throw uno::Exception(
223             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
224             "Could not decode URI for stream element.")), 0);
225 
226         rtl::OUString aElement = rURI.copy( nSepPos+1 );
227         uno::Reference < embed::XStorage > xSubStore = rxStore->openStorageElement( aStoreName, embed::ElementModes::READ );
228         xInStream = OpenInputStream( xSubStore, aElement );
229     }
230     return xInStream;
231 }
232 
233 
234