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: xsecsign.cxx,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 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #include <xsecctl.hxx>
35 #include <tools/debug.hxx>
37 #include <com/sun/star/xml/crypto/sax/XKeyCollector.hpp>
38 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
39 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
40 #include <com/sun/star/xml/crypto/sax/XBlockerMonitor.hpp>
41 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
42 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp>
43 #include <com/sun/star/io/XActiveDataSource.hpp>
48 namespace cssu
= com::sun::star::uno
;
49 namespace cssl
= com::sun::star::lang
;
50 namespace cssxc
= com::sun::star::xml::crypto
;
51 namespace cssxs
= com::sun::star::xml::sax
;
53 /* xml security framework components */
54 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator"
56 /* protected: for signature generation */
57 rtl::OUString
XSecController::createId()
59 cssu::Sequence
< sal_Int8
> aSeq( 16 );
60 rtl_createUuid ((sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
64 for (int i
=0; i
<16; ++i
)
66 length
+= sprintf(str
+length
, "%04x", (unsigned char)aSeq
[i
]);
69 return rtl::OUString::createFromAscii(str
);
72 cssu::Reference
< cssxc::sax::XReferenceResolvedListener
> XSecController::prepareSignatureToWrite(
73 InternalSignatureInformation
& internalSignatureInfor
)
75 sal_Int32 nSecurityId
= internalSignatureInfor
.signatureInfor
.nSecurityId
;
76 SignatureReferenceInformations
& vReferenceInfors
= internalSignatureInfor
.signatureInfor
.vSignatureReferenceInfors
;
78 sal_Int32 nIdOfSignatureElementCollector
;
79 cssu::Reference
< cssxc::sax::XReferenceResolvedListener
> xReferenceResolvedListener
;
81 nIdOfSignatureElementCollector
=
82 m_xSAXEventKeeper
->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY
, sal_True
);
84 m_xSAXEventKeeper
->setSecurityId(nIdOfSignatureElementCollector
, nSecurityId
);
87 * create a SignatureCreator
89 cssu::Reference
< cssl::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
90 xReferenceResolvedListener
= cssu::Reference
< cssxc::sax::XReferenceResolvedListener
>(
91 xMCF
->createInstanceWithContext(
92 rtl::OUString::createFromAscii(SIGNATURECREATOR_COMPONENT
), mxCtx
),
95 cssu::Reference
<cssl::XInitialization
> xInitialization(xReferenceResolvedListener
, cssu::UNO_QUERY
);
97 cssu::Sequence
<cssu::Any
> args(5);
98 args
[0] = cssu::makeAny(rtl::OUString::valueOf(nSecurityId
));
99 args
[1] = cssu::makeAny(m_xSAXEventKeeper
);
100 args
[2] = cssu::makeAny(rtl::OUString::valueOf(nIdOfSignatureElementCollector
));
102 //i39448 : for nss, the internal module is used for signing, which needs to be improved later
103 sal_Int32 nEnvIndex
= internalSignatureInfor
.signatureInfor
.nSecurityEnvironmentIndex
;
104 if( nEnvIndex
< 0 || nEnvIndex
>= m_xSecurityContext
->getSecurityEnvironmentNumber())
106 args
[3] = cssu::makeAny(m_xSecurityContext
->getSecurityEnvironment());
110 args
[3] = cssu::makeAny(m_xSecurityContext
->getSecurityEnvironmentByIndex(nEnvIndex
));
113 args
[4] = cssu::makeAny(m_xXMLSignature
);
114 xInitialization
->initialize(args
);
116 sal_Int32 nBlockerId
= m_xSAXEventKeeper
->addBlocker();
117 m_xSAXEventKeeper
->setSecurityId(nBlockerId
, nSecurityId
);
119 cssu::Reference
<cssxc::sax::XBlockerMonitor
> xBlockerMonitor(xReferenceResolvedListener
, cssu::UNO_QUERY
);
120 xBlockerMonitor
->setBlockerId(nBlockerId
);
122 cssu::Reference
< cssxc::sax::XSignatureCreationResultBroadcaster
>
123 xSignatureCreationResultBroadcaster(xReferenceResolvedListener
, cssu::UNO_QUERY
);
125 xSignatureCreationResultBroadcaster
->addSignatureCreationResultListener( this );
127 cssu::Reference
<cssxc::sax::XReferenceResolvedBroadcaster
>
128 xReferenceResolvedBroadcaster
132 xReferenceResolvedBroadcaster
->addReferenceResolvedListener(
133 nIdOfSignatureElementCollector
,
134 xReferenceResolvedListener
);
136 cssu::Reference
<cssxc::sax::XReferenceCollector
> xReferenceCollector
137 (xReferenceResolvedListener
, cssu::UNO_QUERY
);
140 int size
= vReferenceInfors
.size();
141 sal_Int32 nReferenceCount
= 0;
143 for(i
=0; i
<size
; ++i
)
145 sal_Int32 keeperId
= internalSignatureInfor
.vKeeperIds
[i
];
149 m_xSAXEventKeeper
->setSecurityId(keeperId
, nSecurityId
);
150 xReferenceResolvedBroadcaster
->addReferenceResolvedListener( keeperId
, xReferenceResolvedListener
);
151 xReferenceCollector
->setReferenceId( keeperId
);
156 xReferenceCollector
->setReferenceCount( nReferenceCount
);
159 * adds all URI binding
161 cssu::Reference
<cssxc::XUriBinding
> xUriBinding
162 (xReferenceResolvedListener
, cssu::UNO_QUERY
);
164 for(i
=0; i
<size
; ++i
)
166 const SignatureReferenceInformation
& refInfor
= vReferenceInfors
[i
];
168 cssu::Reference
< com::sun::star::io::XInputStream
> xInputStream
169 = getObjectInputStream( refInfor
.ouURI
);
171 if (xInputStream
.is())
173 xUriBinding
->setUriBinding(refInfor
.ouURI
,xInputStream
);
177 cssu::Reference
<cssxc::sax::XKeyCollector
> keyCollector (xReferenceResolvedListener
, cssu::UNO_QUERY
);
178 keyCollector
->setKeyId(0);
180 internalSignatureInfor
.signatureInfor
.ouSignatureId
= createId();
181 internalSignatureInfor
.signatureInfor
.ouPropertyId
= createId();
182 internalSignatureInfor
.addReference(TYPE_SAMEDOCUMENT_REFERENCE
, internalSignatureInfor
.signatureInfor
.ouPropertyId
, -1 );
186 * replace both digestValues and signatueValue to " "
188 for(i
=0; i
<size
; ++i
)
190 SignatureReferenceInformation
& refInfor
= vReferenceInfors
[i
];
191 refInfor
.ouDigestValue
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK
));
194 internalSignatureInfor
.signatureInfor
.ouSignatureValue
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CHAR_BLANK
));
196 return xReferenceResolvedListener
;
199 /* public: for signature generation */
200 void XSecController::collectToSign( sal_Int32 securityId
, const rtl::OUString
& referenceId
)
202 /* DBG_ASSERT( m_xSAXEventKeeper.is(), "the SAXEventKeeper is NULL" ); */
206 if ( m_nStatusOfSecurityComponents
== INITIALIZED
)
208 * if all security components are ready, add a signature.
211 sal_Int32 nKeeperId
= m_xSAXEventKeeper
->addSecurityElementCollector(
212 cssxc::sax::ElementMarkPriority_AFTERMODIFY
, sal_False
);
214 int index
= findSignatureInfor( securityId
);
218 InternalSignatureInformation
isi(securityId
, NULL
);
219 isi
.addReference(TYPE_SAMEDOCUMENT_REFERENCE
, referenceId
, nKeeperId
);
220 m_vInternalSignatureInformations
.push_back( isi
);
224 m_vInternalSignatureInformations
[index
].addReference(TYPE_SAMEDOCUMENT_REFERENCE
, referenceId
, nKeeperId
);
229 void XSecController::signAStream( sal_Int32 securityId
, const rtl::OUString
& uri
, const rtl::OUString
& /*objectURL*/, sal_Bool isBinary
)
231 sal_Int32 type
= ((isBinary
==sal_True
)?TYPE_BINARYSTREAM_REFERENCE
:TYPE_XMLSTREAM_REFERENCE
);
233 int index
= findSignatureInfor( securityId
);
237 InternalSignatureInformation
isi(securityId
, NULL
);
238 isi
.addReference(type
, uri
, -1);
239 m_vInternalSignatureInformations
.push_back( isi
);
243 m_vInternalSignatureInformations
[index
].addReference(type
, uri
, -1);
247 void XSecController::setX509Certificate(
248 sal_Int32 nSecurityId
,
249 const rtl::OUString
& ouX509IssuerName
,
250 const rtl::OUString
& ouX509SerialNumber
,
251 const rtl::OUString
& ouX509Cert
)
253 setX509Certificate(nSecurityId
, -1, ouX509IssuerName
, ouX509SerialNumber
, ouX509Cert
);
256 void XSecController::setX509Certificate(
257 sal_Int32 nSecurityId
,
258 const sal_Int32 nSecurityEnvironmentIndex
,
259 const rtl::OUString
& ouX509IssuerName
,
260 const rtl::OUString
& ouX509SerialNumber
,
261 const rtl::OUString
& ouX509Cert
)
263 int index
= findSignatureInfor( nSecurityId
);
267 InternalSignatureInformation
isi(nSecurityId
, NULL
);
268 isi
.signatureInfor
.nSecurityEnvironmentIndex
= nSecurityEnvironmentIndex
;
269 isi
.signatureInfor
.ouX509IssuerName
= ouX509IssuerName
;
270 isi
.signatureInfor
.ouX509SerialNumber
= ouX509SerialNumber
;
271 isi
.signatureInfor
.ouX509Certificate
= ouX509Cert
;
272 m_vInternalSignatureInformations
.push_back( isi
);
276 SignatureInformation
&si
277 = m_vInternalSignatureInformations
[index
].signatureInfor
;
278 si
.ouX509IssuerName
= ouX509IssuerName
;
279 si
.ouX509SerialNumber
= ouX509SerialNumber
;
280 si
.ouX509Certificate
= ouX509Cert
;
281 si
.nSecurityEnvironmentIndex
= nSecurityEnvironmentIndex
;
285 void XSecController::setDate(
286 sal_Int32 nSecurityId
,
287 const ::com::sun::star::util::DateTime
& rDateTime
)
289 int index
= findSignatureInfor( nSecurityId
);
293 InternalSignatureInformation
isi(nSecurityId
, NULL
);
294 isi
.signatureInfor
.stDateTime
= rDateTime
;
295 m_vInternalSignatureInformations
.push_back( isi
);
299 SignatureInformation
&si
300 = m_vInternalSignatureInformations
[index
].signatureInfor
;
301 si
.stDateTime
= rDateTime
;
305 bool XSecController::WriteSignature(
306 const cssu::Reference
<cssxs::XDocumentHandler
>& xDocumentHandler
)
310 DBG_ASSERT( xDocumentHandler
.is(), "I really need a document handler!" );
313 * chain the SAXEventKeeper to the SAX chain
317 if ( m_nStatusOfSecurityComponents
== INITIALIZED
)
319 * if all security components are ready, add the signature
323 m_bIsSAXEventKeeperSticky
= true;
324 m_xSAXEventKeeper
->setNextHandler(xDocumentHandler
);
329 * export the signature template
331 cssu::Reference
<cssxs::XDocumentHandler
> xSEKHandler( m_xSAXEventKeeper
,cssu::UNO_QUERY
);
334 int sigNum
= m_vInternalSignatureInformations
.size();
336 for (i
=0; i
<sigNum
; ++i
)
338 InternalSignatureInformation
&isi
= m_vInternalSignatureInformations
[i
];
341 * prepare the signature creator
343 isi
.xReferenceResolvedListener
344 = prepareSignatureToWrite( isi
);
346 exportSignature( xSEKHandler
, isi
.signatureInfor
);
349 m_bIsSAXEventKeeperSticky
= false;
354 catch( cssxs::SAXException
& )
356 m_pErrorMessage
= ERROR_SAXEXCEPTIONDURINGCREATION
;
358 catch( com::sun::star::io::IOException
& )
360 m_pErrorMessage
= ERROR_IOEXCEPTIONDURINGCREATION
;
362 catch( cssu::Exception
& )
364 m_pErrorMessage
= ERROR_EXCEPTIONDURINGCREATION
;
367 m_xSAXEventKeeper
->setNextHandler( NULL
);
368 m_bIsSAXEventKeeperSticky
= false;
372 m_pErrorMessage
= ERROR_CANNOTCREATEXMLSECURITYCOMPONENT
;