27#if defined _MSC_VER && defined __clang__
28#pragma clang diagnostic push
29#pragma clang diagnostic ignored "-Wundef"
32#if defined _MSC_VER && defined __clang__
33#pragma clang diagnostic pop
38#include <signingresult.h>
39#include <importresult.h>
47using namespace css::uno;
48using namespace css::lang;
49using namespace css::xml::wrapper;
50using namespace css::xml::crypto;
59Reference< XXMLSignatureTemplate >
61 const Reference< XXMLSignatureTemplate >& aTemplate ,
62 const Reference< XSecurityEnvironment >& aEnvironment
65 xmlSecDSigCtxPtr pDsigCtx = nullptr ;
66 xmlNodePtr pNode = nullptr ;
71 if( !aEnvironment.is() )
75 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
76 if( !xElement.is() ) {
82 if( pElement ==
nullptr ) {
89 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
90 if( xUriBinding.is() ) {
99 if( pSecEnv ==
nullptr )
105 pDsigCtx = xmlSecDSigCtxCreate(
nullptr ) ;
106 if( pDsigCtx ==
nullptr )
114 pDsigCtx->operation = xmlSecTransformOperationSign;
120 xmlNodePtr cur = xmlSecGetNextElementNode(pNode->children);
122 cur = xmlSecGetNextElementNode(cur->children);
123 while( cur !=
nullptr )
126 if( xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs) )
128 xmlSecDSigReferenceCtxPtr pDsigRefCtx =
129 xmlSecDSigReferenceCtxCreate(pDsigCtx,
130 xmlSecDSigReferenceOriginSignedInfo);
131 if(pDsigRefCtx ==
nullptr)
135 if( xmlSecPtrListAdd(&(pDsigCtx->signedInfoReferences),
139 xmlSecDSigReferenceCtxDestroy(pDsigRefCtx);
143 if( xmlSecDSigReferenceCtxProcessNode(pDsigRefCtx, cur) < 0 )
147 if(pDsigRefCtx->status != xmlSecDSigStatusSucceeded)
149 pDsigCtx->status = xmlSecDSigStatusInvalid;
154 cur = xmlSecGetNextElementNode(cur->next);
162 xmlSecNodeSetPtr nodeset =
nullptr;
163 cur = xmlSecGetNextElementNode(pNode->children);
165 nodeset = xmlSecNodeSetGetChildren(pNode->doc, cur, 1, 0);
166 if(nodeset ==
nullptr)
167 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
169 if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
170 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
176 cur = xmlSecGetNextElementNode(pNode->children);
178 cur = xmlSecGetNextElementNode(cur->next);
179 cur = xmlSecGetNextElementNode(cur->next);
180 cur = xmlSecGetNextElementNode(cur->children);
182 if(!xmlSecCheckNodeName(cur, xmlSecNodePGPData, xmlSecDSigNs))
183 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
185 cur = xmlSecGetNextElementNode(cur->children);
186 static const xmlChar xmlSecNodePGPKeyID[] =
"PGPKeyID";
187 if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyID, xmlSecDSigNs))
188 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
191 rCtx.setKeyListMode(GPGME_KEYLIST_MODE_LOCAL);
193 xmlChar* pKey=xmlNodeGetContent(cur);
195 int nRet = xmlSecBase64Decode_ex(pKey,
reinterpret_cast<xmlSecByte*
>(pKey), xmlStrlen(pKey), &nWritten);
197 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
198 if( rCtx.addSigningKey(
200 reinterpret_cast<char*
>(pKey),
err,
true)) )
201 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
207 reinterpret_cast<char*
>(xmlSecBufferGetData(pDsigCtx->transformCtx.result)),
208 xmlSecBufferGetSize(pDsigCtx->transformCtx.result),
false);
209 GpgME::Data data_out;
211 SAL_INFO(
"xmlsecurity.xmlsec.gpg",
"Generating signature for: " << xmlSecBufferGetData(pDsigCtx->transformCtx.result));
214 rCtx.setArmor(
false);
215 GpgME::SigningResult sign_res=rCtx.sign(data_in, data_out,
217 off_t
result = data_out.seek(0,SEEK_SET);
220 int len=0, curr=0;
char buf;
221 while( (curr=data_out.read(&buf, 1)) )
224 if(sign_res.error() || !len)
225 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
228 xmlChar* signature =
static_cast<xmlChar*
>(xmlMalloc(len + 1));
229 if(signature ==
nullptr)
230 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
231 result = data_out.seek(0,SEEK_SET);
233 if( data_out.read(signature, len) != len )
234 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
237 xmlChar* signatureEncoded=
nullptr;
238 if( !(signatureEncoded=xmlSecBase64Encode(
reinterpret_cast<xmlSecByte*
>(signature), len, 79)) )
239 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
244 cur = xmlSecGetNextElementNode(pNode->children);
245 cur = xmlSecGetNextElementNode(cur->next);
248 xmlNodeSetContentLen(cur, signatureEncoded, xmlStrlen(signatureEncoded));
249 xmlFree(signatureEncoded);
251 aTemplate->setStatus(SecurityOperationStatus_OPERATION_SUCCEEDED);
254 xmlSecDSigCtxDestroy( pDsigCtx ) ;
257 if( xUriBinding.is() )
265Reference< XXMLSignatureTemplate >
267 const Reference< XXMLSignatureTemplate >& aTemplate ,
268 const Reference< XXMLSecurityContext >& aSecurityCtx
270 xmlSecDSigCtxPtr pDsigCtx = nullptr ;
271 xmlNodePtr pNode = nullptr ;
273 if( !aTemplate.is() )
276 if( !aSecurityCtx.is() )
280 Reference< XXMLElementWrapper > xElement = aTemplate->getTemplate() ;
286 if( pElement ==
nullptr )
292 Reference< XUriBinding > xUriBinding = aTemplate->getBinding() ;
293 if( xUriBinding.is() ) {
301 sal_Int32 nSecurityEnvironment = aSecurityCtx->getSecurityEnvironmentNumber();
304 for (
i=0;
i<nSecurityEnvironment; ++
i)
306 Reference< XSecurityEnvironment > aEnvironment = aSecurityCtx->getSecurityEnvironmentByIndex(
i);
310 if( pSecEnv ==
nullptr )
317 pDsigCtx = xmlSecDSigCtxCreate(
nullptr ) ;
318 if( pDsigCtx ==
nullptr )
326 pDsigCtx->operation = xmlSecTransformOperationVerify;
329 pDsigCtx->status = xmlSecDSigStatusUnknown;
336 xmlSecNodeSetPtr nodeset =
nullptr;
337 xmlNodePtr cur = xmlSecGetNextElementNode(pNode->children);
339 nodeset = xmlSecNodeSetGetChildren(pNode->doc, cur, 1, 0);
340 if(nodeset ==
nullptr)
341 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
344 if( xmlSecTransformCtxXmlExecute(&(pDsigCtx->transformCtx), nodeset) < 0 )
345 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
350 GpgME::Data data_text(
351 reinterpret_cast<char*
>(xmlSecBufferGetData(pDsigCtx->transformCtx.result)),
352 xmlSecBufferGetSize(pDsigCtx->transformCtx.result),
false);
354 SAL_INFO(
"xmlsecurity.xmlsec.gpg",
"Validating SignatureInfo: " << xmlSecBufferGetData(pDsigCtx->transformCtx.result));
358 cur = xmlSecGetNextElementNode(pNode->children);
359 cur = xmlSecGetNextElementNode(cur->next);
361 if(!xmlSecCheckNodeName(cur, xmlSecNodeSignatureValue, xmlSecDSigNs))
362 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
363 xmlChar* pSignatureValue=xmlNodeGetContent(cur);
365 int nRet = xmlSecBase64Decode_ex(pSignatureValue,
reinterpret_cast<xmlSecByte*
>(pSignatureValue), xmlStrlen(pSignatureValue), &nSigSize);
367 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
369 GpgME::Data data_signature(
370 reinterpret_cast<char*
>(pSignatureValue),
373 GpgME::VerificationResult verify_res=rCtx.verifyDetachedSignature(
374 data_signature, data_text);
377 if( verify_res.isNull() || verify_res.numSignatures() == 0
379 || ( (verify_res.numSignatures() > 0)
380 && verify_res.signature(0).status().encodedError() > 0 ) )
390 cur = xmlSecGetNextElementNode(pNode->children);
392 cur = xmlSecGetNextElementNode(cur->next);
393 cur = xmlSecGetNextElementNode(cur->next);
394 cur = xmlSecGetNextElementNode(cur->children);
396 if(!xmlSecCheckNodeName(cur, xmlSecNodePGPData, xmlSecDSigNs))
397 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
399 cur = xmlSecGetNextElementNode(cur->children);
400 static const xmlChar xmlSecNodePGPKeyPacket[] =
"PGPKeyPacket";
401 if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyPacket, xmlSecDSigNs))
404 cur = xmlSecGetNextElementNode(cur->next);
405 if(!xmlSecCheckNodeName(cur, xmlSecNodePGPKeyPacket, xmlSecDSigNs))
409 xmlFree(pSignatureValue);
416 xmlChar* pKeyPacket=xmlNodeGetContent(cur);
418 nRet = xmlSecBase64Decode_ex(pKeyPacket,
reinterpret_cast<xmlSecByte*
>(pKeyPacket), xmlStrlen(pKeyPacket), &nKeyLen);
420 throw RuntimeException(
"The GpgME library failed to initialize for the OpenPGP protocol.");
422 GpgME::Data data_key(
423 reinterpret_cast<char*
>(pKeyPacket),
426 rCtx.importKeys(data_key);
430 (void)data_text.seek(0,SEEK_SET);
431 (void)data_signature.seek(0,SEEK_SET);
432 verify_res=rCtx.verifyDetachedSignature(data_signature, data_text);
435 if( verify_res.isNull() || verify_res.numSignatures() == 0
437 || ( (verify_res.numSignatures() > 0)
438 && verify_res.signature(0).status().encodedError() > 0 ) )
441 xmlFree(pSignatureValue);
447 xmlFree(pSignatureValue);
450 cur = xmlSecGetNextElementNode(pNode->children);
452 cur = xmlSecGetNextElementNode(cur->children);
453 while( cur !=
nullptr )
456 if( xmlSecCheckNodeName(cur, xmlSecNodeReference, xmlSecDSigNs) )
458 xmlSecDSigReferenceCtxPtr pDsigRefCtx =
459 xmlSecDSigReferenceCtxCreate(pDsigCtx,
460 xmlSecDSigReferenceOriginSignedInfo);
461 if(pDsigRefCtx ==
nullptr)
465 if( xmlSecPtrListAdd(&(pDsigCtx->signedInfoReferences),
469 xmlSecDSigReferenceCtxDestroy(pDsigRefCtx);
473 if( xmlSecDSigReferenceCtxProcessNode(pDsigRefCtx, cur) < 0 )
477 if(pDsigRefCtx->status != xmlSecDSigStatusSucceeded)
479 pDsigCtx->status = xmlSecDSigStatusInvalid;
484 cur = xmlSecGetNextElementNode(cur->next);
488 aTemplate->setStatus(SecurityOperationStatus_OPERATION_SUCCEEDED);
491 xmlSecDSigCtxDestroy( pDsigCtx ) ;
495 if( xUriBinding.is() )
519 Sequence<OUString> seqServiceNames {
"com.sun.star.xml.crypto.XMLSignature" };
520 return seqServiceNames ;
524 return "com.sun.star.xml.security.bridge.xmlsec.XMLSignature_GpgImpl" ;
GpgME::Context & getGpgContext()
xmlNodePtr getNativeElement() const
virtual css::uno::Reference< css::xml::crypto::XXMLSignatureTemplate > SAL_CALL generate(const css::uno::Reference< css::xml::crypto::XXMLSignatureTemplate > &aTemplate, const css::uno::Reference< css::xml::crypto::XSecurityEnvironment > &aEnvironment) override
virtual css::uno::Reference< css::xml::crypto::XXMLSignatureTemplate > SAL_CALL validate(const css::uno::Reference< css::xml::crypto::XXMLSignatureTemplate > &aTemplate, const css::uno::Reference< css::xml::crypto::XXMLSecurityContext > &aContext) override
static css::uno::Reference< css::uno::XInterface > impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory > &aServiceManager)
virtual OUString SAL_CALL getImplementationName() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
static css::uno::Sequence< OUString > impl_getSupportedServiceNames()
virtual ~XMLSignature_GpgImpl() override
static OUString impl_getImplementationName()
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
void clearErrorRecorder()
#define SAL_INFO(area, stream)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int xmlRegisterStreamInputCallbacks(css::uno::Reference< css::xml::crypto::XUriBinding > const &aUriBinding)
int xmlUnregisterStreamInputCallbacks()