1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/XKeyCollector.hpp>
25 #include <com/sun/star/xml/crypto/sax/ElementMarkPriority.hpp>
26 #include <com/sun/star/xml/crypto/sax/XReferenceResolvedBroadcaster.hpp>
27 #include <com/sun/star/xml/crypto/sax/XBlockerMonitor.hpp>
28 #include <com/sun/star/xml/crypto/sax/XReferenceCollector.hpp>
29 #include <com/sun/star/xml/crypto/sax/XSignatureCreationResultBroadcaster.hpp>
30 #include <com/sun/star/io/XActiveDataSource.hpp>
35 namespace cssu
= com::sun::star::uno
;
36 namespace cssl
= com::sun::star::lang
;
37 namespace cssxc
= com::sun::star::xml::crypto
;
38 namespace cssxs
= com::sun::star::xml::sax
;
40 /* xml security framework components */
41 #define SIGNATURECREATOR_COMPONENT "com.sun.star.xml.crypto.sax.SignatureCreator"
43 /* protected: for signature generation */
44 OUString
XSecController::createId()
46 cssu::Sequence
< sal_Int8
> aSeq( 16 );
47 rtl_createUuid (reinterpret_cast<sal_uInt8
*>(aSeq
.getArray()), 0, sal_True
);
51 for (int i
=0; i
<16; ++i
)
53 length
+= sprintf(str
+length
, "%04x", (unsigned char)aSeq
[i
]);
56 return OUString::createFromAscii(str
);
59 cssu::Reference
< cssxc::sax::XReferenceResolvedListener
> XSecController::prepareSignatureToWrite(
60 InternalSignatureInformation
& internalSignatureInfor
)
62 sal_Int32 nSecurityId
= internalSignatureInfor
.signatureInfor
.nSecurityId
;
63 SignatureReferenceInformations
& vReferenceInfors
= internalSignatureInfor
.signatureInfor
.vSignatureReferenceInfors
;
65 sal_Int32 nIdOfSignatureElementCollector
;
66 cssu::Reference
< cssxc::sax::XReferenceResolvedListener
> xReferenceResolvedListener
;
68 nIdOfSignatureElementCollector
=
69 m_xSAXEventKeeper
->addSecurityElementCollector( cssxc::sax::ElementMarkPriority_AFTERMODIFY
, sal_True
);
71 m_xSAXEventKeeper
->setSecurityId(nIdOfSignatureElementCollector
, nSecurityId
);
74 * create a SignatureCreator
76 cssu::Reference
< cssl::XMultiComponentFactory
> xMCF( mxCtx
->getServiceManager() );
77 xReferenceResolvedListener
= cssu::Reference
< cssxc::sax::XReferenceResolvedListener
>(
78 xMCF
->createInstanceWithContext(
79 OUString(SIGNATURECREATOR_COMPONENT
), mxCtx
),
82 cssu::Reference
<cssl::XInitialization
> xInitialization(xReferenceResolvedListener
, cssu::UNO_QUERY
);
84 cssu::Sequence
<cssu::Any
> args(5);
85 args
[0] = cssu::makeAny(OUString::number(nSecurityId
));
86 args
[1] = cssu::makeAny(m_xSAXEventKeeper
);
87 args
[2] = cssu::makeAny(OUString::number(nIdOfSignatureElementCollector
));
89 //for nss, the internal module is used for signing, which needs to be improved later
90 sal_Int32 nEnvIndex
= internalSignatureInfor
.signatureInfor
.nSecurityEnvironmentIndex
;
91 if( nEnvIndex
< 0 || nEnvIndex
>= m_xSecurityContext
->getSecurityEnvironmentNumber())
93 args
[3] = cssu::makeAny(m_xSecurityContext
->getSecurityEnvironment());
97 args
[3] = cssu::makeAny(m_xSecurityContext
->getSecurityEnvironmentByIndex(nEnvIndex
));
100 args
[4] = cssu::makeAny(m_xXMLSignature
);
101 xInitialization
->initialize(args
);
103 sal_Int32 nBlockerId
= m_xSAXEventKeeper
->addBlocker();
104 m_xSAXEventKeeper
->setSecurityId(nBlockerId
, nSecurityId
);
106 cssu::Reference
<cssxc::sax::XBlockerMonitor
> xBlockerMonitor(xReferenceResolvedListener
, cssu::UNO_QUERY
);
107 xBlockerMonitor
->setBlockerId(nBlockerId
);
109 cssu::Reference
< cssxc::sax::XSignatureCreationResultBroadcaster
>
110 xSignatureCreationResultBroadcaster(xReferenceResolvedListener
, cssu::UNO_QUERY
);
112 xSignatureCreationResultBroadcaster
->addSignatureCreationResultListener( this );
114 cssu::Reference
<cssxc::sax::XReferenceResolvedBroadcaster
>
115 xReferenceResolvedBroadcaster
119 xReferenceResolvedBroadcaster
->addReferenceResolvedListener(
120 nIdOfSignatureElementCollector
,
121 xReferenceResolvedListener
);
123 cssu::Reference
<cssxc::sax::XReferenceCollector
> xReferenceCollector
124 (xReferenceResolvedListener
, cssu::UNO_QUERY
);
127 int size
= vReferenceInfors
.size();
128 sal_Int32 nReferenceCount
= 0;
130 for(i
=0; i
<size
; ++i
)
132 sal_Int32 keeperId
= internalSignatureInfor
.vKeeperIds
[i
];
136 m_xSAXEventKeeper
->setSecurityId(keeperId
, nSecurityId
);
137 xReferenceResolvedBroadcaster
->addReferenceResolvedListener( keeperId
, xReferenceResolvedListener
);
138 xReferenceCollector
->setReferenceId( keeperId
);
143 xReferenceCollector
->setReferenceCount( nReferenceCount
);
146 * adds all URI binding
148 cssu::Reference
<cssxc::XUriBinding
> xUriBinding
149 (xReferenceResolvedListener
, cssu::UNO_QUERY
);
151 for(i
=0; i
<size
; ++i
)
153 const SignatureReferenceInformation
& refInfor
= vReferenceInfors
[i
];
155 cssu::Reference
< com::sun::star::io::XInputStream
> xInputStream
156 = getObjectInputStream( refInfor
.ouURI
);
158 if (xInputStream
.is())
160 xUriBinding
->setUriBinding(refInfor
.ouURI
,xInputStream
);
164 cssu::Reference
<cssxc::sax::XKeyCollector
> keyCollector (xReferenceResolvedListener
, cssu::UNO_QUERY
);
165 keyCollector
->setKeyId(0);
167 internalSignatureInfor
.signatureInfor
.ouSignatureId
= createId();
168 internalSignatureInfor
.signatureInfor
.ouPropertyId
= createId();
169 internalSignatureInfor
.addReference(TYPE_SAMEDOCUMENT_REFERENCE
, internalSignatureInfor
.signatureInfor
.ouPropertyId
, -1 );
173 * replace both digestValues and signatueValue to " "
175 for(i
=0; i
<size
; ++i
)
177 SignatureReferenceInformation
& refInfor
= vReferenceInfors
[i
];
178 refInfor
.ouDigestValue
= CHAR_BLANK
;
181 internalSignatureInfor
.signatureInfor
.ouSignatureValue
= CHAR_BLANK
;
183 return xReferenceResolvedListener
;
186 void XSecController::signAStream( sal_Int32 securityId
, const OUString
& uri
, const OUString
& /*objectURL*/, bool isBinary
)
188 sal_Int32 type
= isBinary
? TYPE_BINARYSTREAM_REFERENCE
: TYPE_XMLSTREAM_REFERENCE
;
190 int index
= findSignatureInfor( securityId
);
194 InternalSignatureInformation
isi(securityId
, NULL
);
195 isi
.addReference(type
, uri
, -1);
196 m_vInternalSignatureInformations
.push_back( isi
);
200 m_vInternalSignatureInformations
[index
].addReference(type
, uri
, -1);
204 void XSecController::setX509Certificate(
205 sal_Int32 nSecurityId
,
206 const OUString
& ouX509IssuerName
,
207 const OUString
& ouX509SerialNumber
,
208 const OUString
& ouX509Cert
)
210 setX509Certificate(nSecurityId
, -1, ouX509IssuerName
, ouX509SerialNumber
, ouX509Cert
);
213 void XSecController::setX509Certificate(
214 sal_Int32 nSecurityId
,
215 const sal_Int32 nSecurityEnvironmentIndex
,
216 const OUString
& ouX509IssuerName
,
217 const OUString
& ouX509SerialNumber
,
218 const OUString
& ouX509Cert
)
220 int index
= findSignatureInfor( nSecurityId
);
224 InternalSignatureInformation
isi(nSecurityId
, NULL
);
225 isi
.signatureInfor
.nSecurityEnvironmentIndex
= nSecurityEnvironmentIndex
;
226 isi
.signatureInfor
.ouX509IssuerName
= ouX509IssuerName
;
227 isi
.signatureInfor
.ouX509SerialNumber
= ouX509SerialNumber
;
228 isi
.signatureInfor
.ouX509Certificate
= ouX509Cert
;
229 m_vInternalSignatureInformations
.push_back( isi
);
233 SignatureInformation
&si
234 = m_vInternalSignatureInformations
[index
].signatureInfor
;
235 si
.ouX509IssuerName
= ouX509IssuerName
;
236 si
.ouX509SerialNumber
= ouX509SerialNumber
;
237 si
.ouX509Certificate
= ouX509Cert
;
238 si
.nSecurityEnvironmentIndex
= nSecurityEnvironmentIndex
;
242 void XSecController::setDate(
243 sal_Int32 nSecurityId
,
244 const ::com::sun::star::util::DateTime
& rDateTime
)
246 int index
= findSignatureInfor( nSecurityId
);
250 InternalSignatureInformation
isi(nSecurityId
, NULL
);
251 isi
.signatureInfor
.stDateTime
= rDateTime
;
252 m_vInternalSignatureInformations
.push_back( isi
);
256 SignatureInformation
&si
257 = m_vInternalSignatureInformations
[index
].signatureInfor
;
258 si
.stDateTime
= rDateTime
;
262 bool XSecController::WriteSignature(
263 const cssu::Reference
<cssxs::XDocumentHandler
>& xDocumentHandler
)
267 DBG_ASSERT( xDocumentHandler
.is(), "I really need a document handler!" );
270 * chain the SAXEventKeeper to the SAX chain
274 if ( m_nStatusOfSecurityComponents
== INITIALIZED
)
276 * if all security components are ready, add the signature
280 m_bIsSAXEventKeeperSticky
= true;
281 m_xSAXEventKeeper
->setNextHandler(xDocumentHandler
);
286 * export the signature template
288 cssu::Reference
<cssxs::XDocumentHandler
> xSEKHandler( m_xSAXEventKeeper
,cssu::UNO_QUERY
);
291 int sigNum
= m_vInternalSignatureInformations
.size();
293 for (i
=0; i
<sigNum
; ++i
)
295 InternalSignatureInformation
&isi
= m_vInternalSignatureInformations
[i
];
298 * prepare the signature creator
300 isi
.xReferenceResolvedListener
301 = prepareSignatureToWrite( isi
);
303 exportSignature( xSEKHandler
, isi
.signatureInfor
);
306 m_bIsSAXEventKeeperSticky
= false;
311 catch( cssxs::SAXException
& )
313 m_pErrorMessage
= ERROR_SAXEXCEPTIONDURINGCREATION
;
315 catch( com::sun::star::io::IOException
& )
317 m_pErrorMessage
= ERROR_IOEXCEPTIONDURINGCREATION
;
319 catch( cssu::Exception
& )
321 m_pErrorMessage
= ERROR_EXCEPTIONDURINGCREATION
;
324 m_xSAXEventKeeper
->setNextHandler( NULL
);
325 m_bIsSAXEventKeeperSticky
= false;
329 m_pErrorMessage
= ERROR_CANNOTCREATEXMLSECURITYCOMPONENT
;
335 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */