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::setX509IssuerName( rtl::OUString& ouX509IssuerName )
181 {
182 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
183 	isi.signatureInfor.ouX509IssuerName = ouX509IssuerName;
184 }
185 
186 void XSecController::setX509SerialNumber( rtl::OUString& ouX509SerialNumber )
187 {
188 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
189 	isi.signatureInfor.ouX509SerialNumber = ouX509SerialNumber;
190 }
191 
192 void XSecController::setX509Certificate( rtl::OUString& ouX509Certificate )
193 {
194 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
195 	isi.signatureInfor.ouX509Certificate = ouX509Certificate;
196 }
197 
198 void XSecController::setSignatureValue( rtl::OUString& ouSignatureValue )
199 {
200 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
201 	isi.signatureInfor.ouSignatureValue = ouSignatureValue;
202 }
203 
204 void XSecController::setDigestValue( rtl::OUString& ouDigestValue )
205 {
206 	SignatureInformation &si = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1].signatureInfor;
207 	SignatureReferenceInformation &reference = si.vSignatureReferenceInfors[si.vSignatureReferenceInfors.size()-1];
208 	reference.ouDigestValue = ouDigestValue;
209 }
210 
211 void XSecController::setDate( rtl::OUString& ouDate )
212 {
213 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
214 	convertDateTime( isi.signatureInfor.stDateTime, ouDate );
215 	isi.signatureInfor.ouDateTime = ouDate;
216 }
217 
218 /*
219 void XSecController::setTime( rtl::OUString& ouTime )
220 {
221 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
222 	isi.signatureInfor.ouTime = ouTime;
223 }
224 */
225 
226 void XSecController::setId( rtl::OUString& ouId )
227 {
228 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
229 	isi.signatureInfor.ouSignatureId = ouId;
230 }
231 
232 void XSecController::setPropertyId( rtl::OUString& ouPropertyId )
233 {
234 	InternalSignatureInformation &isi = m_vInternalSignatureInformations[m_vInternalSignatureInformations.size()-1];
235 	isi.signatureInfor.ouPropertyId = ouPropertyId;
236 }
237 
238 /* public: for signature verify */
239 void XSecController::collectToVerify( const rtl::OUString& referenceId )
240 {
241 	/* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */
242 
243 	if ( m_nStatusOfSecurityComponents == INITIALIZED )
244 	/*
245 	 * if all security components are ready, verify the signature.
246 	 */
247 	{
248 		bool bJustChainingOn = false;
249 		cssu::Reference< cssxs::XDocumentHandler > xHandler = NULL;
250 
251 		int i,j;
252 		int sigNum = m_vInternalSignatureInformations.size();
253 
254 		for (i=0; i<sigNum; ++i)
255 		{
256 			InternalSignatureInformation& isi = m_vInternalSignatureInformations[i];
257 			SignatureReferenceInformations& vReferenceInfors = isi.signatureInfor.vSignatureReferenceInfors;
258 			int refNum = vReferenceInfors.size();
259 
260 			for (j=0; j<refNum; ++j)
261 			{
262 				SignatureReferenceInformation &refInfor = vReferenceInfors[j];
263 
264 				if (refInfor.ouURI == referenceId)
265 				{
266 					if (chainOn(false))
267 					{
268 						bJustChainingOn = true;
269 						xHandler = m_xSAXEventKeeper->setNextHandler(NULL);
270 					}
271 
272 					sal_Int32 nKeeperId = m_xSAXEventKeeper->addSecurityElementCollector(
273 						cssxc::sax::ElementMarkPriority_BEFOREMODIFY, sal_False );
274 
275 					cssu::Reference<cssxc::sax::XReferenceResolvedBroadcaster> xReferenceResolvedBroadcaster
276 						(m_xSAXEventKeeper,
277 						cssu::UNO_QUERY );
278 
279 					cssu::Reference<cssxc::sax::XReferenceCollector> xReferenceCollector
280 						( isi.xReferenceResolvedListener, cssu::UNO_QUERY );
281 
282 					m_xSAXEventKeeper->setSecurityId(nKeeperId, isi.signatureInfor.nSecurityId);
283 					xReferenceResolvedBroadcaster->addReferenceResolvedListener( nKeeperId, isi.xReferenceResolvedListener);
284 					xReferenceCollector->setReferenceId( nKeeperId );
285 
286 					isi.vKeeperIds[j] = nKeeperId;
287 					break;
288 				}
289 			}
290 		}
291 
292 		if ( bJustChainingOn )
293 		{
294 			cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
295 			if (m_xElementStackKeeper.is())
296 			{
297 				m_xElementStackKeeper->retrieve(xSEKHandler, sal_True);
298 			}
299 			m_xSAXEventKeeper->setNextHandler(xHandler);
300 		}
301 	}
302 }
303 
304 void XSecController::addSignature( sal_Int32 nSignatureId )
305 {
306 	DBG_ASSERT( m_pXSecParser != NULL, "No XSecParser initialized" );
307 
308 	m_nReservedSignatureId = nSignatureId;
309 	m_bVerifyCurrentSignature = true;
310 }
311 
312 cssu::Reference< cssxs::XDocumentHandler > XSecController::createSignatureReader()
313 {
314 	m_pXSecParser = new XSecParser( this, NULL );
315 	cssu::Reference< cssl::XInitialization > xInitialization = m_pXSecParser;
316 
317 	setSAXChainConnector(xInitialization, NULL, NULL);
318 
319 	return m_pXSecParser;
320 }
321 
322 void XSecController::releaseSignatureReader()
323 {
324 	clearSAXChainConnector( );
325 	m_pXSecParser = NULL;
326 }
327 
328