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