xref: /trunk/main/xmlsecurity/source/helper/xsecctl.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #ifndef _XSEC_CTL_HXX
29 #define _XSEC_CTL_HXX
30 
31 #include <xmlsecurity/sigstruct.hxx>
32 
33 #include <com/sun/star/uno/XComponentContext.hpp>
34 #include <com/sun/star/xml/sax/XParser.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
37 #include <com/sun/star/xml/sax/XAttributeList.hpp>
38 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
39 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
40 #include <com/sun/star/xml/crypto/sax/XSecurityController.hpp>
41 #include <com/sun/star/xml/crypto/sax/XElementStackKeeper.hpp>
42 #include <com/sun/star/xml/crypto/sax/XSecuritySAXEventKeeper.hpp>
43 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedListener.hpp>
44 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeListener.hpp>
45 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp>
46 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp>
47 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp>
48 #include <com/sun/star/beans/XFastPropertySet.hpp>
49 #include <com/sun/star/io/XOutputStream.hpp>
50 #include <com/sun/star/io/XInputStream.hpp>
51 
52 #include <rtl/ustrbuf.hxx>
53 
54 #include <cppuhelper/implbase4.hxx>
55 
56 #ifndef INCLUDED_VECTOR
57 #include <vector>
58 #define INCLUDED_VECTOR
59 #endif
60 
61 /*
62  * all error information
63  */
64 #define ERROR_CANNOTCREATEXMLSECURITYCOMPONENT    "Can't create XML security components."
65 #define ERROR_SAXEXCEPTIONDURINGCREATION          "A SAX exception is throwed during signature creation."
66 #define ERROR_IOEXCEPTIONDURINGCREATION           "An IO exception is throwed during signature creation."
67 #define ERROR_EXCEPTIONDURINGCREATION             "An exception is throwed during signature creation."
68 
69 /*
70  * all stringS in signature element
71  */
72 #define TAG_SIGNATURE           "Signature"
73 #define TAG_SIGNEDINFO          "SignedInfo"
74 #define TAG_CANONICALIZATIONMETHOD  "CanonicalizationMethod"
75 #define TAG_SIGNATUREMETHOD     "SignatureMethod"
76 #define TAG_REFERENCE           "Reference"
77 #define TAG_TRANSFORMS          "Transforms"
78 #define TAG_TRANSFORM           "Transform"
79 #define TAG_DIGESTMETHOD        "DigestMethod"
80 #define TAG_DIGESTVALUE         "DigestValue"
81 #define TAG_SIGNATUREVALUE      "SignatureValue"
82 #define TAG_KEYINFO         "KeyInfo"
83 #define TAG_X509DATA            "X509Data"
84 #define TAG_X509ISSUERSERIAL        "X509IssuerSerial"
85 #define TAG_X509ISSUERNAME      "X509IssuerName"
86 #define TAG_X509SERIALNUMBER        "X509SerialNumber"
87 #define TAG_X509CERTIFICATE     "X509Certificate"
88 #define TAG_OBJECT          "Object"
89 #define TAG_SIGNATUREPROPERTIES     "SignatureProperties"
90 #define TAG_SIGNATUREPROPERTY       "SignatureProperty"
91 #define TAG_TIMESTAMP           "timestamp"
92 #define TAG_DATE            "date"
93 //#define TAG_TIME          "time"
94 
95 #define ATTR_XMLNS          "xmlns"
96 #define ATTR_ALGORITHM          "Algorithm"
97 #define ATTR_URI            "URI"
98 #define ATTR_ID             "Id"
99 #define ATTR_TARGET         "Target"
100 
101 #define NSTAG_DC            "dc"
102 
103 #define NS_XMLDSIG          "http://www.w3.org/2000/09/xmldsig#"
104 //#define NS_DATETIME           "http://www.ietf.org/rfcXXXX.txt"
105 #define NS_DC               "http://purl.org/dc/elements/1.1/"
106 
107 #define ALGO_C14N           "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
108 #define ALGO_RSASHA1            "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
109 #define ALGO_XMLDSIGSHA1        "http://www.w3.org/2000/09/xmldsig#sha1"
110 
111 #define CHAR_FRAGMENT           "#"
112 #define CHAR_BLANK          " "
113 
114 
115 /*
116  * status of security related components
117  */
118 #define UNINITIALIZED     0
119 #define INITIALIZED       1
120 #define FAILTOINITIALIZED 2
121 
122 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
123 
124 // forward declaration
125 class XSecParser;
126 
127 class InternalSignatureInformation
128 {
129 public:
130     SignatureInformation signatureInfor;
131 
132     com::sun::star::uno::Reference<
133         com::sun::star::xml::crypto::sax::XReferenceResolvedListener >
134         xReferenceResolvedListener;
135 
136     ::std::vector< sal_Int32 > vKeeperIds;
137 
138     InternalSignatureInformation(
139         sal_Int32 nId,
140         com::sun::star::uno::Reference< com::sun::star::xml::crypto::sax::XReferenceResolvedListener >
141             xListener)
142         :signatureInfor(nId)
143     {
144         xReferenceResolvedListener = xListener;
145     }
146 
147     void addReference( sal_Int32 type, rtl::OUString uri, sal_Int32 keeperId )
148     {
149         signatureInfor.vSignatureReferenceInfors.push_back(
150                 SignatureReferenceInformation(type, uri));
151         vKeeperIds.push_back( keeperId );
152     }
153 };
154 
155 typedef ::std::vector< InternalSignatureInformation > InternalSignatureInformations;
156 
157 class XSecController : public cppu::WeakImplHelper4
158 <
159     com::sun::star::xml::crypto::sax::XSecurityController,
160     //com::sun::star::beans::XFastPropertySet,
161     com::sun::star::xml::crypto::sax::XSAXEventKeeperStatusChangeListener,
162     com::sun::star::xml::crypto::sax::XSignatureCreationResultListener,
163     com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener
164 >
165 /****** XSecController.hxx/CLASS XSecController *******************************
166  *
167  *   NAME
168  *  XSecController -- the xml security framework controller
169  *
170  *   FUNCTION
171  *  Controlls the whole xml security framework to create signatures or to
172  *  verify signatures.
173  *
174  *   HISTORY
175  *  05.01.2004 -    Interface supported: XSecurityController,
176  *          XFastPropertySet, XSAXEventKeeperStatusChangeListener,
177  *                  XSignatureCreationResultListener,
178  *                  XSignatureVerifyResultListener
179  *
180  *   NOTES
181  *  The XFastPropertySet interface is used to transfer common values to
182  *  classes in other module, for instance, the signature id for all
183  *  sessions is transferred to xmloff module through this interface.
184  *
185  *   AUTHOR
186  *  Michael Mi
187  *  Email: michael.mi@sun.com
188  ******************************************************************************/
189 {
190     friend class XSecParser;
191 
192 private:
193     com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext> mxCtx;
194 
195     /*
196      * used to buffer SAX events
197      */
198     com::sun::star::uno::Reference<
199         com::sun::star::xml::wrapper::XXMLDocumentWrapper > m_xXMLDocumentWrapper;
200 
201     /*
202      * the SAX events keeper
203      */
204     com::sun::star::uno::Reference<
205         com::sun::star::xml::crypto::sax::XSecuritySAXEventKeeper > m_xSAXEventKeeper;
206 
207     /*
208      * the bridge component which creates/verifies signature
209      */
210     com::sun::star::uno::Reference<
211         com::sun::star::xml::crypto::XXMLSignature > m_xXMLSignature;
212 
213     /*
214      * the Security Context
215      */
216     com::sun::star::uno::Reference<
217         com::sun::star::xml::crypto::XXMLSecurityContext > m_xSecurityContext;
218 
219 #if 0
220     /*
221      * the signature creation result listener
222      */
223     com::sun::star::uno::Reference<
224         com::sun::star::xml::crypto::sax::XSignatureCreationResultListener > m_xSignatureCreationResultListener;
225     /*
226      * the signature verify result listener
227      */
228     com::sun::star::uno::Reference<
229         com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener > m_xSignatureVerifyResultListener;
230 #endif
231 
232     /*
233      * the security id incrementer, in order to make any security id unique
234      * to the SAXEventKeeper.
235      * Because each XSecController has its own SAXEventKeeper, so this variable
236      * is not necessary to be static.
237      */
238     sal_Int32 m_nNextSecurityId;
239 
240     /*
241      * Signature information
242      */
243     InternalSignatureInformations m_vInternalSignatureInformations;
244 
245     /*
246      * the previous node on the SAX chain.
247      * The reason that use a Reference<XInterface> type variable
248      * is that the previous components are different when exporting
249      * and importing, and there is no other common interface they
250      * can provided.
251      */
252     com::sun::star::uno::Reference<
253         com::sun::star::uno::XInterface > m_xPreviousNodeOnSAXChain;
254     /*
255      * whether the preivous node can provide an XInitiazlize interface,
256      * use this variable in order to typecast the XInterface to the
257      * correct interface type.
258      */
259     bool m_bIsPreviousNodeInitializable;
260 
261     /*
262      * the next node on the SAX chain.
263      * it can always provide an XDocumentHandler interface.
264      */
265     com::sun::star::uno::Reference<
266         com::sun::star::xml::sax::XDocumentHandler > m_xNextNodeOnSAXChain;
267 
268     /*
269      * the ElementStackKeeper is used to reserve the key SAX events.
270      * when the SAXEventKeeper is chained on the SAX chain, it need
271      * first get all missed key SAX events in order to make sure the
272      * DOM tree it buffering has the same structure with the original
273      * document.
274      *
275      * For a given section of a SAX event stream, the key SAX events
276      * are the minimal SAX event subset of that section, which,
277      * combining with SAX events outside of this section, has the same
278      * structure with the original document.
279      *
280      * For example, sees the following dom fragment:
281      *     <A>
282      *      <B/>
283      *      <C>
284      *       <D>
285      *        <E/>
286      *       </D>
287      *      </C>
288      *     </A>
289      *
290      * If we consider the SAX event section from startElement(<A>) to
291      * startElement(<D>), then the key SAX events are:
292      *
293      *    startElement(<A>), startElement(<C>), startElement(<D>)
294      *
295      * The startElement(<B>) and endElement(<B>) is ignored, because
296      * they are unimportant for the tree structure in this section.
297      *
298      * If we consider the SAX event section from startElement(<D>) to
299      * endElement(<A>), the key SAX events are:
300      *
301      *    startElement(<D>), endElement(<D>), endElement(<C>),
302      *    endElement(<A>).
303      */
304     com::sun::star::uno::Reference<
305         com::sun::star::xml::crypto::sax::XElementStackKeeper > m_xElementStackKeeper;
306 
307     /*
308      * a flag representing whether the SAXEventKeeper is now on the
309      * SAX chain.
310      */
311     bool m_bIsSAXEventKeeperConnected;
312 
313     /*
314      * a flag representing whether it is collecting some element,
315      * which means that the SAXEventKeeper can't be chained off the
316      * SAX chain.
317      */
318     bool m_bIsCollectingElement;
319 
320     /*
321      * a flag representing whether the SAX event stream is blocking,
322      * which also means that the SAXEventKeeper can't be chained off
323      * the SAX chain.
324      */
325     bool m_bIsBlocking;
326 
327     /*
328      * a flag representing the current status of security related
329      * components.
330      */
331     sal_Int32 m_nStatusOfSecurityComponents;
332 
333     /*
334      * a flag representing whether the SAXEventKeeper need to be
335      * on the SAX chain all the time.
336      * This flag is used to the situation when creating signature.
337      */
338     bool m_bIsSAXEventKeeperSticky;
339 
340     /*
341      * fast property vector
342      */
343     std::vector< sal_Int32 > m_vFastPropertyIndexs;
344     std::vector< com::sun::star::uno::Any > m_vFastPropertyValues;
345 
346     /*
347      * error message pointer
348      */
349     const char *m_pErrorMessage;
350 
351     /*
352      * the XSecParser which is used to parse the signature stream
353      */
354     XSecParser *m_pXSecParser;
355 
356     /*
357      * the caller assigned signature id for the next signature in the
358      * signature stream
359      */
360     sal_Int32 m_nReservedSignatureId;
361 
362     /*
363      * representing whether to verify the current signature
364      */
365     bool m_bVerifyCurrentSignature;
366 public:
367     /*
368      * An xUriBinding is provided to map Uris to XInputStream interfaces.
369      */
370     com::sun::star::uno::Reference<
371         com::sun::star::xml::crypto::XUriBinding > m_xUriBinding;
372 
373 private:
374 
375     /*
376      * Common methods
377      */
378     sal_Bool convertNumber( sal_Int32& rValue, const rtl::OUString& rString, sal_Int32 nMin, sal_Int32 nMax );
379     void convertDateTime( ::rtl::OUStringBuffer& rBuffer, const com::sun::star::util::DateTime& rDateTime );
380     sal_Bool convertDateTime( com::sun::star::util::DateTime& rDateTime, const ::rtl::OUString& rString );
381 
382     void createXSecComponent( );
383     int findSignatureInfor( sal_Int32 nSecurityId ) const;
384     bool chainOn( bool bRetrievingLastEvent );
385     void chainOff();
386     void checkChainingStatus();
387     void initializeSAXChain();
388 
389     com::sun::star::uno::Reference<
390         com::sun::star::io::XInputStream > getObjectInputStream( const rtl::OUString& objectURL );
391 
392         //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
393 
394     /*
395      * For signature generation
396      */
397     rtl::OUString createId();
398     com::sun::star::uno::Reference<
399         com::sun::star::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToWrite(
400         InternalSignatureInformation& signatureInfo );
401 
402     /*
403      * For signature verification
404      */
405     void addSignature();
406     void addReference( const rtl::OUString& ouUri);
407     void addStreamReference(
408         const rtl::OUString& ouUri,
409         bool isBinary );
410     void setReferenceCount() const;
411 
412     void setX509IssuerName( rtl::OUString& ouX509IssuerName );
413     void setX509SerialNumber( rtl::OUString& ouX509SerialNumber );
414     void setX509Certificate( rtl::OUString& ouX509Certificate );
415     void setSignatureValue( rtl::OUString& ouSignatureValue );
416     void setDigestValue( rtl::OUString& ouDigestValue );
417 
418     void setDate( rtl::OUString& ouDate );
419 
420     void setId( rtl::OUString& ouId );
421     void setPropertyId( rtl::OUString& ouPropertyId );
422 
423     com::sun::star::uno::Reference<
424         com::sun::star::xml::crypto::sax::XReferenceResolvedListener > prepareSignatureToRead(
425         sal_Int32 nSecurityId );
426 
427 public:
428     XSecController(const com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext>& rxCtx);
429     ~XSecController();
430 
431     sal_Int32 getNewSecurityId(  );
432 
433     void startMission( const com::sun::star::uno::Reference<
434         com::sun::star::xml::crypto::XUriBinding >& xUriBinding,
435         const com::sun::star::uno::Reference<
436             com::sun::star::xml::crypto::XXMLSecurityContext >& xSecurityContext );
437 
438     void setSAXChainConnector(
439         const com::sun::star::uno::Reference<
440             com::sun::star::lang::XInitialization >& xInitialization,
441         const com::sun::star::uno::Reference<
442             com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler,
443         const com::sun::star::uno::Reference<
444             com::sun::star::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper);
445 
446     void setSAXChainConnector(
447         const com::sun::star::uno::Reference<
448             com::sun::star::xml::sax::XParser >& xParser,
449         const com::sun::star::uno::Reference<
450             com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler,
451         const com::sun::star::uno::Reference<
452             com::sun::star::xml::crypto::sax::XElementStackKeeper >& xElementStackKeeper);
453 
454     void clearSAXChainConnector();
455     void endMission();
456     const char* getErrorMessage();
457 
458     SignatureInformation    getSignatureInformation( sal_Int32 nSecurityId ) const;
459     SignatureInformations   getSignatureInformations() const;
460 
461     void exportSignature(
462         const com::sun::star::uno::Reference<
463             com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler,
464         const SignatureInformation& signatureInfo );
465 
466 
467     /*
468      * For signature generation
469      */
470     void collectToSign( sal_Int32 securityId, const rtl::OUString& referenceId );
471     void signAStream( sal_Int32 securityId, const rtl::OUString& uri, const rtl::OUString& objectURL, sal_Bool isBinary);
472 
473 
474     /** sets data that describes the certificate.
475 
476         It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
477         the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
478         the private key. Although issuer name and certificate should be sufficient to identify
479         the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
480         The reason is that they use functions to find the certificate which take as parameter
481         the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
482         are of type DirectoryName, which is a choice of 5 string types. This information is
483         not contained in the issuer string and while it is converted to the ASN.1 name the
484         conversion function must assume a particular type, which is often wrong. For example,
485         the Windows function CertStrToName will use a T.61 string if the string does not contain
486         special characters. So if the certificate uses simple characters but encodes the
487         issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
488         ASN.1 name now contains different bytes which indicate the string type. The functions
489         for finding the certificate apparently use memcmp - hence they fail to find the
490         certificate.
491      */
492     void setX509Certificate(
493         sal_Int32 nSecurityId,
494         const rtl::OUString& ouX509IssuerName,
495         const rtl::OUString& ouX509SerialNumber,
496         const rtl::OUString& ouX509Cert);
497     // see the other setX509Certifcate function
498     void setX509Certificate(
499         sal_Int32 nSecurityId,
500         const sal_Int32 nSecurityEnvironmentIndex,
501         const rtl::OUString& ouX509IssuerName,
502         const rtl::OUString& ouX509SerialNumber,
503         const rtl::OUString& ouX509Cert);
504 
505     void setDate(
506         sal_Int32 nSecurityId,
507         const ::com::sun::star::util::DateTime& rDateTime );
508 
509 
510     bool WriteSignature(
511         const com::sun::star::uno::Reference<
512             com::sun::star::xml::sax::XDocumentHandler >& xDocumentHandler );
513 
514     /*
515      * For signature verification
516      */
517     void collectToVerify( const rtl::OUString& referenceId );
518     void addSignature( sal_Int32 nSignatureId );
519     com::sun::star::uno::Reference< com::sun::star::xml::sax::XDocumentHandler > createSignatureReader();
520     void releaseSignatureReader();
521 
522 public:
523     /* Interface methods */
524 
525     /*
526      * XSecurityController
527      *
528      * no method in XSecurityController interface
529      */
530 
531     /*
532      * XFastPropertySet
533      */
534     /*
535     virtual void SAL_CALL setFastPropertyValue(
536         sal_Int32 nHandle,
537         const com::sun::star::uno::Any& aValue )
538         throw (
539             com::sun::star::beans::UnknownPropertyException,
540             com::sun::star::beans::PropertyVetoException,
541             com::sun::star::lang::IllegalArgumentException,
542             com::sun::star::lang::WrappedTargetException,
543             com::sun::star::uno::RuntimeException);
544     virtual com::sun::star::uno::Any SAL_CALL getFastPropertyValue(
545         sal_Int32 nHandle )
546         throw (
547             com::sun::star::beans::UnknownPropertyException,
548             com::sun::star::lang::WrappedTargetException,
549             com::sun::star::uno::RuntimeException);
550     */
551 
552     /*
553      * XSAXEventKeeperStatusChangeListener
554      */
555     virtual void SAL_CALL blockingStatusChanged( sal_Bool isBlocking )
556         throw (com::sun::star::uno::RuntimeException);
557     virtual void SAL_CALL collectionStatusChanged(
558         sal_Bool isInsideCollectedElement )
559         throw (com::sun::star::uno::RuntimeException);
560     virtual void SAL_CALL bufferStatusChanged( sal_Bool isBufferEmpty )
561         throw (com::sun::star::uno::RuntimeException);
562 
563     /*
564      * XSignatureCreationResultListener
565      */
566     virtual void SAL_CALL signatureCreated( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
567         throw (com::sun::star::uno::RuntimeException);
568 
569     /*
570      * XSignatureVerifyResultListener
571      */
572     virtual void SAL_CALL signatureVerified( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
573         throw (com::sun::star::uno::RuntimeException);
574 };
575 
576 #endif
577 
578