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 setIfEmpty(isi.signatureInfor.ouDateTime, ouDate); 224 } 225 226 /* 227 void XSecController::setTime( rtl::OUString& ouTime ) 228 { 229 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 230 isi.signatureInfor.ouTime = ouTime; 231 } 232 */ 233 234 void XSecController::setId( rtl::OUString& ouId ) 235 { 236 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 237 isi.signatureInfor.ouSignatureId = ouId; 238 } 239 240 void XSecController::setPropertyId( rtl::OUString& ouPropertyId ) 241 { 242 InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1]; 243 isi.signatureInfor.ouPropertyId = ouPropertyId; 244 } 245 246 /* public: for signature verify */ 247 void XSecController::collectToVerify( const rtl::OUString& referenceId ) 248 { 249 /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */ 250 251 if ( m_nStatusOfSecurityComponents == INITIALIZED ) 252 /* 253 * if all security components are ready, verify the signature. 254 */ 255 { 256 bool bJustChainingOn = false; 257 cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL; 258 259 int i,j; 260 int sigNum = m_vInternalSignatureInformations.size(); 261 262 for (i=0; i<sigNum; ++i) 263 { 264 InternalSignatureInformation& isi = m_vInternalSignatureInformations[i]; 265 SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors; 266 int refNum = vReferenceInfors.size(); 267 268 for (j=0; j<refNum; ++j) 269 { 270 SignatureReferenceInformation &refInfor = vReferenceInfors[j]; 271 272 if (refInfor.ouURI == referenceId) 273 { 274 if (chainOn(false)) 275 { 276 bJustChainingOn = true; 277 xHandler = m_xSAXEventKeeper->setNextHandler(NULL); 278 } 279 280 sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector( 281 cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False ); 282 283 cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster 284 (m_xSAXEventKeeper, 285 cssu::UNO_QUERY ); 286 287 cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector 288 ( isi.xReferenceResolvedListener, cssu::UNO_QUERY ); 289 290 m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId); 291 xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener); 292 xReferenceCollector->setReferenceId( nKeeperId ); 293 294 isi.vKeeperIds[j] = nKeeperId; 295 break; 296 } 297 } 298 } 299 300 if ( bJustChainingOn ) 301 { 302 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY); 303 if (m_xElementStackKeeper.is()) 304 { 305 m_xElementStackKeeper->retrieve(xSEKHandler, sal_True); 306 } 307 m_xSAXEventKeeper->setNextHandler(xHandler); 308 } 309 } 310 } 311 312 void XSecController::addSignature( sal_Int32 nSignatureId ) 313 { 314 DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" ); 315 316 m_nReservedSignatureId = nSignatureId; 317 m_bVerifyCurrentSignature = true; 318 } 319 320 cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader() 321 { 322 m_pXSecParser = new XSecParser( this, NULL ); 323 cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser; 324 325 setSAXChainConnector(xInitialization, NULL, NULL); 326 327 return m_pXSecParser; 328 } 329 330 void XSecController::releaseSignatureReader() 331 { 332 clearSAXChainConnector( ); 333 m_pXSecParser = NULL; 334 } 335 336