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