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