Version 4.0.2.1, tag libreoffice-4.0.2.1
[LibreOffice.git] / xmlsecurity / source / helper / xsecctl.cxx
blob56f4df3e838fb8a31b13965ce15750ffd4a40afc
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <xsecctl.hxx>
22 #include <tools/debug.hxx>
24 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
25 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
26 #include <com/sun/star/xml/crypto/sax/XMissionTaker.hpp>
27 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
28 #include <com/sun/star/xml/crypto/sax/XSAXEventKeeperStatusChangeBroadcaster.hpp>
29 #include <com/sun/star/xml/crypto/SecurityOperationStatus.hpp>
31 #include <xmloff/attrlist.hxx>
32 #include <rtl/math.hxx>
34 namespace cssu = com::sun::star::uno;
35 namespace cssl = com::sun::star::lang;
36 namespace cssxc = com::sun::star::xml::crypto;
37 namespace cssxs = com::sun::star::xml::sax;
38 namespace cssxw = com::sun::star::xml::wrapper;
40 const sal_Int8 XML_MAXDIGITSCOUNT_TIME = 11;
41 const sal_Int8 XML_MAXDIGITSCOUNT_DATETIME = 6;
43 /* bridge component names */
44 #define XMLSIGNATURE_COMPONENT "com.sun.star.xml.crypto.XMLSignature"
45 #define XMLDOCUMENTWRAPPER_COMPONENT "com.sun.star.xml.wrapper.XMLDocumentWrapper"
47 /* xml security framework components */
48 #define SAXEVENTKEEPER_COMPONENT "com.sun.star.xml.crypto.sax.SAXEventKeeper"
50 /* string for package protocol */
51 #define PACKAGEPROTOCOL "vnd.sun.star.Package:"
53 XSecController::XSecController( const cssu::Reference<cssu::XComponentContext>& rxCtx )
54 :mxCtx(rxCtx),
55 m_nNextSecurityId(1),
56 m_bIsSAXEventKeeperConnected(false),
57 m_nStatusOfSecurityComponents(UNINITIALIZED),
58 m_bIsSAXEventKeeperSticky(false),
59 m_pErrorMessage(NULL),
60 m_pXSecParser(NULL)
64 XSecController::~XSecController()
70 * private methods
72 /** convert string to number with optional min and max values */
73 sal_Bool XSecController::convertNumber( sal_Int32& rValue,
74 const rtl::OUString& rString,
75 sal_Int32 /*nMin*/, sal_Int32 /*nMax*/ )
77 sal_Bool bNeg = sal_False;
78 rValue = 0;
80 sal_Int32 nPos = 0L;
81 sal_Int32 nLen = rString.getLength();
83 // skip white space
84 while( nPos < nLen && sal_Unicode(' ') == rString[nPos] )
85 nPos++;
87 if( nPos < nLen && sal_Unicode('-') == rString[nPos] )
89 bNeg = sal_True;
90 nPos++;
93 // get number
94 while( nPos < nLen &&
95 sal_Unicode('0') <= rString[nPos] &&
96 sal_Unicode('9') >= rString[nPos] )
98 // TODO: check overflow!
99 rValue *= 10;
100 rValue += (rString[nPos] - sal_Unicode('0'));
101 nPos++;
104 if( bNeg )
105 rValue *= -1;
107 return nPos == nLen;
110 /** convert util::DateTime to ISO Date String */
111 void XSecController::convertDateTime( ::rtl::OUStringBuffer& rBuffer,
112 const com::sun::star::util::DateTime& rDateTime )
114 rBuffer.append((sal_Int32) rDateTime.Year);
115 rBuffer.append('-');
116 if( rDateTime.Month < 10 )
117 rBuffer.append('0');
118 rBuffer.append((sal_Int32) rDateTime.Month);
119 rBuffer.append('-');
120 if( rDateTime.Day < 10 )
121 rBuffer.append('0');
122 rBuffer.append((sal_Int32) rDateTime.Day);
124 if( rDateTime.Seconds != 0 ||
125 rDateTime.Minutes != 0 ||
126 rDateTime.Hours != 0 )
128 rBuffer.append('T');
129 if( rDateTime.Hours < 10 )
130 rBuffer.append('0');
131 rBuffer.append((sal_Int32) rDateTime.Hours);
132 rBuffer.append(':');
133 if( rDateTime.Minutes < 10 )
134 rBuffer.append('0');
135 rBuffer.append((sal_Int32) rDateTime.Minutes);
136 rBuffer.append(':');
137 if( rDateTime.Seconds < 10 )
138 rBuffer.append('0');
139 rBuffer.append((sal_Int32) rDateTime.Seconds);
140 if ( rDateTime.HundredthSeconds > 0)
142 rBuffer.append(',');
143 if (rDateTime.HundredthSeconds < 10)
144 rBuffer.append('0');
145 rBuffer.append((sal_Int32) rDateTime.HundredthSeconds);
150 /** convert ISO Date String to util::DateTime */
151 sal_Bool XSecController::convertDateTime( com::sun::star::util::DateTime& rDateTime,
152 const ::rtl::OUString& rString )
154 sal_Bool bSuccess = sal_True;
156 rtl::OUString aDateStr, aTimeStr, sHundredth;
157 sal_Int32 nPos = rString.indexOf( (sal_Unicode) 'T' );
158 sal_Int32 nPos2 = rString.indexOf( (sal_Unicode) ',' );
159 if ( nPos >= 0 )
161 aDateStr = rString.copy( 0, nPos );
162 if ( nPos2 >= 0 )
164 aTimeStr = rString.copy( nPos + 1, nPos2 - nPos - 1 );
166 //Get the fraction of a second with the accuracy of one hundreds second.
167 //The fraction part of the date could have different accuracies. To calculate
168 //the count of a hundredth units one could form a fractional number by appending
169 //the value of the time string to 0. Then multiply it by 100 and use only the whole number.
170 //For example: 5:27:46,1 -> 0,1 * 100 = 10
171 //5:27:46,01 -> 0,01 * 100 = 1
172 //5:27:46,001 -> 0,001 * 100 = 0
173 //Due to the inaccuracy of floating point numbers the result may not be the same on different
174 //platforms. We had the case where we had a value of 24 hundredth of second, which converted to
175 //23 on Linux and 24 on Solaris and Windows.
177 //we only support a hundredth second
178 //make ,1 -> 10 ,01 -> 1 ,001 -> only use first two diggits
179 sHundredth = rString.copy(nPos2 + 1);
180 sal_Int32 len = sHundredth.getLength();
181 if (len == 1)
182 sHundredth += rtl::OUString("0");
183 if (len > 2)
184 sHundredth = sHundredth.copy(0, 2);
186 else
188 aTimeStr = rString.copy(nPos + 1);
189 sHundredth = rtl::OUString("0");
192 else
193 aDateStr = rString; // no separator: only date part
195 sal_Int32 nYear = 1899;
196 sal_Int32 nMonth = 12;
197 sal_Int32 nDay = 30;
198 sal_Int32 nHour = 0;
199 sal_Int32 nMin = 0;
200 sal_Int32 nSec = 0;
202 const sal_Unicode* pStr = aDateStr.getStr();
203 sal_Int32 nDateTokens = 1;
204 while ( *pStr )
206 if ( *pStr == '-' )
207 nDateTokens++;
208 pStr++;
210 if ( nDateTokens > 3 || aDateStr.isEmpty() )
211 bSuccess = sal_False;
212 else
214 sal_Int32 n = 0;
215 if ( !convertNumber( nYear, aDateStr.getToken( 0, '-', n ), 0, 9999 ) )
216 bSuccess = sal_False;
217 if ( nDateTokens >= 2 )
218 if ( !convertNumber( nMonth, aDateStr.getToken( 0, '-', n ), 0, 12 ) )
219 bSuccess = sal_False;
220 if ( nDateTokens >= 3 )
221 if ( !convertNumber( nDay, aDateStr.getToken( 0, '-', n ), 0, 31 ) )
222 bSuccess = sal_False;
225 if ( !aTimeStr.isEmpty() ) // time is optional
227 pStr = aTimeStr.getStr();
228 sal_Int32 nTimeTokens = 1;
229 while ( *pStr )
231 if ( *pStr == ':' )
232 nTimeTokens++;
233 pStr++;
235 if ( nTimeTokens > 3 )
236 bSuccess = sal_False;
237 else
239 sal_Int32 n = 0;
240 if ( !convertNumber( nHour, aTimeStr.getToken( 0, ':', n ), 0, 23 ) )
241 bSuccess = sal_False;
242 if ( nTimeTokens >= 2 )
243 if ( !convertNumber( nMin, aTimeStr.getToken( 0, ':', n ), 0, 59 ) )
244 bSuccess = sal_False;
245 if ( nTimeTokens >= 3 )
246 if ( !convertNumber( nSec, aTimeStr.getToken( 0, ':', n ), 0, 59 ) )
247 bSuccess = sal_False;
251 if (bSuccess)
253 rDateTime.Year = (sal_uInt16)nYear;
254 rDateTime.Month = (sal_uInt16)nMonth;
255 rDateTime.Day = (sal_uInt16)nDay;
256 rDateTime.Hours = (sal_uInt16)nHour;
257 rDateTime.Minutes = (sal_uInt16)nMin;
258 rDateTime.Seconds = (sal_uInt16)nSec;
259 // rDateTime.HundredthSeconds = sDoubleStr.toDouble() * 100;
260 rDateTime.HundredthSeconds = static_cast<sal_uInt16>(sHundredth.toInt32());
262 return bSuccess;
265 int XSecController::findSignatureInfor( sal_Int32 nSecurityId) const
266 /****** XSecController/findSignatureInfor *************************************
268 * NAME
269 * findSignatureInfor -- find SignatureInformation struct for a particular
270 * signature
272 * SYNOPSIS
273 * index = findSignatureInfor( nSecurityId );
275 * FUNCTION
276 * see NAME.
278 * INPUTS
279 * nSecurityId - the signature's id
281 * RESULT
282 * index - the index of the signature, or -1 when no such signature
283 * existing
285 * AUTHOR
286 * Michael Mi
287 * Email: michael.mi@sun.com
288 ******************************************************************************/
290 int i;
291 int size = m_vInternalSignatureInformations.size();
293 for (i=0; i<size; ++i)
295 if (m_vInternalSignatureInformations[i].signatureInfor.nSecurityId == nSecurityId)
297 return i;
301 return -1;
304 void XSecController::createXSecComponent( )
305 /****** XSecController/createXSecComponent ************************************
307 * NAME
308 * bResult = createXSecComponent -- creates xml security components
310 * SYNOPSIS
311 * createXSecComponent( );
313 * FUNCTION
314 * Creates xml security components, including:
315 * 1. an xml signature bridge component ( Java based or C based)
316 * 2. an XMLDocumentWrapper component ( Java based or C based)
317 * 3. a SAXEventKeeper component
319 * INPUTS
320 * empty
322 * RESULT
323 * empty
325 * AUTHOR
326 * Michael Mi
327 * Email: michael.mi@sun.com
328 ******************************************************************************/
330 rtl::OUString sSAXEventKeeper( SAXEVENTKEEPER_COMPONENT );
331 rtl::OUString sXMLSignature( XMLSIGNATURE_COMPONENT );
332 rtl::OUString sXMLDocument( XMLDOCUMENTWRAPPER_COMPONENT );
335 * marks all security components are not available.
337 m_nStatusOfSecurityComponents = FAILTOINITIALIZED;
338 m_xXMLSignature = NULL;
339 m_xXMLDocumentWrapper = NULL;
340 m_xSAXEventKeeper = NULL;
342 cssu::Reference< cssl::XMultiComponentFactory > xMCF( mxCtx->getServiceManager() );
344 m_xXMLSignature = cssu::Reference< cssxc::XXMLSignature >(
345 xMCF->createInstanceWithContext( sXMLSignature, mxCtx ),
346 cssu::UNO_QUERY );
348 bool bSuccess = (0!=m_xXMLSignature.is());
349 if ( bSuccess )
351 * XMLSignature created successfully.
354 m_xXMLDocumentWrapper = cssu::Reference< cssxw::XXMLDocumentWrapper >(
355 xMCF->createInstanceWithContext( sXMLDocument, mxCtx ),
356 cssu::UNO_QUERY );
359 bSuccess &= (0!=m_xXMLDocumentWrapper.is());
360 if ( bSuccess )
362 * XMLDocumentWrapper created successfully.
365 m_xSAXEventKeeper = cssu::Reference< cssxc::sax::XSecuritySAXEventKeeper >(
366 xMCF->createInstanceWithContext( sSAXEventKeeper, mxCtx ),
367 cssu::UNO_QUERY );
370 bSuccess &= (0!=m_xSAXEventKeeper.is());
372 if (bSuccess)
374 * SAXEventKeeper created successfully.
377 cssu::Reference< cssl::XInitialization > xInitialization(m_xSAXEventKeeper, cssu::UNO_QUERY);
379 cssu::Sequence <cssu::Any> arg(1);
380 arg[0] = cssu::makeAny(m_xXMLDocumentWrapper);
381 xInitialization->initialize(arg);
383 cssu::Reference<cssxc::sax::XSAXEventKeeperStatusChangeBroadcaster>
384 xSAXEventKeeperStatusChangeBroadcaster(m_xSAXEventKeeper, cssu::UNO_QUERY);
385 cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >
386 xStatusChangeListener = this;
388 xSAXEventKeeperStatusChangeBroadcaster
389 ->addSAXEventKeeperStatusChangeListener( xStatusChangeListener );
391 m_nStatusOfSecurityComponents = INITIALIZED;
395 bool XSecController::chainOn( bool bRetrievingLastEvent )
396 /****** XSecController/chainOn ************************************************
398 * NAME
399 * chainOn -- tyies to connect the SAXEventKeeper with the SAX chain.
401 * SYNOPSIS
402 * bJustChainingOn = chainOn( bRetrievingLastEvent );
404 * FUNCTION
405 * First, checks whether the SAXEventKeeper is on the SAX chain. If not,
406 * creates xml security components, and chains the SAXEventKeeper into
407 * the SAX chain.
408 * Before being chained in, the SAXEventKeeper needs to receive all
409 * missed key SAX events, which can promise the DOM tree bufferred by the
410 * SAXEventKeeper has the same structure with the original document.
412 * INPUTS
413 * bRetrievingLastEvent - whether to retrieve the last key SAX event from
414 * the ElementStackKeeper.
416 * RESULT
417 * bJustChainingOn - whether the SAXEventKeeper is just chained into the
418 * SAX chain.
420 * NOTES
421 * Sometimes, the last key SAX event can't be transferred to the
422 * SAXEventKeeper together.
423 * For instance, at the time an referenced element is detected, the
424 * startElement event has already been reserved by the ElementStackKeeper.
425 * Meanwhile, an ElementCollector needs to be created before the
426 * SAXEventKeeper receives that startElement event.
427 * So for the SAXEventKeeper, it needs to receive all missed key SAX
428 * events except that startElement event, then adds a new
429 * ElementCollector, then receives that startElement event.
431 * AUTHOR
432 * Michael Mi
433 * Email: michael.mi@sun.com
434 ******************************************************************************/
436 bool rc = false;
438 if (!m_bIsSAXEventKeeperSticky && !m_bIsSAXEventKeeperConnected)
440 if ( m_nStatusOfSecurityComponents == UNINITIALIZED )
442 createXSecComponent();
445 if ( m_nStatusOfSecurityComponents == INITIALIZED )
447 * if all security components are ready, chains on the SAXEventKeeper
451 * disconnect the SAXEventKeeper with its current output handler,
452 * to make sure no SAX event is forwarded during the connecting
453 * phase.
455 m_xSAXEventKeeper->setNextHandler( NULL );
457 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
460 * connects the previous document handler on the SAX chain
462 if ( m_xPreviousNodeOnSAXChain.is() )
464 if ( m_bIsPreviousNodeInitializable )
466 cssu::Reference< cssl::XInitialization > xInitialization
467 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
469 cssu::Sequence<cssu::Any> aArgs( 1 );
470 aArgs[0] <<= xSEKHandler;
471 xInitialization->initialize(aArgs);
473 else
475 cssu::Reference< cssxs::XParser > xParser
476 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
477 xParser->setDocumentHandler( xSEKHandler );
482 * get missed key SAX events
484 if (m_xElementStackKeeper.is())
486 m_xElementStackKeeper->retrieve(xSEKHandler, bRetrievingLastEvent);
489 * now the ElementStackKeeper can stop its work, because the
490 * SAXEventKeeper is on the SAX chain, no SAX events will be
491 * missed.
493 m_xElementStackKeeper->stop();
497 * connects the next document handler on the SAX chain
499 m_xSAXEventKeeper->setNextHandler( m_xNextNodeOnSAXChain );
501 m_bIsSAXEventKeeperConnected = true;
503 rc = true;
507 return rc;
510 void XSecController::chainOff()
511 /****** XSecController/chainOff ***********************************************
513 * NAME
514 * chainOff -- disconnects the SAXEventKeeper from the SAX chain.
516 * SYNOPSIS
517 * chainOff( );
519 * FUNCTION
520 * See NAME.
522 * INPUTS
523 * empty
525 * RESULT
526 * empty
528 * AUTHOR
529 * Michael Mi
530 * Email: michael.mi@sun.com
531 ******************************************************************************/
533 if (!m_bIsSAXEventKeeperSticky )
535 if (m_bIsSAXEventKeeperConnected)
537 m_xSAXEventKeeper->setNextHandler( NULL );
539 if ( m_xPreviousNodeOnSAXChain.is() )
541 if ( m_bIsPreviousNodeInitializable )
543 cssu::Reference< cssl::XInitialization > xInitialization
544 (m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
546 cssu::Sequence<cssu::Any> aArgs( 1 );
547 aArgs[0] <<= m_xNextNodeOnSAXChain;
548 xInitialization->initialize(aArgs);
550 else
552 cssu::Reference< cssxs::XParser > xParser(m_xPreviousNodeOnSAXChain, cssu::UNO_QUERY);
553 xParser->setDocumentHandler( m_xNextNodeOnSAXChain );
557 if (m_xElementStackKeeper.is())
560 * start the ElementStackKeeper to reserve any possible
561 * missed key SAX events
563 m_xElementStackKeeper->start();
566 m_bIsSAXEventKeeperConnected = false;
571 void XSecController::checkChainingStatus()
572 /****** XSecController/checkChainingStatus ************************************
574 * NAME
575 * checkChainingStatus -- connects or disconnects the SAXEventKeeper
576 * according to the current situation.
578 * SYNOPSIS
579 * checkChainingStatus( );
581 * FUNCTION
582 * The SAXEventKeeper is chained into the SAX chain, when:
583 * 1. some element is being collected, or
584 * 2. the SAX event stream is blocking.
585 * Otherwise, chain off the SAXEventKeeper.
587 * INPUTS
588 * empty
590 * RESULT
591 * empty
593 * AUTHOR
594 * Michael Mi
595 * Email: michael.mi@sun.com
596 ******************************************************************************/
598 if ( m_bIsCollectingElement || m_bIsBlocking )
600 chainOn(true);
602 else
604 chainOff();
608 void XSecController::initializeSAXChain()
609 /****** XSecController/initializeSAXChain *************************************
611 * NAME
612 * initializeSAXChain -- initializes the SAX chain according to the
613 * current setting.
615 * SYNOPSIS
616 * initializeSAXChain( );
618 * FUNCTION
619 * Initializes the SAX chain, if the SAXEventKeeper is asked to be always
620 * on the SAX chain, chains it on. Otherwise, starts the
621 * ElementStackKeeper to reserve key SAX events.
623 * INPUTS
624 * empty
626 * RESULT
627 * empty
629 * AUTHOR
630 * Michael Mi
631 * Email: michael.mi@sun.com
632 ******************************************************************************/
634 m_bIsSAXEventKeeperConnected = false;
635 m_bIsCollectingElement = false;
636 m_bIsBlocking = false;
638 if (m_xElementStackKeeper.is())
641 * starts the ElementStackKeeper
643 m_xElementStackKeeper->start();
646 chainOff();
649 cssu::Reference< com::sun::star::io::XInputStream >
650 XSecController::getObjectInputStream( const rtl::OUString& objectURL )
651 /****** XSecController/getObjectInputStream ************************************
653 * NAME
654 * getObjectInputStream -- get a XInputStream interface from a SvStorage
656 * SYNOPSIS
657 * xInputStream = getObjectInputStream( objectURL );
659 * FUNCTION
660 * See NAME.
662 * INPUTS
663 * objectURL - the object uri
665 * RESULT
666 * xInputStream - the XInputStream interface
668 * AUTHOR
669 * Michael Mi
670 * Email: michael.mi@sun.com
671 ******************************************************************************/
673 cssu::Reference< com::sun::star::io::XInputStream > xObjectInputStream;
675 DBG_ASSERT( m_xUriBinding.is(), "Need XUriBinding!" );
677 xObjectInputStream = m_xUriBinding->getUriBinding(objectURL);
679 return xObjectInputStream;
683 * public methods
686 sal_Int32 XSecController::getNewSecurityId( )
688 sal_Int32 nId = m_nNextSecurityId;
689 m_nNextSecurityId++;
690 return nId;
693 void XSecController::startMission(
694 const cssu::Reference< cssxc::XUriBinding >& xUriBinding,
695 const cssu::Reference< cssxc::XXMLSecurityContext >& xSecurityContext )
696 /****** XSecController/startMission *******************************************
698 * NAME
699 * startMission -- starts a new security mission.
701 * SYNOPSIS
702 * startMission( xUriBinding, xSecurityContect );
704 * FUNCTION
705 * get ready for a new mission.
707 * INPUTS
708 * xUriBinding - the Uri binding that provide maps between uris and
709 * XInputStreams
710 * xSecurityContext - the security context component which can provide
711 * cryptoken
713 * RESULT
714 * empty
716 * AUTHOR
717 * Michael Mi
718 * Email: michael.mi@sun.com
719 ******************************************************************************/
721 m_xUriBinding = xUriBinding;
723 m_nStatusOfSecurityComponents = UNINITIALIZED;
724 m_xSecurityContext = xSecurityContext;
725 m_pErrorMessage = NULL;
727 m_vInternalSignatureInformations.clear();
729 m_bVerifyCurrentSignature = false;
732 void XSecController::setSAXChainConnector(
733 const cssu::Reference< cssl::XInitialization >& xInitialization,
734 const cssu::Reference< cssxs::XDocumentHandler >& xDocumentHandler,
735 const cssu::Reference< cssxc::sax::XElementStackKeeper >& xElementStackKeeper)
736 /****** XSecController/setSAXChainConnector ***********************************
738 * NAME
739 * setSAXChainConnector -- configures the components which will
740 * collaborate with the SAXEventKeeper on the SAX chain.
742 * SYNOPSIS
743 * setSAXChainConnector( xInitialization,
744 * xDocumentHandler,
745 * xElementStackKeeper );
747 * FUNCTION
748 * See NAME.
750 * INPUTS
751 * xInitialization - the previous node on the SAX chain
752 * xDocumentHandler - the next node on the SAX chain
753 * xElementStackKeeper - the ElementStackKeeper component which reserves
754 * missed key SAX events for the SAXEventKeeper
756 * RESULT
757 * empty
759 * AUTHOR
760 * Michael Mi
761 * Email: michael.mi@sun.com
762 ******************************************************************************/
764 m_bIsPreviousNodeInitializable = true;
765 m_xPreviousNodeOnSAXChain = xInitialization;
766 m_xNextNodeOnSAXChain = xDocumentHandler;
767 m_xElementStackKeeper = xElementStackKeeper;
769 initializeSAXChain( );
772 void XSecController::clearSAXChainConnector()
773 /****** XSecController/clearSAXChainConnector *********************************
775 * NAME
776 * clearSAXChainConnector -- resets the collaborating components.
778 * SYNOPSIS
779 * clearSAXChainConnector( );
781 * FUNCTION
782 * See NAME.
784 * INPUTS
785 * empty
787 * RESULT
788 * empty
790 * AUTHOR
791 * Michael Mi
792 * Email: michael.mi@sun.com
793 ******************************************************************************/
796 * before reseting, if the ElementStackKeeper has kept something, then
797 * those kept key SAX events must be transferred to the SAXEventKeeper
798 * first. This is to promise the next node to the SAXEventKeeper on the
799 * SAX chain always receives a complete document.
801 if (m_xElementStackKeeper.is() && m_xSAXEventKeeper.is())
803 cssu::Reference< cssxs::XDocumentHandler > xSEKHandler(m_xSAXEventKeeper, cssu::UNO_QUERY);
804 m_xElementStackKeeper->retrieve(xSEKHandler, sal_True);
807 chainOff();
809 m_xPreviousNodeOnSAXChain = NULL;
810 m_xNextNodeOnSAXChain = NULL;
811 m_xElementStackKeeper = NULL;
814 void XSecController::endMission()
815 /****** XSecController/endMission *********************************************
817 * NAME
818 * endMission -- forces to end all missions
820 * SYNOPSIS
821 * endMission( );
823 * FUNCTION
824 * Deletes all signature information and forces all missions to an end.
826 * INPUTS
827 * empty
829 * RESULT
830 * empty
832 * AUTHOR
833 * Michael Mi
834 * Email: michael.mi@sun.com
835 ******************************************************************************/
837 sal_Int32 size = m_vInternalSignatureInformations.size();
839 for (int i=0; i<size; ++i)
841 if ( m_nStatusOfSecurityComponents == INITIALIZED )
843 * ResolvedListener only exist when the security components are created.
846 cssu::Reference< cssxc::sax::XMissionTaker > xMissionTaker
847 ( m_vInternalSignatureInformations[i].xReferenceResolvedListener, cssu::UNO_QUERY );
850 * askes the SignatureCreator/SignatureVerifier to release
851 * all resouces it uses.
853 xMissionTaker->endMission();
857 m_xUriBinding = NULL;
858 m_xSecurityContext = NULL;
861 * free the status change listener reference to this object
863 if (m_xSAXEventKeeper.is())
865 cssu::Reference<cssxc::sax::XSAXEventKeeperStatusChangeBroadcaster>
866 xSAXEventKeeperStatusChangeBroadcaster(m_xSAXEventKeeper, cssu::UNO_QUERY);
867 xSAXEventKeeperStatusChangeBroadcaster
868 ->addSAXEventKeeperStatusChangeListener( NULL );
872 void XSecController::exportSignature(
873 const cssu::Reference<cssxs::XDocumentHandler>& xDocumentHandler,
874 const SignatureInformation& signatureInfo )
875 /****** XSecController/exportSignature ****************************************
877 * NAME
878 * exportSignature -- export a signature structure to an XDocumentHandler
880 * SYNOPSIS
881 * exportSignature( xDocumentHandler, signatureInfo);
883 * FUNCTION
884 * see NAME.
886 * INPUTS
887 * xDocumentHandler - the document handler to receive the signature
888 * signatureInfo - signature to be exported
890 * RESULT
891 * empty
893 * AUTHOR
894 * Michael Mi
895 * Email: michael.mi@sun.com
896 ******************************************************************************/
899 * defines all element tags in Signature element.
901 rtl::OUString tag_Signature(TAG_SIGNATURE);
902 rtl::OUString tag_SignedInfo(TAG_SIGNEDINFO);
903 rtl::OUString tag_CanonicalizationMethod(TAG_CANONICALIZATIONMETHOD);
904 rtl::OUString tag_SignatureMethod(TAG_SIGNATUREMETHOD);
905 rtl::OUString tag_Reference(TAG_REFERENCE);
906 rtl::OUString tag_Transforms(TAG_TRANSFORMS);
907 rtl::OUString tag_Transform(TAG_TRANSFORM);
908 rtl::OUString tag_DigestMethod(TAG_DIGESTMETHOD);
909 rtl::OUString tag_DigestValue(TAG_DIGESTVALUE);
910 rtl::OUString tag_SignatureValue(TAG_SIGNATUREVALUE);
911 rtl::OUString tag_KeyInfo(TAG_KEYINFO);
912 rtl::OUString tag_X509Data(TAG_X509DATA);
913 rtl::OUString tag_X509IssuerSerial(TAG_X509ISSUERSERIAL);
914 rtl::OUString tag_X509IssuerName(TAG_X509ISSUERNAME);
915 rtl::OUString tag_X509SerialNumber(TAG_X509SERIALNUMBER);
916 rtl::OUString tag_X509Certificate(TAG_X509CERTIFICATE);
917 rtl::OUString tag_Object(TAG_OBJECT);
918 rtl::OUString tag_SignatureProperties(TAG_SIGNATUREPROPERTIES);
919 rtl::OUString tag_SignatureProperty(TAG_SIGNATUREPROPERTY);
920 rtl::OUString tag_Date(TAG_DATE);
922 const SignatureReferenceInformations& vReferenceInfors = signatureInfo.vSignatureReferenceInfors;
923 SvXMLAttributeList *pAttributeList;
926 * Write Signature element
928 pAttributeList = new SvXMLAttributeList();
929 pAttributeList->AddAttribute(
930 rtl::OUString(ATTR_XMLNS),
931 rtl::OUString(NS_XMLDSIG));
933 if (!signatureInfo.ouSignatureId.isEmpty())
935 pAttributeList->AddAttribute(
936 rtl::OUString(ATTR_ID),
937 rtl::OUString(signatureInfo.ouSignatureId));
940 xDocumentHandler->startElement( tag_Signature, cssu::Reference< cssxs::XAttributeList > (pAttributeList));
942 /* Write SignedInfo element */
943 xDocumentHandler->startElement(
944 tag_SignedInfo,
945 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
947 /* Write CanonicalizationMethod element */
948 pAttributeList = new SvXMLAttributeList();
949 pAttributeList->AddAttribute(
950 rtl::OUString(ATTR_ALGORITHM),
951 rtl::OUString(ALGO_C14N));
952 xDocumentHandler->startElement( tag_CanonicalizationMethod, cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
953 xDocumentHandler->endElement( tag_CanonicalizationMethod );
955 /* Write SignatureMethod element */
956 pAttributeList = new SvXMLAttributeList();
957 pAttributeList->AddAttribute(
958 rtl::OUString(ATTR_ALGORITHM),
959 rtl::OUString(ALGO_RSASHA1));
960 xDocumentHandler->startElement( tag_SignatureMethod, cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
961 xDocumentHandler->endElement( tag_SignatureMethod );
963 /* Write Reference element */
964 int j;
965 int refNum = vReferenceInfors.size();
967 for(j=0; j<refNum; ++j)
969 const SignatureReferenceInformation& refInfor = vReferenceInfors[j];
971 pAttributeList = new SvXMLAttributeList();
972 if ( refInfor.nType != TYPE_SAMEDOCUMENT_REFERENCE )
974 * stream reference
977 pAttributeList->AddAttribute(
978 rtl::OUString(ATTR_URI),
979 refInfor.ouURI);
981 else
983 * same-document reference
986 pAttributeList->AddAttribute(
987 rtl::OUString(ATTR_URI),
988 rtl::OUString(CHAR_FRAGMENT)+refInfor.ouURI);
991 xDocumentHandler->startElement( tag_Reference, cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
993 /* Write Transforms element */
994 if (refInfor.nType == TYPE_XMLSTREAM_REFERENCE)
996 * xml stream, so c14n transform is needed
999 xDocumentHandler->startElement(
1000 tag_Transforms,
1001 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1003 pAttributeList = new SvXMLAttributeList();
1004 pAttributeList->AddAttribute(
1005 rtl::OUString(ATTR_ALGORITHM),
1006 rtl::OUString(ALGO_C14N));
1007 xDocumentHandler->startElement(
1008 tag_Transform,
1009 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
1010 xDocumentHandler->endElement( tag_Transform );
1012 xDocumentHandler->endElement( tag_Transforms );
1015 /* Write DigestMethod element */
1016 pAttributeList = new SvXMLAttributeList();
1017 pAttributeList->AddAttribute(
1018 rtl::OUString(ATTR_ALGORITHM),
1019 rtl::OUString(ALGO_XMLDSIGSHA1));
1020 xDocumentHandler->startElement(
1021 tag_DigestMethod,
1022 cssu::Reference< cssxs::XAttributeList > (pAttributeList) );
1023 xDocumentHandler->endElement( tag_DigestMethod );
1025 /* Write DigestValue element */
1026 xDocumentHandler->startElement(
1027 tag_DigestValue,
1028 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1029 xDocumentHandler->characters( refInfor.ouDigestValue );
1030 xDocumentHandler->endElement( tag_DigestValue );
1032 xDocumentHandler->endElement( tag_Reference );
1035 xDocumentHandler->endElement( tag_SignedInfo );
1037 /* Write SignatureValue element */
1038 xDocumentHandler->startElement(
1039 tag_SignatureValue,
1040 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1041 xDocumentHandler->characters( signatureInfo.ouSignatureValue );
1042 xDocumentHandler->endElement( tag_SignatureValue );
1044 /* Write KeyInfo element */
1045 xDocumentHandler->startElement(
1046 tag_KeyInfo,
1047 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1049 /* Write X509Data element */
1050 xDocumentHandler->startElement(
1051 tag_X509Data,
1052 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1054 /* Write X509IssuerSerial element */
1055 xDocumentHandler->startElement(
1056 tag_X509IssuerSerial,
1057 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1059 /* Write X509IssuerName element */
1060 xDocumentHandler->startElement(
1061 tag_X509IssuerName,
1062 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1063 xDocumentHandler->characters( signatureInfo.ouX509IssuerName );
1064 xDocumentHandler->endElement( tag_X509IssuerName );
1066 /* Write X509SerialNumber element */
1067 xDocumentHandler->startElement(
1068 tag_X509SerialNumber,
1069 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1070 xDocumentHandler->characters( signatureInfo.ouX509SerialNumber );
1071 xDocumentHandler->endElement( tag_X509SerialNumber );
1073 xDocumentHandler->endElement( tag_X509IssuerSerial );
1075 /* Write X509Certificate element */
1076 if (!signatureInfo.ouX509Certificate.isEmpty())
1078 xDocumentHandler->startElement(
1079 tag_X509Certificate,
1080 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1081 xDocumentHandler->characters( signatureInfo.ouX509Certificate );
1082 xDocumentHandler->endElement( tag_X509Certificate );
1085 xDocumentHandler->endElement( tag_X509Data );
1087 xDocumentHandler->endElement( tag_KeyInfo );
1089 /* Write Object element */
1090 xDocumentHandler->startElement(
1091 tag_Object,
1092 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1094 /* Write SignatureProperties element */
1095 xDocumentHandler->startElement(
1096 tag_SignatureProperties,
1097 cssu::Reference< cssxs::XAttributeList > (new SvXMLAttributeList()));
1099 /* Write SignatureProperty element */
1100 pAttributeList = new SvXMLAttributeList();
1101 pAttributeList->AddAttribute(
1102 rtl::OUString(ATTR_ID),
1103 signatureInfo.ouPropertyId);
1104 pAttributeList->AddAttribute(
1105 rtl::OUString(ATTR_TARGET),
1106 rtl::OUString(CHAR_FRAGMENT)+signatureInfo.ouSignatureId);
1107 xDocumentHandler->startElement(
1108 tag_SignatureProperty,
1109 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
1111 /* Write timestamp element */
1113 pAttributeList = new SvXMLAttributeList();
1114 pAttributeList->AddAttribute(
1115 rtl::OUString(ATTR_XMLNS)
1116 +rtl::OUString(":")
1117 +rtl::OUString(NSTAG_DC),
1118 rtl::OUString(NS_DC));
1120 xDocumentHandler->startElement(
1121 rtl::OUString(NSTAG_DC)
1122 +rtl::OUString(":")
1123 +tag_Date,
1124 cssu::Reference< cssxs::XAttributeList > (pAttributeList));
1126 ::rtl::OUStringBuffer buffer;
1127 //If the xml signature was already contained in the document,
1128 //then we use the original date and time string, rather then the
1129 //converted one. When the original string is converted to the DateTime
1130 //structure then information may be lost because it only holds a fractional
1131 //of a second with a accuracy of one hundredth of second. If the string contains
1132 //milli seconds (document was signed by an application other than OOo)
1133 //and the converted time is written back, then the string looks different
1134 //and the signature is broken.
1135 if (!signatureInfo.ouDateTime.isEmpty())
1136 buffer = signatureInfo.ouDateTime;
1137 else
1138 convertDateTime( buffer, signatureInfo.stDateTime );
1139 xDocumentHandler->characters( buffer.makeStringAndClear() );
1141 xDocumentHandler->endElement(
1142 rtl::OUString(NSTAG_DC)
1143 +rtl::OUString(":")
1144 +tag_Date);
1146 xDocumentHandler->endElement( tag_SignatureProperty );
1148 xDocumentHandler->endElement( tag_SignatureProperties );
1150 xDocumentHandler->endElement( tag_Object );
1152 xDocumentHandler->endElement( tag_Signature );
1155 SignatureInformation XSecController::getSignatureInformation( sal_Int32 nSecurityId ) const
1157 SignatureInformation aInf( 0 );
1158 int nIndex = findSignatureInfor(nSecurityId);
1159 DBG_ASSERT( nIndex != -1, "getSignatureInformation - SecurityId is invalid!" );
1160 if ( nIndex != -1)
1162 aInf = m_vInternalSignatureInformations[nIndex].signatureInfor;
1164 return aInf;
1167 SignatureInformations XSecController::getSignatureInformations() const
1169 SignatureInformations vInfors;
1170 int sigNum = m_vInternalSignatureInformations.size();
1172 for (int i=0; i<sigNum; ++i)
1174 SignatureInformation si = m_vInternalSignatureInformations[i].signatureInfor;
1175 vInfors.push_back(si);
1178 return vInfors;
1182 * XSecurityController
1184 * no methods
1188 * XFastPropertySet
1192 * XSAXEventKeeperStatusChangeListener
1195 void SAL_CALL XSecController::blockingStatusChanged( sal_Bool isBlocking )
1196 throw (cssu::RuntimeException)
1198 this->m_bIsBlocking = isBlocking;
1199 checkChainingStatus();
1202 void SAL_CALL XSecController::collectionStatusChanged(
1203 sal_Bool isInsideCollectedElement )
1204 throw (cssu::RuntimeException)
1206 this->m_bIsCollectingElement = isInsideCollectedElement;
1207 checkChainingStatus();
1210 void SAL_CALL XSecController::bufferStatusChanged( sal_Bool /*isBufferEmpty*/)
1211 throw (cssu::RuntimeException)
1217 * XSignatureCreationResultListener
1219 void SAL_CALL XSecController::signatureCreated( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
1220 throw (com::sun::star::uno::RuntimeException)
1222 int index = findSignatureInfor(securityId);
1223 DBG_ASSERT( index != -1, "Signature Not Found!" );
1225 SignatureInformation& signatureInfor = m_vInternalSignatureInformations[index].signatureInfor;
1227 signatureInfor.nStatus = nResult;
1231 * XSignatureVerifyResultListener
1233 void SAL_CALL XSecController::signatureVerified( sal_Int32 securityId, com::sun::star::xml::crypto::SecurityOperationStatus nResult )
1234 throw (com::sun::star::uno::RuntimeException)
1236 int index = findSignatureInfor(securityId);
1237 DBG_ASSERT( index != -1, "Signature Not Found!" );
1239 SignatureInformation& signatureInfor = m_vInternalSignatureInformations[index].signatureInfor;
1241 signatureInfor.nStatus = nResult;
1244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */