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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmlsecurity.hxx"
26 
27 #include <xmlsecurity/xmlsignaturehelper.hxx>
28 #include <xmlsecurity/documentsignaturehelper.hxx>
29 #include <xsecctl.hxx>
30 
31 #include <xmlsignaturehelper2.hxx>
32 
33 #include <tools/stream.hxx>
34 #include <tools/debug.hxx>
35 
36 #include <xmloff/attrlist.hxx>
37 
38 #include <com/sun/star/io/XOutputStream.hpp>
39 #include <com/sun/star/io/XInputStream.hpp>
40 #include <com/sun/star/io/XActiveDataSource.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
42 #include <com/sun/star/security/SerialNumberAdapter.hpp>
43 #include <com/sun/star/beans/XPropertySet.hpp>
44 
45 #include <tools/date.hxx>
46 #include <tools/time.hxx>
47 
48 //MM : search for the default profile
49 //#include <unotools/streamhelper.hxx>
50 //MM : end
51 
52 /* SEInitializer component */
53 #define SEINITIALIZER_COMPONENT "com.sun.star.xml.crypto.SEInitializer"
54 
55 #define TAG_DOCUMENTSIGNATURES	"document-signatures"
56 #define NS_DOCUMENTSIGNATURES	"http://openoffice.org/2004/documentsignatures"
57 #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
58 
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::uno;
61 
XMLSignatureHelper(const uno::Reference<uno::XComponentContext> & rxCtx)62 XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
63     : mxCtx(rxCtx), mbODFPre1_2(false)
64 {
65     mpXSecController = new XSecController(rxCtx);
66     mxSecurityController = mpXSecController;
67     mbError = false;
68 }
69 
~XMLSignatureHelper()70 XMLSignatureHelper::~XMLSignatureHelper()
71 {
72 }
73 
Init()74 bool XMLSignatureHelper::Init()
75 {
76     DBG_ASSERT( !mxSEInitializer.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
77     DBG_ASSERT( !mxSecurityContext.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
78 
79     ImplCreateSEInitializer();
80 
81 	if ( mxSEInitializer.is() )
82 		mxSecurityContext = mxSEInitializer->createSecurityContext( ::rtl::OUString() );
83 
84     return mxSecurityContext.is();
85 }
86 
ImplCreateSEInitializer()87 void XMLSignatureHelper::ImplCreateSEInitializer()
88 {
89     rtl::OUString sSEInitializer(rtl::OUString::createFromAscii( SEINITIALIZER_COMPONENT ));
90     uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
91     mxSEInitializer = uno::Reference< com::sun::star::xml::crypto::XSEInitializer > (
92         xMCF->createInstanceWithContext( sSEInitializer,  mxCtx ), uno::UNO_QUERY );
93 }
94 
SetUriBinding(com::sun::star::uno::Reference<com::sun::star::xml::crypto::XUriBinding> & rxUriBinding)95 void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding >& rxUriBinding )
96 {
97     mxUriBinding = rxUriBinding;
98 }
99 
GetUriBinding() const100 com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > XMLSignatureHelper::GetUriBinding() const
101 {
102     return mxUriBinding;
103 }
104 
SetStorage(const Reference<css::embed::XStorage> & rxStorage,::rtl::OUString sODFVersion)105 void XMLSignatureHelper::SetStorage(
106     const Reference < css::embed::XStorage >& rxStorage,
107     ::rtl::OUString sODFVersion)
108 {
109     DBG_ASSERT( !mxUriBinding.is(), "SetStorage - UriBinding already set!" );
110     mxUriBinding = new UriBindingHelper( rxStorage );
111     DBG_ASSERT(rxStorage.is(), "SetStorage - empty storage!");
112     mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
113 }
114 
115 
SetStartVerifySignatureHdl(const Link & rLink)116 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link& rLink )
117 {
118     maStartVerifySignatureHdl = rLink;
119 }
120 
121 
StartMission()122 void XMLSignatureHelper::StartMission()
123 {
124     if ( !mxUriBinding.is() )
125         mxUriBinding = new UriBindingHelper();
126 
127     mpXSecController->startMission( mxUriBinding, mxSecurityContext );
128 }
129 
EndMission()130 void XMLSignatureHelper::EndMission()
131 {
132     mpXSecController->endMission();
133 }
134 
GetNewSecurityId()135 sal_Int32 XMLSignatureHelper::GetNewSecurityId()
136 {
137     return mpXSecController->getNewSecurityId();
138 }
139 
SetX509Certificate(sal_Int32 nSecurityId,const rtl::OUString & ouX509IssuerName,const rtl::OUString & ouX509SerialNumber,const rtl::OUString & ouX509Cert)140 void XMLSignatureHelper::SetX509Certificate(
141 		sal_Int32 nSecurityId,
142 		const rtl::OUString& ouX509IssuerName,
143 		const rtl::OUString& ouX509SerialNumber,
144 		const rtl::OUString& ouX509Cert)
145 {
146 	mpXSecController->setX509Certificate(
147 		nSecurityId,
148 		ouX509IssuerName,
149 		ouX509SerialNumber,
150 		ouX509Cert);
151 }
152 
SetX509Certificate(sal_Int32 nSecurityId,sal_Int32 nSecurityEnvironmentIndex,const rtl::OUString & ouX509IssuerName,const rtl::OUString & ouX509SerialNumber,const rtl::OUString & ouX509Cert)153 void XMLSignatureHelper::SetX509Certificate(
154 		sal_Int32 nSecurityId,
155 		sal_Int32 nSecurityEnvironmentIndex,
156 		const rtl::OUString& ouX509IssuerName,
157 		const rtl::OUString& ouX509SerialNumber,
158 		const rtl::OUString& ouX509Cert)
159 {
160 	mpXSecController->setX509Certificate(
161 		nSecurityId,
162 		nSecurityEnvironmentIndex,
163 		ouX509IssuerName,
164 		ouX509SerialNumber,
165 		ouX509Cert);
166 }
167 
SetDateTime(sal_Int32 nSecurityId,const Date & rDate,const Time & rTime)168 void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const Time& rTime )
169 {
170 	/*
171     rtl::OUString aDate = String::CreateFromInt32( rDate.GetDate() );
172     rtl::OUString aTime = String::CreateFromInt32( rTime.GetTime() );
173 	mpXSecController->setDateTime( nSecurityId, aDate, aTime );
174 	*/
175 	::com::sun::star::util::DateTime stDateTime;
176 	stDateTime.HundredthSeconds = (::sal_uInt16)rTime.Get100Sec();
177 	stDateTime.Seconds = (::sal_uInt16)rTime.GetSec();
178 	stDateTime.Minutes = (::sal_uInt16)rTime.GetMin();
179 	stDateTime.Hours = (::sal_uInt16)rTime.GetHour();
180 	stDateTime.Day = (::sal_uInt16)rDate.GetDay();
181 	stDateTime.Month = (::sal_uInt16)rDate.GetMonth();
182 	stDateTime.Year = (::sal_uInt16)rDate.GetYear();
183 	mpXSecController->setDate( nSecurityId, stDateTime );
184 }
185 
AddForSigning(sal_Int32 nSecurityId,const rtl::OUString & uri,const rtl::OUString & objectURL,sal_Bool bBinary)186 void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool bBinary )
187 {
188 	mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary );
189 }
190 
191 
CreateDocumentHandlerWithHeader(const com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> & xOutputStream)192 uno::Reference<xml::sax::XDocumentHandler> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
193 	const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
194 {
195 	/*
196 	 * get SAX writer component
197 	 */
198 	uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
199 	uno::Reference< io::XActiveDataSource > xSaxWriter(
200 		xMCF->createInstanceWithContext(rtl::OUString::createFromAscii(
201 			"com.sun.star.xml.sax.Writer"), mxCtx ), uno::UNO_QUERY );
202 
203 	DBG_ASSERT( xSaxWriter.is(), "can't instantiate XML writer" );
204 
205 	/*
206 	 * connect XML writer to output stream
207 	 */
208 	xSaxWriter->setOutputStream( xOutputStream );
209 
210 	/*
211 	 * prepare document handler
212 	 */
213 	uno::Reference<xml::sax::XDocumentHandler>
214 		xDocHandler( xSaxWriter,uno::UNO_QUERY);
215 
216 	/*
217 	 * write the xml context for signatures
218 	 */
219 	rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES));
220 
221 	SvXMLAttributeList *pAttributeList = new SvXMLAttributeList();
222     rtl::OUString sNamespace;
223     if (mbODFPre1_2)
224         sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES));
225     else
226         sNamespace = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(NS_DOCUMENTSIGNATURES_ODF_1_2));
227 
228 	pAttributeList->AddAttribute(
229 		rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(ATTR_XMLNS)),
230 		sNamespace);
231 
232 	xDocHandler->startDocument();
233 	xDocHandler->startElement(
234 		tag_AllSignatures,
235 		uno::Reference< com::sun::star::xml::sax::XAttributeList > (pAttributeList));
236 
237 	return xDocHandler;
238 }
239 
CloseDocumentHandler(const uno::Reference<xml::sax::XDocumentHandler> & xDocumentHandler)240 void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler )
241 {
242 	rtl::OUString tag_AllSignatures(RTL_CONSTASCII_USTRINGPARAM(TAG_DOCUMENTSIGNATURES));
243 	xDocumentHandler->endElement( tag_AllSignatures );
244 	xDocumentHandler->endDocument();
245 }
246 
ExportSignature(const uno::Reference<xml::sax::XDocumentHandler> & xDocumentHandler,const SignatureInformation & signatureInfo)247 void XMLSignatureHelper::ExportSignature(
248 	const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
249 	const SignatureInformation& signatureInfo )
250 {
251 	mpXSecController->exportSignature(xDocumentHandler, signatureInfo);
252 }
253 
CreateAndWriteSignature(const uno::Reference<xml::sax::XDocumentHandler> & xDocumentHandler)254 bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler )
255 {
256 	mbError = false;
257 
258 	/*
259 	 * create a signature listener
260 	 */
261 /*
262 	ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
263 	                                                LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
264 	                                                LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
265 	                                                LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
266 */
267 	/*
268 	 * configure the signature creation listener
269 	 */
270 	//mpXSecController->setSignatureCreationResultListener( pSignatureListener );
271 
272 	/*
273 	 * write signatures
274 	 */
275 	if ( !mpXSecController->WriteSignature( xDocumentHandler ) )
276 	{
277 		mbError = true;
278 	}
279 
280 	/*
281 	 * clear up the signature creation listener
282 	 */
283 	//mpXSecController->setSignatureCreationResultListener( NULL );
284 
285 	return !mbError;
286 }
287 
CreateAndWriteSignature(const com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> & xOutputStream)288 bool XMLSignatureHelper::CreateAndWriteSignature( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
289 {
290 	uno::Reference<xml::sax::XDocumentHandler> xDocHandler
291 		= CreateDocumentHandlerWithHeader(xOutputStream);
292 
293 	bool rc = CreateAndWriteSignature( xDocHandler );
294 
295 	CloseDocumentHandler(xDocHandler);
296 
297 	return rc;
298 }
299 
ReadAndVerifySignature(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream> & xInputStream)300 bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream )
301 {
302 	mbError = false;
303 
304 	DBG_ASSERT(xInputStream.is(), "input stream missing");
305 
306 	/*
307 	 * prepare ParserInputSrouce
308 	 */
309 	xml::sax::InputSource aParserInput;
310 	// aParserInput.sSystemId = ouName;
311 	aParserInput.aInputStream = xInputStream;
312 
313 	/*
314 	 * get SAX parser component
315 	 */
316 	uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
317 	uno::Reference< xml::sax::XParser > xParser(
318 		xMCF->createInstanceWithContext(
319 			rtl::OUString::createFromAscii("com.sun.star.xml.sax.Parser"), mxCtx ),
320 		uno::UNO_QUERY );
321 
322 	DBG_ASSERT( xParser.is(), "Can't create parser" );
323 
324 	/*
325 	 * create a signature reader
326 	 */
327 	uno::Reference< xml::sax::XDocumentHandler > xHandler
328 		= mpXSecController->createSignatureReader( );
329 
330 	/*
331 	 * create a signature listener
332 	 */
333 	ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
334 	                                                LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
335 	                                                LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
336 	                                                LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
337 
338 	/*
339 	 * configure the signature verify listener
340 	 */
341 	//mpXSecController->setSignatureVerifyResultListener( pSignatureListener );
342 
343 	/*
344 	 * setup the connection:
345 	 * Parser -> SignatureListener -> SignatureReader
346 	 */
347 	pSignatureListener->setNextHandler(xHandler);
348 	xParser->setDocumentHandler( pSignatureListener );
349 
350 	/*
351 	 * parser the stream
352 	 */
353 	try
354 	{
355 		xParser->parseStream( aParserInput );
356 	}
357 	catch( xml::sax::SAXParseException& )
358 	{
359 		mbError = true;
360 	}
361 	catch( xml::sax::SAXException& )
362 	{
363 		mbError = true;
364 	}
365 	catch( com::sun::star::io::IOException& )
366 	{
367 		mbError = true;
368 	}
369 	catch( uno::Exception& )
370 	{
371 		mbError = true;
372 	}
373 
374 	/*
375 	 * clear up the connection
376 	 */
377 	pSignatureListener->setNextHandler( NULL );
378 
379 	/*
380 	 * clear up the signature verify listener
381 	 */
382 	//mpXSecController->setSignatureVerifyResultListener( NULL );
383 
384 	/*
385 	 * release the signature reader
386 	 */
387 	mpXSecController->releaseSignatureReader( );
388 
389 	return !mbError;
390 }
391 
GetSignatureInformation(sal_Int32 nSecurityId) const392 SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const
393 {
394 	return mpXSecController->getSignatureInformation( nSecurityId );
395 }
396 
GetSignatureInformations() const397 SignatureInformations XMLSignatureHelper::GetSignatureInformations() const
398 {
399 	return mpXSecController->getSignatureInformations();
400 }
401 
GetSecurityEnvironment()402 uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironment()
403 {
404 	return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironment()): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >());
405 }
406 
GetSecurityEnvironmentByIndex(sal_Int32 nId)407 uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironmentByIndex(sal_Int32 nId)
408 {
409 	return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentByIndex(nId)): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >());
410 }
411 
GetSecurityEnvironmentNumber()412 sal_Int32 XMLSignatureHelper::GetSecurityEnvironmentNumber()
413 {
414 	return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentNumber()): 0);
415 }
416 
IMPL_LINK(XMLSignatureHelper,SignatureCreationResultListener,XMLSignatureCreationResult *,pResult)417 IMPL_LINK( XMLSignatureHelper, SignatureCreationResultListener, XMLSignatureCreationResult*, pResult )
418 {
419     maCreationResults.insert( maCreationResults.begin() + maCreationResults.size(), *pResult );
420     if ( pResult->nSignatureCreationResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
421         mbError = true;
422     return 0;
423 }
424 
IMPL_LINK(XMLSignatureHelper,SignatureVerifyResultListener,XMLSignatureVerifyResult *,pResult)425 IMPL_LINK( XMLSignatureHelper, SignatureVerifyResultListener, XMLSignatureVerifyResult*, pResult )
426 {
427     maVerifyResults.insert( maVerifyResults.begin() + maVerifyResults.size(), *pResult );
428     if ( pResult->nSignatureVerifyResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
429         mbError = true;
430     return 0;
431 }
432 
IMPL_LINK(XMLSignatureHelper,StartVerifySignatureElement,const uno::Reference<com::sun::star::xml::sax::XAttributeList> *,pAttrs)433 IMPL_LINK( XMLSignatureHelper, StartVerifySignatureElement, const uno::Reference< com::sun::star::xml::sax::XAttributeList >*, pAttrs )
434 {
435     if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call( (void*)pAttrs ) )
436 	{
437 		sal_Int32 nSignatureId = mpXSecController->getNewSecurityId();
438 		mpXSecController->addSignature( nSignatureId );
439 	}
440 
441     return 0;
442 }
443