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 "xsecparser.hxx" 29 #include <tools/debug.hxx> 30 31 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp> 32 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp> 33 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp> 34 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp> 35 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultBroadcaster.hpp> 36 #include <com/sun/star/xml/sax/SAXParseException.hpp> 37 38 namespace cssu = com::sun::star::uno; 39 namespace cssl = com::sun::star::lang; 40 namespace cssxc = com::sun::star::xml::crypto; 41 namespace cssxs = com::sun::star::xml::sax; 42 43 /* xml security framework components */ 44 #define SIGNATUREVERIFIER_COMPONENT "com.sun.star.xml.crypto.sax.SignatureVerifier" 45 46 /* protected: for signature verify */ 47 cssu::Reference< cssxc::sax::XReferenceResolvedListener > XSecController::prepareSignatureToRead( 48 sal_Int32 nSecurityId) 49 { 50 if ( m_nStatusOfSecurityComponents != INITIALIZED ) 51 { 52 return NULL; 53 } 54 55 sal_Int32 nIdOfSignatureElementCollector; 56 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener; 57 58 nIdOfSignatureElementCollector = 59 m_xSAXEventKeeper->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False); 60 61 m_xSAXEventKeeper->setSecurityId(nIdOfSignatureElementCollector, nSecurityId); 62 63 /* 64 * create a SignatureVerifier 65 */ 66 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() ); 67 xReferenceResolvedListener = cssu::Reference< cssxc::sax::XReferenceResolvedListener >( 68 xMCF->createInstanceWithContext( 69 rtl::OUString::createFromAscii( SIGNATUREVERIFIER_COMPONENT ), mxCtx), 70 cssu::UNO_QUERY); 71 72 cssu::Reference<cssl::XInitialization> xInitialization(xReferenceResolvedListener, cssu::UNO_QUERY); 73 74 cssu::Sequence<cssu::Any> args(5); 75 args[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId)); 76 args[1] = cssu::makeAny(m_xSAXEventKeeper); 77 args[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector)); 78 args[3] = cssu::makeAny(m_xSecurityContext); 79 args[4] = cssu::makeAny(m_xXMLSignature); 80 xInitialization->initialize(args); 81 82 cssu::Reference< cssxc::sax::XSignatureVerifyResultBroadcaster > 83 signatureVerifyResultBroadcaster(xReferenceResolvedListener, cssu::UNO_QUERY); 84 85 signatureVerifyResultBroadcaster->addSignatureVerifyResultListener( this ); 86 87 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster 88 (m_xSAXEventKeeper, 89 cssu::UNO_QUERY); 90 91 xReferenceResolvedBroadcaster->addReferenceResolvedListener( 92 nIdOfSignatureElementCollector, 93 xReferenceResolvedListener); 94 95 cssu::Reference<cssxc::sax::XKeyCollector> keyCollector (xReferenceResolvedListener, cssu::UNO_QUERY); 96 keyCollector->setKeyId(0); 97 98 return xReferenceResolvedListener; 99 } 100 101 void XSecController::addSignature() 102 { 103 cssu::Reference< cssxc::sax::XReferenceResolvedListener > xReferenceResolvedListener = NULL; 104 sal_Int32 nSignatureId = 0; 105 106 107 if (m_bVerifyCurrentSignature) 108 { 109 chainOn(true); 110 xReferenceResolvedListener = prepareSignatureToRead( m_nReservedSignatureId ); 111 m_bVerifyCurrentSignature = false; 112 nSignatureId = m_nReservedSignatureId; 113 } 114 115 InternalSignatureInformation isi( nSignatureId, xReferenceResolvedListener ); 116 m_vInternalSignatureInformations.push_back( isi ); 117 } 118 119 void XSecController::addReference( const rtl::OUString& ouUri) 120 { 121 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 122 isi.addReference(TYPE_SAMEDOCUMENT_REFERENCE,ouUri, -1 ); 123 } 124 125 void XSecController::addStreamReference( 126 const rtl::OUString& ouUri, 127 bool isBinary ) 128 { 129 sal_Int32 type = (isBinary?TYPE_BINARYSTREAM_REFERENCE:TYPE_XMLSTREAM_REFERENCE); 130 131 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 132 133 if ( isi.xReferenceResolvedListener.is() ) 134 { 135 /* 136 * get the input stream 137 */ 138 cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream 139 = getObjectInputStream( ouUri ); 140 141 if ( xObjectInputStream.is() ) 142 { 143 cssu::Reference<cssxc::XUriBinding> xUriBinding 144 (isi.xReferenceResolvedListener, cssu::UNO_QUERY); 145 xUriBinding->setUriBinding(ouUri, xObjectInputStream); 146 } 147 } 148 149 isi.addReference(type, ouUri, -1); 150 } 151 152 void XSecController::setReferenceCount() const 153 { 154 const InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 155 156 if ( isi.xReferenceResolvedListener.is() ) 157 { 158 const SignatureReferenceInformations &refInfors = isi.signatureInfor.vSignatureReferenceInfors; 159 160 int refNum = refInfors.size(); 161 sal_Int32 referenceCount = 0; 162 163 for(int i=0 ; i<refNum; ++i) 164 { 165 if (refInfors[i].nType == TYPE_SAMEDOCUMENT_REFERENCE ) 166 /* 167 * same-document reference 168 */ 169 { 170 referenceCount++; 171 } 172 } 173 174 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector 175 (isi.xReferenceResolvedListener, cssu::UNO_QUERY); 176 xReferenceCollector->setReferenceCount( referenceCount ); 177 } 178 } 179 180 void XSecController::setIfEmpty(rtl::OUString &variable, const rtl::OUString &value) { 181 if (variable.getLength() == 0) { 182 variable = value; 183 } else if (variable != value) { 184 throw cssu::RuntimeException(rtl::OUString::createFromAscii("Value already set. Tampering?"), *this); 185 } 186 } 187 188 void XSecController::setX509IssuerName( rtl::OUString& ouX509IssuerName ) 189 { 190 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 191 setIfEmpty(isi.signatureInfor.ouX509IssuerName, ouX509IssuerName); 192 } 193 194 void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber ) 195 { 196 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 197 setIfEmpty(isi.signatureInfor.ouX509SerialNumber, ouX509SerialNumber); 198 } 199 200 void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate ) 201 { 202 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 203 setIfEmpty(isi.signatureInfor.ouX509Certificate, ouX509Certificate); 204 } 205 206 void XSecController::setSignatureValue( rtl::OUString& ouSignatureValue ) 207 { 208 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 209 isi.signatureInfor.ouSignatureValue = ouSignatureValue; 210 } 211 212 void XSecController::setDigestValue( rtl::OUString& ouDigestValue ) 213 { 214 SignatureInformation &si = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1].signatureInfor; 215 SignatureReferenceInformation &reference = si.vSignatureReferenceInfors[si.vSignatureReferenceInfors.size()-1]; 216 reference.ouDigestValue = ouDigestValue; 217 } 218 219 void XSecController::setDate( rtl::OUString& ouDate ) 220 { 221 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 222 convertDateTime( isi.signatureInfor.stDateTime, ouDate ); 223 isi.signatureInfor.ouDateTime = ouDate; 224 /* When signing with the following code we get a 0 date time. 225 setIfEmpty(isi.signatureInfor.ouDateTime, ouDate); 226 */ 227 } 228 229 /* 230 void XSecController::setTime( rtl::OUString& ouTime ) 231 { 232 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 233 isi.signatureInfor.ouTime = ouTime; 234 } 235 */ 236 237 void XSecController::setId( rtl::OUString& ouId ) 238 { 239 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 240 isi.signatureInfor.ouSignatureId = ouId; 241 } 242 243 void XSecController::setPropertyId( rtl::OUString& ouPropertyId ) 244 { 245 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 246 isi.signatureInfor.ouPropertyId = ouPropertyId; 247 } 248 249 /* public: for signature verify */ 250 void XSecController::collectToVerify( const rtl::OUString& referenceId ) 251 { 252 /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */ 253 254 if ( m_nStatusOfSecurityComponents == INITIALIZED ) 255 /* 256 * if all security components are ready, verify the signature. 257 */ 258 { 259 bool bJustChainingOn = false; 260 cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL; 261 262 int i,j; 263 int sigNum = m_vInternalSignatureInformations.size(); 264 265 for (i=0; i<sigNum; ++i) 266 { 267 InternalSignatureInformation& isi = m_vInternalSignatureInformations[i]; 268 SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors; 269 int refNum = vReferenceInfors.size(); 270 271 for (j=0; j<refNum; ++j) 272 { 273 SignatureReferenceInformation &refInfor = vReferenceInfors[j]; 274 275 if (refInfor.ouURI == referenceId) 276 { 277 if (chainOn(false)) 278 { 279 bJustChainingOn = true; 280 xHandler = m_xSAXEventKeeper->setNextHandler(NULL); 281 } 282 283 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector( 284 cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False ); 285 286 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster 287 (m_xSAXEventKeeper, 288 cssu::UNO_QUERY ); 289 290 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector 291 ( isi.xReferenceResolvedListener, cssu::UNO_QUERY ); 292 293 m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId); 294 xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener); 295 xReferenceCollector->setReferenceId( nKeeperId ); 296 297 isi.vKeeperIds[j] = nKeeperId; 298 break; 299 } 300 } 301 } 302 303 if ( bJustChainingOn ) 304 { 305 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY); 306 if (m_xElementStackKeeper.is()) 307 { 308 m_xElementStackKeeper->retrieve(xSEKHandler, sal_True); 309 } 310 m_xSAXEventKeeper->setNextHandler(xHandler); 311 } 312 } 313 } 314 315 void XSecController::addSignature( sal_Int32 nSignatureId ) 316 { 317 DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" ); 318 319 m_nReservedSignatureId = nSignatureId; 320 m_bVerifyCurrentSignature = true; 321 } 322 323 cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader() 324 { 325 m_pXSecParser = new XSecParser( this, NULL ); 326 cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser; 327 328 setSAXChainConnector(xInitialization, NULL, NULL); 329 330 return m_pXSecParser; 331 } 332 333 void XSecController::releaseSignatureReader() 334 { 335 clearSAXChainConnector( ); 336 m_pXSecParser = NULL; 337 } 338 339