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 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 70 XMLSignatureHelper::~XMLSignatureHelper() 71 { 72 } 73 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 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 95 void XMLSignatureHelper::SetUriBinding( com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding >& rxUriBinding ) 96 { 97 mxUriBinding = rxUriBinding; 98 } 99 100 com::sun::star::uno::Reference< com::sun::star::xml::crypto::XUriBinding > XMLSignatureHelper::GetUriBinding() const 101 { 102 return mxUriBinding; 103 } 104 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 116 void XMLSignatureHelper::SetStartVerifySignatureHdl( const Link& rLink ) 117 { 118 maStartVerifySignatureHdl = rLink; 119 } 120 121 122 void XMLSignatureHelper::StartMission() 123 { 124 if ( !mxUriBinding.is() ) 125 mxUriBinding = new UriBindingHelper(); 126 127 mpXSecController->startMission( mxUriBinding, mxSecurityContext ); 128 } 129 130 void XMLSignatureHelper::EndMission() 131 { 132 mpXSecController->endMission(); 133 } 134 135 sal_Int32 XMLSignatureHelper::GetNewSecurityId() 136 { 137 return mpXSecController->getNewSecurityId(); 138 } 139 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 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 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 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 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 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 247 void XMLSignatureHelper::ExportSignature( 248 const uno::Reference< xml::sax::XDocumentHandler >& xDocumentHandler, 249 const SignatureInformation& signatureInfo ) 250 { 251 mpXSecController->exportSignature(xDocumentHandler, signatureInfo); 252 } 253 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 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 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 392 SignatureInformation XMLSignatureHelper::GetSignatureInformation( sal_Int32 nSecurityId ) const 393 { 394 return mpXSecController->getSignatureInformation( nSecurityId ); 395 } 396 397 SignatureInformations XMLSignatureHelper::GetSignatureInformations() const 398 { 399 return mpXSecController->getSignatureInformations(); 400 } 401 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 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 412 sal_Int32 XMLSignatureHelper::GetSecurityEnvironmentNumber() 413 { 414 return (mxSecurityContext.is()?(mxSecurityContext->getSecurityEnvironmentNumber()): 0); 415 } 416 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 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 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