1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
31 #include <xmlsecurity/sigstruct.hxx>
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>
52 #include <rtl/ustrbuf.hxx>
54 #include <cppuhelper/implbase4.hxx>
56 #ifndef INCLUDED_VECTOR
58 #define INCLUDED_VECTOR
62 * all error information
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."
70 * all stringS in signature element
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"
95 #define ATTR_XMLNS "xmlns"
96 #define ATTR_ALGORITHM "Algorithm"
97 #define ATTR_URI "URI"
99 #define ATTR_TARGET "Target"
101 #define NSTAG_DC "dc"
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/"
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"
111 #define CHAR_FRAGMENT "#"
112 #define CHAR_BLANK " "
116 * status of security related components
118 #define UNINITIALIZED 0
119 #define INITIALIZED 1
120 #define FAILTOINITIALIZED 2
122 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
124 // forward declaration
127 class InternalSignatureInformation
130 SignatureInformation signatureInfor
;
132 com::sun::star::uno::Reference
<
133 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
>
134 xReferenceResolvedListener
;
136 ::std::vector
< sal_Int32
> vKeeperIds
;
138 InternalSignatureInformation(
140 com::sun::star::uno::Reference
< com::sun::star::xml::crypto::sax::XReferenceResolvedListener
>
144 xReferenceResolvedListener
= xListener
;
147 void addReference( sal_Int32 type
, rtl::OUString uri
, sal_Int32 keeperId
)
149 signatureInfor
.vSignatureReferenceInfors
.push_back(
150 SignatureReferenceInformation(type
, uri
));
151 vKeeperIds
.push_back( keeperId
);
155 typedef ::std::vector
< InternalSignatureInformation
> InternalSignatureInformations
;
157 class XSecController
: public cppu::WeakImplHelper4
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
165 /****** XSecController.hxx/CLASS XSecController *******************************
168 * XSecController -- the xml security framework controller
171 * Controlls the whole xml security framework to create signatures or to
175 * 05.01.2004 - Interface supported: XSecurityController,
176 * XFastPropertySet, XSAXEventKeeperStatusChangeListener,
177 * XSignatureCreationResultListener,
178 * XSignatureVerifyResultListener
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.
187 * Email: michael.mi@sun.com
188 ******************************************************************************/
190 friend class XSecParser
;
193 com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> mxCtx
;
196 * used to buffer SAX events
198 com::sun::star::uno::Reference
<
199 com::sun::star::xml::wrapper::XXMLDocumentWrapper
> m_xXMLDocumentWrapper
;
202 * the SAX events keeper
204 com::sun::star::uno::Reference
<
205 com::sun::star::xml::crypto::sax::XSecuritySAXEventKeeper
> m_xSAXEventKeeper
;
208 * the bridge component which creates/verifies signature
210 com::sun::star::uno::Reference
<
211 com::sun::star::xml::crypto::XXMLSignature
> m_xXMLSignature
;
214 * the Security Context
216 com::sun::star::uno::Reference
<
217 com::sun::star::xml::crypto::XXMLSecurityContext
> m_xSecurityContext
;
221 * the signature creation result listener
223 com::sun::star::uno::Reference
<
224 com::sun::star::xml::crypto::sax::XSignatureCreationResultListener
> m_xSignatureCreationResultListener
;
226 * the signature verify result listener
228 com::sun::star::uno::Reference
<
229 com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener
> m_xSignatureVerifyResultListener
;
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.
238 sal_Int32 m_nNextSecurityId
;
241 * Signature information
243 InternalSignatureInformations m_vInternalSignatureInformations
;
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
252 com::sun::star::uno::Reference
<
253 com::sun::star::uno::XInterface
> m_xPreviousNodeOnSAXChain
;
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.
259 bool m_bIsPreviousNodeInitializable
;
262 * the next node on the SAX chain.
263 * it can always provide an XDocumentHandler interface.
265 com::sun::star::uno::Reference
<
266 com::sun::star::xml::sax::XDocumentHandler
> m_xNextNodeOnSAXChain
;
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
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.
280 * For example, sees the following dom fragment:
290 * If we consider the SAX event section from startElement(<A>) to
291 * startElement(<D>), then the key SAX events are:
293 * startElement(<A>), startElement(<C>), startElement(<D>)
295 * The startElement(<B>) and endElement(<B>) is ignored, because
296 * they are unimportant for the tree structure in this section.
298 * If we consider the SAX event section from startElement(<D>) to
299 * endElement(<A>), the key SAX events are:
301 * startElement(<D>), endElement(<D>), endElement(<C>),
304 com::sun::star::uno::Reference
<
305 com::sun::star::xml::crypto::sax::XElementStackKeeper
> m_xElementStackKeeper
;
308 * a flag representing whether the SAXEventKeeper is now on the
311 bool m_bIsSAXEventKeeperConnected
;
314 * a flag representing whether it is collecting some element,
315 * which means that the SAXEventKeeper can't be chained off the
318 bool m_bIsCollectingElement
;
321 * a flag representing whether the SAX event stream is blocking,
322 * which also means that the SAXEventKeeper can't be chained off
328 * a flag representing the current status of security related
331 sal_Int32 m_nStatusOfSecurityComponents
;
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.
338 bool m_bIsSAXEventKeeperSticky
;
341 * fast property vector
343 std::vector
< sal_Int32
> m_vFastPropertyIndexs
;
344 std::vector
< com::sun::star::uno::Any
> m_vFastPropertyValues
;
347 * error message pointer
349 const char *m_pErrorMessage
;
352 * the XSecParser which is used to parse the signature stream
354 XSecParser
*m_pXSecParser
;
357 * the caller assigned signature id for the next signature in the
360 sal_Int32 m_nReservedSignatureId
;
363 * representing whether to verify the current signature
365 bool m_bVerifyCurrentSignature
;
368 * An xUriBinding is provided to map Uris to XInputStream interfaces.
370 com::sun::star::uno::Reference
<
371 com::sun::star::xml::crypto::XUriBinding
> m_xUriBinding
;
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
);
382 void createXSecComponent( );
383 int findSignatureInfor( sal_Int32 nSecurityId
) const;
384 bool chainOn( bool bRetrievingLastEvent
);
386 void checkChainingStatus();
387 void initializeSAXChain();
389 com::sun::star::uno::Reference
<
390 com::sun::star::io::XInputStream
> getObjectInputStream( const rtl::OUString
& objectURL
);
392 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
395 * For signature generation
397 rtl::OUString
createId();
398 com::sun::star::uno::Reference
<
399 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
> prepareSignatureToWrite(
400 InternalSignatureInformation
& signatureInfo
);
403 * For signature verification
406 void addReference( const rtl::OUString
& ouUri
);
407 void addStreamReference(
408 const rtl::OUString
& ouUri
,
410 void setReferenceCount() const;
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
);
418 void setDate( rtl::OUString
& ouDate
);
420 void setId( rtl::OUString
& ouId
);
421 void setPropertyId( rtl::OUString
& ouPropertyId
);
423 com::sun::star::uno::Reference
<
424 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
> prepareSignatureToRead(
425 sal_Int32 nSecurityId
);
428 XSecController(const com::sun::star::uno::Reference
<com::sun::star::uno::XComponentContext
>& rxCtx
);
431 sal_Int32
getNewSecurityId( );
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
);
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
);
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
);
454 void clearSAXChainConnector();
456 const char* getErrorMessage();
458 SignatureInformation
getSignatureInformation( sal_Int32 nSecurityId
) const;
459 SignatureInformations
getSignatureInformations() const;
461 void exportSignature(
462 const com::sun::star::uno::Reference
<
463 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
,
464 const SignatureInformation
& signatureInfo
);
468 * For signature generation
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
);
474 /** sets data that describes the certificate.
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
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
);
506 sal_Int32 nSecurityId
,
507 const ::com::sun::star::util::DateTime
& rDateTime
);
511 const com::sun::star::uno::Reference
<
512 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
);
515 * For signature verification
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();
523 /* Interface methods */
526 * XSecurityController
528 * no method in XSecurityController interface
535 virtual void SAL_CALL setFastPropertyValue(
537 const com::sun::star::uno::Any& aValue )
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(
547 com::sun::star::beans::UnknownPropertyException,
548 com::sun::star::lang::WrappedTargetException,
549 com::sun::star::uno::RuntimeException);
553 * XSAXEventKeeperStatusChangeListener
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
);
564 * XSignatureCreationResultListener
566 virtual void SAL_CALL
signatureCreated( sal_Int32 securityId
, com::sun::star::xml::crypto::SecurityOperationStatus nResult
)
567 throw (com::sun::star::uno::RuntimeException
);
570 * XSignatureVerifyResultListener
572 virtual void SAL_CALL
signatureVerified( sal_Int32 securityId
, com::sun::star::xml::crypto::SecurityOperationStatus nResult
)
573 throw (com::sun::star::uno::RuntimeException
);