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