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