xref: /AOO41X/main/xmlsecurity/source/helper/xsecverify.cxx (revision 8167b394bd75b0ba1462b5f1ed80a6d339d0f4ec)
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