Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <xmlsecurity/xmlsignaturehelper.hxx>
22 : #include <xmlsecurity/documentsignaturehelper.hxx>
23 : #include <xsecctl.hxx>
24 :
25 : #include <xmlsignaturehelper2.hxx>
26 :
27 : #include <tools/stream.hxx>
28 : #include <tools/debug.hxx>
29 :
30 : #include <xmloff/attrlist.hxx>
31 :
32 : #include <com/sun/star/io/XOutputStream.hpp>
33 : #include <com/sun/star/io/XInputStream.hpp>
34 : #include <com/sun/star/io/XActiveDataSource.hpp>
35 : #include <com/sun/star/lang/XComponent.hpp>
36 : #include <com/sun/star/beans/XPropertySet.hpp>
37 : #include <com/sun/star/xml/sax/Parser.hpp>
38 : #include <com/sun/star/xml/sax/Writer.hpp>
39 : #include <com/sun/star/xml/crypto/SEInitializer.hpp>
40 :
41 : #include <tools/date.hxx>
42 : #include <tools/time.hxx>
43 :
44 : #define TAG_DOCUMENTSIGNATURES "document-signatures"
45 : #define NS_DOCUMENTSIGNATURES "http://openoffice.org/2004/documentsignatures"
46 : #define NS_DOCUMENTSIGNATURES_ODF_1_2 "urn:oasis:names:tc:opendocument:xmlns:digitalsignature:1.0"
47 :
48 : using namespace ::com::sun::star;
49 : using namespace ::com::sun::star::uno;
50 :
51 0 : XMLSignatureHelper::XMLSignatureHelper( const uno::Reference< uno::XComponentContext >& rxCtx)
52 0 : : mxCtx(rxCtx), mbODFPre1_2(false)
53 : {
54 0 : mpXSecController = new XSecController(rxCtx);
55 0 : mxSecurityController = mpXSecController;
56 0 : mbError = false;
57 0 : }
58 :
59 0 : XMLSignatureHelper::~XMLSignatureHelper()
60 : {
61 0 : }
62 :
63 0 : bool XMLSignatureHelper::Init()
64 : {
65 : DBG_ASSERT( !mxSEInitializer.is(), "XMLSignatureHelper::Init - mxSEInitializer already set!" );
66 : DBG_ASSERT( !mxSecurityContext.is(), "XMLSignatureHelper::Init - mxSecurityContext already set!" );
67 :
68 0 : mxSEInitializer = com::sun::star::xml::crypto::SEInitializer::create( mxCtx );
69 :
70 0 : if ( mxSEInitializer.is() )
71 0 : mxSecurityContext = mxSEInitializer->createSecurityContext( ::rtl::OUString() );
72 :
73 0 : return mxSecurityContext.is();
74 : }
75 :
76 0 : void XMLSignatureHelper::SetStorage(
77 : const Reference < css::embed::XStorage >& rxStorage,
78 : ::rtl::OUString sODFVersion)
79 : {
80 : DBG_ASSERT( !mxUriBinding.is(), "SetStorage - UriBinding already set!" );
81 0 : mxUriBinding = new UriBindingHelper( rxStorage );
82 : DBG_ASSERT(rxStorage.is(), "SetStorage - empty storage!");
83 0 : mbODFPre1_2 = DocumentSignatureHelper::isODFPre_1_2(sODFVersion);
84 0 : }
85 :
86 :
87 0 : void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link& rLink )
88 : {
89 0 : maStartVerifySignatureHdl = rLink;
90 0 : }
91 :
92 :
93 0 : void XMLSignatureHelper::StartMission()
94 : {
95 0 : if ( !mxUriBinding.is() )
96 0 : mxUriBinding = new UriBindingHelper();
97 :
98 0 : mpXSecController->startMission( mxUriBinding, mxSecurityContext );
99 0 : }
100 :
101 0 : void XMLSignatureHelper::EndMission()
102 : {
103 0 : mpXSecController->endMission();
104 0 : }
105 :
106 0 : sal_Int32 XMLSignatureHelper::GetNewSecurityId()
107 : {
108 0 : return mpXSecController->getNewSecurityId();
109 : }
110 :
111 0 : void XMLSignatureHelper::SetX509Certificate(
112 : sal_Int32 nSecurityId,
113 : const rtl::OUString& ouX509IssuerName,
114 : const rtl::OUString& ouX509SerialNumber,
115 : const rtl::OUString& ouX509Cert)
116 : {
117 : mpXSecController->setX509Certificate(
118 : nSecurityId,
119 : ouX509IssuerName,
120 : ouX509SerialNumber,
121 0 : ouX509Cert);
122 0 : }
123 :
124 0 : void XMLSignatureHelper::SetDateTime( sal_Int32 nSecurityId, const Date& rDate, const Time& rTime )
125 : {
126 0 : ::com::sun::star::util::DateTime stDateTime;
127 0 : stDateTime.HundredthSeconds = (::sal_uInt16)rTime.Get100Sec();
128 0 : stDateTime.Seconds = (::sal_uInt16)rTime.GetSec();
129 0 : stDateTime.Minutes = (::sal_uInt16)rTime.GetMin();
130 0 : stDateTime.Hours = (::sal_uInt16)rTime.GetHour();
131 0 : stDateTime.Day = (::sal_uInt16)rDate.GetDay();
132 0 : stDateTime.Month = (::sal_uInt16)rDate.GetMonth();
133 0 : stDateTime.Year = (::sal_uInt16)rDate.GetYear();
134 0 : mpXSecController->setDate( nSecurityId, stDateTime );
135 0 : }
136 :
137 0 : void XMLSignatureHelper::AddForSigning( sal_Int32 nSecurityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool bBinary )
138 : {
139 0 : mpXSecController->signAStream( nSecurityId, uri, objectURL, bBinary );
140 0 : }
141 :
142 :
143 0 : uno::Reference<xml::sax::XWriter> XMLSignatureHelper::CreateDocumentHandlerWithHeader(
144 : const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xOutputStream )
145 : {
146 : /*
147 : * get SAX writer component
148 : */
149 0 : uno::Reference< lang::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
150 0 : uno::Reference< xml::sax::XWriter > xSaxWriter = xml::sax::Writer::create(mxCtx);
151 :
152 : /*
153 : * connect XML writer to output stream
154 : */
155 0 : xSaxWriter->setOutputStream( xOutputStream );
156 :
157 : /*
158 : * write the xml context for signatures
159 : */
160 0 : rtl::OUString tag_AllSignatures(TAG_DOCUMENTSIGNATURES);
161 :
162 0 : SvXMLAttributeList *pAttributeList = new SvXMLAttributeList();
163 0 : rtl::OUString sNamespace;
164 0 : if (mbODFPre1_2)
165 0 : sNamespace = rtl::OUString(NS_DOCUMENTSIGNATURES);
166 : else
167 0 : sNamespace = rtl::OUString(NS_DOCUMENTSIGNATURES_ODF_1_2);
168 :
169 : pAttributeList->AddAttribute(
170 : rtl::OUString(ATTR_XMLNS),
171 0 : sNamespace);
172 :
173 0 : xSaxWriter->startDocument();
174 0 : xSaxWriter->startElement(
175 : tag_AllSignatures,
176 0 : uno::Reference< com::sun::star::xml::sax::XAttributeList > (pAttributeList));
177 :
178 0 : return xSaxWriter;
179 : }
180 :
181 0 : void XMLSignatureHelper::CloseDocumentHandler( const uno::Reference<xml::sax::XDocumentHandler>& xDocumentHandler )
182 : {
183 0 : rtl::OUString tag_AllSignatures(TAG_DOCUMENTSIGNATURES);
184 0 : xDocumentHandler->endElement( tag_AllSignatures );
185 0 : xDocumentHandler->endDocument();
186 0 : }
187 :
188 0 : void XMLSignatureHelper::ExportSignature(
189 : const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler,
190 : const SignatureInformation& signatureInfo )
191 : {
192 0 : mpXSecController->exportSignature(xDocumentHandler, signatureInfo);
193 0 : }
194 :
195 0 : bool XMLSignatureHelper::CreateAndWriteSignature( const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler )
196 : {
197 0 : mbError = false;
198 :
199 : /*
200 : * create a signature listener
201 : */
202 :
203 : /*
204 : * configure the signature creation listener
205 : */
206 :
207 : /*
208 : * write signatures
209 : */
210 0 : if ( !mpXSecController->WriteSignature( xDocumentHandler ) )
211 : {
212 0 : mbError = true;
213 : }
214 :
215 : /*
216 : * clear up the signature creation listener
217 : */
218 :
219 0 : return !mbError;
220 : }
221 :
222 0 : bool XMLSignatureHelper::ReadAndVerifySignature( const com::sun::star::uno::Reference< com::sun::star::io::XInputStream >& xInputStream )
223 : {
224 0 : mbError = false;
225 :
226 : DBG_ASSERT(xInputStream.is(), "input stream missing");
227 :
228 : /*
229 : * prepare ParserInputSrouce
230 : */
231 0 : xml::sax::InputSource aParserInput;
232 0 : aParserInput.aInputStream = xInputStream;
233 :
234 : /*
235 : * get SAX parser component
236 : */
237 0 : uno::Reference< xml::sax::XParser > xParser = xml::sax::Parser::create(mxCtx);
238 :
239 : /*
240 : * create a signature reader
241 : */
242 : uno::Reference< xml::sax::XDocumentHandler > xHandler
243 0 : = mpXSecController->createSignatureReader( );
244 :
245 : /*
246 : * create a signature listener
247 : */
248 : ImplXMLSignatureListener* pSignatureListener = new ImplXMLSignatureListener(
249 : LINK( this, XMLSignatureHelper, SignatureCreationResultListener ),
250 : LINK( this, XMLSignatureHelper, SignatureVerifyResultListener ),
251 0 : LINK( this, XMLSignatureHelper, StartVerifySignatureElement ) );
252 :
253 : /*
254 : * configure the signature verify listener
255 : */
256 :
257 : /*
258 : * setup the connection:
259 : * Parser -> SignatureListener -> SignatureReader
260 : */
261 0 : pSignatureListener->setNextHandler(xHandler);
262 0 : xParser->setDocumentHandler( pSignatureListener );
263 :
264 : /*
265 : * parser the stream
266 : */
267 : try
268 : {
269 0 : xParser->parseStream( aParserInput );
270 : }
271 0 : catch( xml::sax::SAXParseException& )
272 : {
273 0 : mbError = true;
274 : }
275 0 : catch( xml::sax::SAXException& )
276 : {
277 0 : mbError = true;
278 : }
279 0 : catch( com::sun::star::io::IOException& )
280 : {
281 0 : mbError = true;
282 : }
283 0 : catch( uno::Exception& )
284 : {
285 0 : mbError = true;
286 : }
287 :
288 : /*
289 : * clear up the connection
290 : */
291 0 : pSignatureListener->setNextHandler( NULL );
292 :
293 : /*
294 : * clear up the signature verify listener
295 : */
296 :
297 : /*
298 : * release the signature reader
299 : */
300 0 : mpXSecController->releaseSignatureReader( );
301 :
302 0 : return !mbError;
303 : }
304 :
305 0 : SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const
306 : {
307 0 : return mpXSecController->getSignatureInformation( nSecurityId );
308 : }
309 :
310 0 : SignatureInformations XMLSignatureHelper::GetSignatureInformations() const
311 : {
312 0 : return mpXSecController->getSignatureInformations();
313 : }
314 :
315 0 : uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment > XMLSignatureHelper::GetSecurityEnvironment()
316 : {
317 0 : return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironment()): uno::Reference< ::com::sun::star::xml::crypto::XSecurityEnvironment >());
318 : }
319 :
320 0 : IMPL_LINK( XMLSignatureHelper, SignatureCreationResultListener, XMLSignatureCreationResult*, pResult )
321 : {
322 0 : maCreationResults.insert( maCreationResults.begin() + maCreationResults.size(), *pResult );
323 0 : if ( pResult->nSignatureCreationResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
324 0 : mbError = true;
325 0 : return 0;
326 : }
327 :
328 0 : IMPL_LINK( XMLSignatureHelper, SignatureVerifyResultListener, XMLSignatureVerifyResult*, pResult )
329 : {
330 0 : maVerifyResults.insert( maVerifyResults.begin() + maVerifyResults.size(), *pResult );
331 0 : if ( pResult->nSignatureVerifyResult != com::sun::star::xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED )
332 0 : mbError = true;
333 0 : return 0;
334 : }
335 :
336 0 : IMPL_LINK( XMLSignatureHelper, StartVerifySignatureElement, const uno::Reference< com::sun::star::xml::sax::XAttributeList >*, pAttrs )
337 : {
338 0 : if ( !maStartVerifySignatureHdl.IsSet() || maStartVerifySignatureHdl.Call( (void*)pAttrs ) )
339 : {
340 0 : sal_Int32 nSignatureId = mpXSecController->getNewSecurityId();
341 0 : mpXSecController->addSignature( nSignatureId );
342 : }
343 :
344 0 : return 0;
345 : }
346 :
347 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|