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 <xsecctl.hxx> 32 #include <tools/debug.hxx> 33 34 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp> 35 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp> 36 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp> 37 #include <com/sun/star/xml/crypto/sax/XBlockerMonitor.hpp> 38 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp> 39 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp> 40 #include <com/sun/star/io/XActiveDataSource.hpp> 41 #include <rtl/uuid.h> 42 43 #include <stdio.h> 44 45 namespace cssu = com::sun::star::uno; 46 namespace cssl = com::sun::star::lang; 47 namespace cssxc = com::sun::star::xml::crypto; 48 namespace cssxs = com::sun::star::xml::sax; 49 50 /* xml security framework components */ 51 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator" 52 53 /* protected: for signature generation */ 54 rtl::OUString XSecController::createId() 55 { 56 cssu::Sequence< sal_Int8 > aSeq( 16 ); 57 rtl_createUuid ((sal_uInt8 *)aSeq.getArray(), 0, sal_True); 58 59 char str[68]="ID_"; 60 int length = 3; 61 for (int i=0; i<16; ++i) 62 { 63 length += sprintf(str+length, "%04x", (unsigned char)aSeq[i]); 64 } 65 66 return rtl::OUString::createFromAscii(str); 67 } 68 69 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToWrite( 70 InternalSignatureInformation& internalSignatureInfor ) 71 { 72 sal_Int32 nSecurityId = internalSignatureInfor.signatureInfor.nSecurityId; 73 SignatureReferenceInformations& vReferenceInfors = internalSignatureInfor.signatureInfor.vSignatureReferenceInfors; 74 75 sal_Int32 nIdOfSignatureElementCollector; 76 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener; 77 78 nIdOfSignatureElementCollector = 79 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_True ); 80 81 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId); 82 83 /* 84 * create a SignatureCreator 85 */ 86 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); 87 xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >( 88 xMCF->createInstanceWithContext( 89 rtl::OUString::createFromAscii(SIGNATURECREATOR_COMPONENT), mxCtx), 90 cssu::UNO_QUERY); 91 92 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY); 93 94 cssu::Sequence<cssu::Any> args(5); 95 args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId)); 96 args[1] = cssu::makeAny(m_xSAXEventKeeper); 97 args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector)); 98 99 //i39448 : for nss, the internal module is used for signing, which needs to be improved later 100 sal_Int32 nEnvIndex = internalSignatureInfor.signatureInfor.nSecurityEnvironmentIndex; 101 if( nEnvIndex < 0 || nEnvIndex >= m_xSecurityContext->getSecurityEnvironmentNumber()) 102 {// set defaultEnv 103 args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironment()); 104 } 105 else 106 { 107 args[3] = cssu::makeAny(m_xSecurityContext->getSecurityEnvironmentByIndex(nEnvIndex)); 108 } 109 110 args[4] = cssu::makeAny(m_xXMLSignature); 111 xInitialization->initialize(args); 112 113 sal_Int32 nBlockerId = m_xSAXEventKeeper->addBlocker(); 114 m_xSAXEventKeeper->setSecurityId(nBlockerId, nSecurityId); 115 116 cssu::Reference<cssxc::sax::XBlockerMonitor> xBlockerMonitor(xReferenceResolvedListener, cssu::UNO_QUERY); 117 xBlockerMonitor->setBlockerId(nBlockerId); 118 119 cssu::Reference< cssxc::sax::XSignatureCreationResultBroadcaster > 120 xSignatureCreationResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY); 121 122 xSignatureCreationResultBroadcaster->addSignatureCreationResultListener( this ); 123 124 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> 125 xReferenceResolvedBroadcaster 126 (m_xSAXEventKeeper, 127 cssu::UNO_QUERY); 128 129 xReferenceResolvedBroadcaster->addReferenceResolvedListener( 130 nIdOfSignatureElementCollector, 131 xReferenceResolvedListener); 132 133 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector 134 (xReferenceResolvedListener, cssu::UNO_QUERY); 135 136 int i; 137 int size = vReferenceInfors.size(); 138 sal_Int32 nReferenceCount = 0; 139 140 for(i=0; i<size; ++i) 141 { 142 sal_Int32 keeperId = internalSignatureInfor.vKeeperIds[i]; 143 144 if ( keeperId != -1) 145 { 146 m_xSAXEventKeeper->setSecurityId(keeperId, nSecurityId); 147 xReferenceResolvedBroadcaster->addReferenceResolvedListener( keeperId, xReferenceResolvedListener); 148 xReferenceCollector->setReferenceId( keeperId ); 149 nReferenceCount++; 150 } 151 } 152 153 xReferenceCollector->setReferenceCount( nReferenceCount ); 154 155 /* 156 * adds all URI binding 157 */ 158 cssu::Reference<cssxc::XUriBinding> xUriBinding 159 (xReferenceResolvedListener, cssu::UNO_QUERY); 160 161 for(i=0; i<size; ++i) 162 { 163 const SignatureReferenceInformation& refInfor = vReferenceInfors[i]; 164 165 cssu::Reference< com::sun::star::io::XInputStream > xInputStream 166 = getObjectInputStream( refInfor.ouURI ); 167 168 if (xInputStream.is()) 169 { 170 xUriBinding->setUriBinding(refInfor.ouURI,xInputStream); 171 } 172 } 173 174 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY); 175 keyCollector->setKeyId(0); 176 177 internalSignatureInfor.signatureInfor.ouSignatureId = createId(); 178 internalSignatureInfor.signatureInfor.ouPropertyId = createId(); 179 internalSignatureInfor.addReference(TYPE_SAMEDOCUMENT_REFERENCE, internalSignatureInfor.signatureInfor.ouPropertyId, -1 ); 180 size++; 181 182 /* 183 * replace both digestValues and signatueValue to " " 184 */ 185 for(i=0; i<size; ++i) 186 { 187 SignatureReferenceInformation& refInfor = vReferenceInfors[i]; 188 refInfor.ouDigestValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK)); 189 } 190 191 internalSignatureInfor.signatureInfor.ouSignatureValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK)); 192 193 return xReferenceResolvedListener; 194 } 195 196 /* public: for signature generation */ 197 void XSecController::collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId ) 198 { 199 /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */ 200 201 chainOn(true); 202 203 if ( m_nStatusOfSecurityComponents == INITIALIZED ) 204 /* 205 * if all security components are ready, add a signature. 206 */ 207 { 208 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector( 209 cssxc::sax::ElementMarkPriority_AFTERMODIFY, sal_False); 210 211 int index = findSignatureInfor( securityId ); 212 213 if ( index == -1 ) 214 { 215 InternalSignatureInformation isi(securityId, NULL); 216 isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId ); 217 m_vInternalSignatureInformations.push_back( isi ); 218 } 219 else 220 { 221 m_vInternalSignatureInformations[index].addReference(TYPE_SAMEDOCUMENT_REFERENCE, referenceId, nKeeperId ); 222 } 223 } 224 } 225 226 void XSecController::signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& /*objectURL*/, sal_Bool isBinary) 227 { 228 sal_Int32 type = ((isBinary==sal_True)?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE); 229 230 int index = findSignatureInfor( securityId ); 231 232 if (index == -1) 233 { 234 InternalSignatureInformation isi(securityId, NULL); 235 isi.addReference(type, uri, -1); 236 m_vInternalSignatureInformations.push_back( isi ); 237 } 238 else 239 { 240 m_vInternalSignatureInformations[index].addReference(type, uri, -1); 241 } 242 } 243 244 void XSecController::setX509Certificate( 245 sal_Int32 nSecurityId, 246 const rtl::OUString& ouX509IssuerName, 247 const rtl::OUString& ouX509SerialNumber, 248 const rtl::OUString& ouX509Cert) 249 { 250 setX509Certificate(nSecurityId, -1, ouX509IssuerName, ouX509SerialNumber, ouX509Cert); 251 } 252 253 void XSecController::setX509Certificate( 254 sal_Int32 nSecurityId, 255 const sal_Int32 nSecurityEnvironmentIndex, 256 const rtl::OUString& ouX509IssuerName, 257 const rtl::OUString& ouX509SerialNumber, 258 const rtl::OUString& ouX509Cert) 259 { 260 int index = findSignatureInfor( nSecurityId ); 261 262 if ( index == -1 ) 263 { 264 InternalSignatureInformation isi(nSecurityId, NULL); 265 isi.signatureInfor.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex; 266 isi.signatureInfor.ouX509IssuerName = ouX509IssuerName; 267 isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber; 268 isi.signatureInfor.ouX509Certificate = ouX509Cert; 269 m_vInternalSignatureInformations.push_back( isi ); 270 } 271 else 272 { 273 SignatureInformation &si 274 = m_vInternalSignatureInformations[index].signatureInfor; 275 si.ouX509IssuerName = ouX509IssuerName; 276 si.ouX509SerialNumber = ouX509SerialNumber; 277 si.ouX509Certificate = ouX509Cert; 278 si.nSecurityEnvironmentIndex = nSecurityEnvironmentIndex; 279 } 280 } 281 282 void XSecController::setDate( 283 sal_Int32 nSecurityId, 284 const ::com::sun::star::util::DateTime& rDateTime ) 285 { 286 int index = findSignatureInfor( nSecurityId ); 287 288 if ( index == -1 ) 289 { 290 InternalSignatureInformation isi(nSecurityId, NULL); 291 isi.signatureInfor.stDateTime = rDateTime; 292 m_vInternalSignatureInformations.push_back( isi ); 293 } 294 else 295 { 296 SignatureInformation &si 297 = m_vInternalSignatureInformations[index].signatureInfor; 298 si.stDateTime = rDateTime; 299 } 300 } 301 302 bool XSecController::WriteSignature( 303 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler ) 304 { 305 bool rc = false; 306 307 DBG_ASSERT( xDocumentHandler.is(), "I really need a document handler!" ); 308 309 /* 310 * chain the SAXEventKeeper to the SAX chain 311 */ 312 chainOn(true); 313 314 if ( m_nStatusOfSecurityComponents == INITIALIZED ) 315 /* 316 * if all security components are ready, add the signature 317 * stream. 318 */ 319 { 320 m_bIsSAXEventKeeperSticky = true; 321 m_xSAXEventKeeper->setNextHandler(xDocumentHandler); 322 323 try 324 { 325 /* 326 * export the signature template 327 */ 328 cssu::Reference<cssxs::XDocumentHandler> xSEKHandler( m_xSAXEventKeeper,cssu::UNO_QUERY); 329 330 int i; 331 int sigNum = m_vInternalSignatureInformations.size(); 332 333 for (i=0; i<sigNum; ++i) 334 { 335 InternalSignatureInformation &isi = m_vInternalSignatureInformations[i]; 336 337 /* 338 * prepare the signature creator 339 */ 340 isi.xReferenceResolvedListener 341 = prepareSignatureToWrite( isi ); 342 343 exportSignature( xSEKHandler, isi.signatureInfor ); 344 } 345 346 m_bIsSAXEventKeeperSticky = false; 347 chainOff(); 348 349 rc = true; 350 } 351 catch( cssxs::SAXException& ) 352 { 353 m_pErrorMessage = ERROR_SAXEXCEPTIONDURINGCREATION; 354 } 355 catch( com::sun::star::io::IOException& ) 356 { 357 m_pErrorMessage = ERROR_IOEXCEPTIONDURINGCREATION; 358 } 359 catch( cssu::Exception& ) 360 { 361 m_pErrorMessage = ERROR_EXCEPTIONDURINGCREATION; 362 } 363 364 m_xSAXEventKeeper->setNextHandler( NULL ); 365 m_bIsSAXEventKeeperSticky = false; 366 } 367 else 368 { 369 m_pErrorMessage = ERROR_CANNOTCREATEXMLSECURITYCOMPONENT; 370 } 371 372 return rc; 373 } 374 375