1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xsecctl.hxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
34 #include <xmlsecurity/sigstruct.hxx>
36 #include <com/sun/star/uno/XComponentContext.hpp>
37 #include <com/sun/star/xml/sax/XParser.hpp>
38 #include <com/sun/star/lang/XInitialization.hpp>
39 #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
40 #include <com/sun/star/xml/sax/XAttributeList.hpp>
41 #include <com/sun/star/xml/crypto/XXMLSignature.hpp>
42 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
43 #include <com/sun/star/xml/crypto/sax/XSecurityController.hpp>
44 #include <com/sun/star/xml/crypto/sax/XElementStackKeeper.hpp>
45 #include <com/sun/star/xml/crypto/sax/XSecuritySAXEventKeeper.hpp>
46 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedListener.hpp>
47 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeListener.hpp>
48 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultListener.hpp>
49 #include <com/sun/star/xml/crypto/sax/XSignatureVerifyResultListener.hpp>
50 #include <com/sun/star/xml/wrapper/XXMLDocumentWrapper.hpp>
51 #include <com/sun/star/beans/XFastPropertySet.hpp>
52 #include <com/sun/star/io/XOutputStream.hpp>
53 #include <com/sun/star/io/XInputStream.hpp>
55 #include <rtl/ustrbuf.hxx>
57 #include <cppuhelper/implbase4.hxx>
59 #ifndef INCLUDED_VECTOR
61 #define INCLUDED_VECTOR
65 * all error information
67 #define ERROR_CANNOTCREATEXMLSECURITYCOMPONENT "Can't create XML security components."
68 #define ERROR_SAXEXCEPTIONDURINGCREATION "A SAX exception is throwed during signature creation."
69 #define ERROR_IOEXCEPTIONDURINGCREATION "An IO exception is throwed during signature creation."
70 #define ERROR_EXCEPTIONDURINGCREATION "An exception is throwed during signature creation."
73 * all stringS in signature element
75 #define TAG_SIGNATURE "Signature"
76 #define TAG_SIGNEDINFO "SignedInfo"
77 #define TAG_CANONICALIZATIONMETHOD "CanonicalizationMethod"
78 #define TAG_SIGNATUREMETHOD "SignatureMethod"
79 #define TAG_REFERENCE "Reference"
80 #define TAG_TRANSFORMS "Transforms"
81 #define TAG_TRANSFORM "Transform"
82 #define TAG_DIGESTMETHOD "DigestMethod"
83 #define TAG_DIGESTVALUE "DigestValue"
84 #define TAG_SIGNATUREVALUE "SignatureValue"
85 #define TAG_KEYINFO "KeyInfo"
86 #define TAG_X509DATA "X509Data"
87 #define TAG_X509ISSUERSERIAL "X509IssuerSerial"
88 #define TAG_X509ISSUERNAME "X509IssuerName"
89 #define TAG_X509SERIALNUMBER "X509SerialNumber"
90 #define TAG_X509CERTIFICATE "X509Certificate"
91 #define TAG_OBJECT "Object"
92 #define TAG_SIGNATUREPROPERTIES "SignatureProperties"
93 #define TAG_SIGNATUREPROPERTY "SignatureProperty"
94 #define TAG_TIMESTAMP "timestamp"
95 #define TAG_DATE "date"
96 //#define TAG_TIME "time"
98 #define ATTR_XMLNS "xmlns"
99 #define ATTR_ALGORITHM "Algorithm"
100 #define ATTR_URI "URI"
102 #define ATTR_TARGET "Target"
104 #define NSTAG_DC "dc"
106 #define NS_XMLDSIG "http://www.w3.org/2000/09/xmldsig#"
107 //#define NS_DATETIME "http://www.ietf.org/rfcXXXX.txt"
108 #define NS_DC "http://purl.org/dc/elements/1.1/"
110 #define ALGO_C14N "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"
111 #define ALGO_RSASHA1 "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
112 #define ALGO_XMLDSIGSHA1 "http://www.w3.org/2000/09/xmldsig#sha1"
114 #define CHAR_FRAGMENT "#"
115 #define CHAR_BLANK " "
119 * status of security related components
121 #define UNINITIALIZED 0
122 #define INITIALIZED 1
123 #define FAILTOINITIALIZED 2
125 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
127 // forward declaration
130 class InternalSignatureInformation
133 SignatureInformation signatureInfor
;
135 com::sun::star::uno::Reference
<
136 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
>
137 xReferenceResolvedListener
;
139 ::std::vector
< sal_Int32
> vKeeperIds
;
141 InternalSignatureInformation(
143 com::sun::star::uno::Reference
< com::sun::star::xml::crypto::sax::XReferenceResolvedListener
>
147 xReferenceResolvedListener
= xListener
;
150 void addReference( sal_Int32 type
, rtl::OUString uri
, sal_Int32 keeperId
)
152 signatureInfor
.vSignatureReferenceInfors
.push_back(
153 SignatureReferenceInformation(type
, uri
));
154 vKeeperIds
.push_back( keeperId
);
158 typedef ::std::vector
< InternalSignatureInformation
> InternalSignatureInformations
;
160 class XSecController
: public cppu::WeakImplHelper4
162 com::sun::star::xml::crypto::sax::XSecurityController
,
163 //com::sun::star::beans::XFastPropertySet,
164 com::sun::star::xml::crypto::sax::XSAXEventKeeperStatusChangeListener
,
165 com::sun::star::xml::crypto::sax::XSignatureCreationResultListener
,
166 com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener
168 /****** XSecController.hxx/CLASS XSecController *******************************
171 * XSecController -- the xml security framework controller
174 * Controlls the whole xml security framework to create signatures or to
178 * 05.01.2004 - Interface supported: XSecurityController,
179 * XFastPropertySet, XSAXEventKeeperStatusChangeListener,
180 * XSignatureCreationResultListener,
181 * XSignatureVerifyResultListener
184 * The XFastPropertySet interface is used to transfer common values to
185 * classes in other module, for instance, the signature id for all
186 * sessions is transferred to xmloff module through this interface.
190 * Email: michael.mi@sun.com
191 ******************************************************************************/
193 friend class XSecParser
;
196 com::sun::star::uno::Reference
< com::sun::star::uno::XComponentContext
> mxCtx
;
199 * used to buffer SAX events
201 com::sun::star::uno::Reference
<
202 com::sun::star::xml::wrapper::XXMLDocumentWrapper
> m_xXMLDocumentWrapper
;
205 * the SAX events keeper
207 com::sun::star::uno::Reference
<
208 com::sun::star::xml::crypto::sax::XSecuritySAXEventKeeper
> m_xSAXEventKeeper
;
211 * the bridge component which creates/verifies signature
213 com::sun::star::uno::Reference
<
214 com::sun::star::xml::crypto::XXMLSignature
> m_xXMLSignature
;
217 * the Security Context
219 com::sun::star::uno::Reference
<
220 com::sun::star::xml::crypto::XXMLSecurityContext
> m_xSecurityContext
;
224 * the signature creation result listener
226 com::sun::star::uno::Reference
<
227 com::sun::star::xml::crypto::sax::XSignatureCreationResultListener
> m_xSignatureCreationResultListener
;
229 * the signature verify result listener
231 com::sun::star::uno::Reference
<
232 com::sun::star::xml::crypto::sax::XSignatureVerifyResultListener
> m_xSignatureVerifyResultListener
;
236 * the security id incrementer, in order to make any security id unique
237 * to the SAXEventKeeper.
238 * Because each XSecController has its own SAXEventKeeper, so this variable
239 * is not necessary to be static.
241 sal_Int32 m_nNextSecurityId
;
244 * Signature information
246 InternalSignatureInformations m_vInternalSignatureInformations
;
249 * the previous node on the SAX chain.
250 * The reason that use a Reference<XInterface> type variable
251 * is that the previous components are different when exporting
252 * and importing, and there is no other common interface they
255 com::sun::star::uno::Reference
<
256 com::sun::star::uno::XInterface
> m_xPreviousNodeOnSAXChain
;
258 * whether the preivous node can provide an XInitiazlize interface,
259 * use this variable in order to typecast the XInterface to the
260 * correct interface type.
262 bool m_bIsPreviousNodeInitializable
;
265 * the next node on the SAX chain.
266 * it can always provide an XDocumentHandler interface.
268 com::sun::star::uno::Reference
<
269 com::sun::star::xml::sax::XDocumentHandler
> m_xNextNodeOnSAXChain
;
272 * the ElementStackKeeper is used to reserve the key SAX events.
273 * when the SAXEventKeeper is chained on the SAX chain, it need
274 * first get all missed key SAX events in order to make sure the
275 * DOM tree it buffering has the same structure with the original
278 * For a given section of a SAX event stream, the key SAX events
279 * are the minimal SAX event subset of that section, which,
280 * combining with SAX events outside of this section, has the same
281 * structure with the original document.
283 * For example, sees the following dom fragment:
293 * If we consider the SAX event section from startElement(<A>) to
294 * startElement(<D>), then the key SAX events are:
296 * startElement(<A>), startElement(<C>), startElement(<D>)
298 * The startElement(<B>) and endElement(<B>) is ignored, because
299 * they are unimportant for the tree structure in this section.
301 * If we consider the SAX event section from startElement(<D>) to
302 * endElement(<A>), the key SAX events are:
304 * startElement(<D>), endElement(<D>), endElement(<C>),
307 com::sun::star::uno::Reference
<
308 com::sun::star::xml::crypto::sax::XElementStackKeeper
> m_xElementStackKeeper
;
311 * a flag representing whether the SAXEventKeeper is now on the
314 bool m_bIsSAXEventKeeperConnected
;
317 * a flag representing whether it is collecting some element,
318 * which means that the SAXEventKeeper can't be chained off the
321 bool m_bIsCollectingElement
;
324 * a flag representing whether the SAX event stream is blocking,
325 * which also means that the SAXEventKeeper can't be chained off
331 * a flag representing the current status of security related
334 sal_Int32 m_nStatusOfSecurityComponents
;
337 * a flag representing whether the SAXEventKeeper need to be
338 * on the SAX chain all the time.
339 * This flag is used to the situation when creating signature.
341 bool m_bIsSAXEventKeeperSticky
;
344 * fast property vector
346 std::vector
< sal_Int32
> m_vFastPropertyIndexs
;
347 std::vector
< com::sun::star::uno::Any
> m_vFastPropertyValues
;
350 * error message pointer
352 const char *m_pErrorMessage
;
355 * the XSecParser which is used to parse the signature stream
357 XSecParser
*m_pXSecParser
;
360 * the caller assigned signature id for the next signature in the
363 sal_Int32 m_nReservedSignatureId
;
366 * representing whether to verify the current signature
368 bool m_bVerifyCurrentSignature
;
371 * An xUriBinding is provided to map Uris to XInputStream interfaces.
373 com::sun::star::uno::Reference
<
374 com::sun::star::xml::crypto::XUriBinding
> m_xUriBinding
;
381 sal_Bool
convertNumber( sal_Int32
& rValue
, const rtl::OUString
& rString
, sal_Int32 nMin
, sal_Int32 nMax
);
382 void convertDateTime( ::rtl::OUStringBuffer
& rBuffer
, const com::sun::star::util::DateTime
& rDateTime
);
383 sal_Bool
convertDateTime( com::sun::star::util::DateTime
& rDateTime
, const ::rtl::OUString
& rString
);
385 void createXSecComponent( );
386 int findSignatureInfor( sal_Int32 nSecurityId
) const;
387 bool chainOn( bool bRetrievingLastEvent
);
389 void checkChainingStatus();
390 void initializeSAXChain();
392 com::sun::star::uno::Reference
<
393 com::sun::star::io::XInputStream
> getObjectInputStream( const rtl::OUString
& objectURL
);
395 //sal_Int32 getFastPropertyIndex(sal_Int32 nHandle) const;
398 * For signature generation
400 rtl::OUString
createId();
401 com::sun::star::uno::Reference
<
402 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
> prepareSignatureToWrite(
403 InternalSignatureInformation
& signatureInfo
);
406 * For signature verification
409 void addReference( const rtl::OUString
& ouUri
);
410 void addStreamReference(
411 const rtl::OUString
& ouUri
,
413 void setReferenceCount() const;
415 void setX509IssuerName( rtl::OUString
& ouX509IssuerName
);
416 void setX509SerialNumber( rtl::OUString
& ouX509SerialNumber
);
417 void setX509Certificate( rtl::OUString
& ouX509Certificate
);
418 void setSignatureValue( rtl::OUString
& ouSignatureValue
);
419 void setDigestValue( rtl::OUString
& ouDigestValue
);
421 void setDate( rtl::OUString
& ouDate
);
423 void setId( rtl::OUString
& ouId
);
424 void setPropertyId( rtl::OUString
& ouPropertyId
);
426 com::sun::star::uno::Reference
<
427 com::sun::star::xml::crypto::sax::XReferenceResolvedListener
> prepareSignatureToRead(
428 sal_Int32 nSecurityId
);
431 XSecController(const com::sun::star::uno::Reference
<com::sun::star::uno::XComponentContext
>& rxCtx
);
434 sal_Int32
getNewSecurityId( );
436 void startMission( const com::sun::star::uno::Reference
<
437 com::sun::star::xml::crypto::XUriBinding
>& xUriBinding
,
438 const com::sun::star::uno::Reference
<
439 com::sun::star::xml::crypto::XXMLSecurityContext
>& xSecurityContext
);
441 void setSAXChainConnector(
442 const com::sun::star::uno::Reference
<
443 com::sun::star::lang::XInitialization
>& xInitialization
,
444 const com::sun::star::uno::Reference
<
445 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
,
446 const com::sun::star::uno::Reference
<
447 com::sun::star::xml::crypto::sax::XElementStackKeeper
>& xElementStackKeeper
);
449 void setSAXChainConnector(
450 const com::sun::star::uno::Reference
<
451 com::sun::star::xml::sax::XParser
>& xParser
,
452 const com::sun::star::uno::Reference
<
453 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
,
454 const com::sun::star::uno::Reference
<
455 com::sun::star::xml::crypto::sax::XElementStackKeeper
>& xElementStackKeeper
);
457 void clearSAXChainConnector();
459 const char* getErrorMessage();
461 SignatureInformation
getSignatureInformation( sal_Int32 nSecurityId
) const;
462 SignatureInformations
getSignatureInformations() const;
464 void exportSignature(
465 const com::sun::star::uno::Reference
<
466 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
,
467 const SignatureInformation
& signatureInfo
);
471 * For signature generation
473 void collectToSign( sal_Int32 securityId
, const rtl::OUString
& referenceId
);
474 void signAStream( sal_Int32 securityId
, const rtl::OUString
& uri
, const rtl::OUString
& objectURL
, sal_Bool isBinary
);
477 /** sets data that describes the certificate.
479 It is absolutely necessary that the parameter ouX509IssuerName is set. It contains
480 the base64 encoded certificate, which is DER encoded. The XMLSec needs it to find
481 the private key. Although issuer name and certificate should be sufficient to identify
482 the certificate the implementation in XMLSec is broken, both for Windows and mozilla.
483 The reason is that they use functions to find the certificate which take as parameter
484 the DER encoded ASN.1 issuer name. The issuer name is a DName, where most attributes
485 are of type DirectoryName, which is a choice of 5 string types. This information is
486 not contained in the issuer string and while it is converted to the ASN.1 name the
487 conversion function must assume a particular type, which is often wrong. For example,
488 the Windows function CertStrToName will use a T.61 string if the string does not contain
489 special characters. So if the certificate uses simple characters but encodes the
490 issuer attributes in Utf8, then CertStrToName will use T.61. The resulting DER encoded
491 ASN.1 name now contains different bytes which indicate the string type. The functions
492 for finding the certificate apparently use memcmp - hence they fail to find the
495 void setX509Certificate(
496 sal_Int32 nSecurityId
,
497 const rtl::OUString
& ouX509IssuerName
,
498 const rtl::OUString
& ouX509SerialNumber
,
499 const rtl::OUString
& ouX509Cert
);
500 // see the other setX509Certifcate function
501 void setX509Certificate(
502 sal_Int32 nSecurityId
,
503 const sal_Int32 nSecurityEnvironmentIndex
,
504 const rtl::OUString
& ouX509IssuerName
,
505 const rtl::OUString
& ouX509SerialNumber
,
506 const rtl::OUString
& ouX509Cert
);
509 sal_Int32 nSecurityId
,
510 const ::com::sun::star::util::DateTime
& rDateTime
);
514 const com::sun::star::uno::Reference
<
515 com::sun::star::xml::sax::XDocumentHandler
>& xDocumentHandler
);
518 * For signature verification
520 void collectToVerify( const rtl::OUString
& referenceId
);
521 void addSignature( sal_Int32 nSignatureId
);
522 com::sun::star::uno::Reference
< com::sun::star::xml::sax::XDocumentHandler
> createSignatureReader();
523 void releaseSignatureReader();
526 /* Interface methods */
529 * XSecurityController
531 * no method in XSecurityController interface
538 virtual void SAL_CALL setFastPropertyValue(
540 const com::sun::star::uno::Any& aValue )
542 com::sun::star::beans::UnknownPropertyException,
543 com::sun::star::beans::PropertyVetoException,
544 com::sun::star::lang::IllegalArgumentException,
545 com::sun::star::lang::WrappedTargetException,
546 com::sun::star::uno::RuntimeException);
547 virtual com::sun::star::uno::Any SAL_CALL getFastPropertyValue(
550 com::sun::star::beans::UnknownPropertyException,
551 com::sun::star::lang::WrappedTargetException,
552 com::sun::star::uno::RuntimeException);
556 * XSAXEventKeeperStatusChangeListener
558 virtual void SAL_CALL
blockingStatusChanged( sal_Bool isBlocking
)
559 throw (com::sun::star::uno::RuntimeException
);
560 virtual void SAL_CALL
collectionStatusChanged(
561 sal_Bool isInsideCollectedElement
)
562 throw (com::sun::star::uno::RuntimeException
);
563 virtual void SAL_CALL
bufferStatusChanged( sal_Bool isBufferEmpty
)
564 throw (com::sun::star::uno::RuntimeException
);
567 * XSignatureCreationResultListener
569 virtual void SAL_CALL
signatureCreated( sal_Int32 securityId
, com::sun::star::xml::crypto::SecurityOperationStatus nResult
)
570 throw (com::sun::star::uno::RuntimeException
);
573 * XSignatureVerifyResultListener
575 virtual void SAL_CALL
signatureVerified( sal_Int32 securityId
, com::sun::star::xml::crypto::SecurityOperationStatus nResult
)
576 throw (com::sun::star::uno::RuntimeException
);