cool#9992 lok doc sign, hash extract: time for getCommandValues('Signature')

The final goal of this API is to give time & hash information about the
PDF signature, so once a 3rd-party produces the PKCS#7 signature, that
can be added to the document and the actual PDF sign can be re-run with
the same parameters.

This commit continues the replacement of XCertificate with
svl::crypto::SigningContext up to the point that the timestamp used in
svl/ can be exposed on the LOK API.

This is done by updating DocumentSignatureManager::add(),
PDFSignatureHelper::SetX509Certificate(),
vcl::filter::PDFDocument::Sign() and finally the svl::crypto::Signing
ctor to work with the signing context instead of an XCertificate
directly.

Time reporting works now, so add a test for that. The digest part still
needs doing.

Change-Id: I83f1274cd420b67194b7caf12b1027e623d4f7fe
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176404
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna 2024-11-11 11:36:12 +01:00
parent e02efcb136
commit 0de900cec7
20 changed files with 189 additions and 77 deletions

View file

@ -39,6 +39,7 @@ class SvStream;
struct SignatureInformation;
namespace svl::crypto {
class SigningContext;
/// Converts a hex-encoded string into a byte array.
SVL_DLLPUBLIC std::vector<unsigned char> DecodeHexString(std::string_view rHex);
@ -49,8 +50,8 @@ class SVL_DLLPUBLIC Signing
{
public:
Signing(css::uno::Reference<css::security::XCertificate> xCertificate) :
m_xCertificate(std::move(xCertificate))
Signing(svl::crypto::SigningContext& rSigningContext) :
m_rSigningContext(rSigningContext)
{
}
@ -84,7 +85,7 @@ public:
private:
/// The certificate to use for signing.
const css::uno::Reference<css::security::XCertificate> m_xCertificate;
svl::crypto::SigningContext& m_rSigningContext;
/// Data blocks (pointer-size pairs).
std::vector<std::pair<const void*, sal_Int32>> m_dataBlocks;
@ -99,7 +100,8 @@ class SVL_DLLPUBLIC SigningContext
public:
/// If set, the certificate used for signing.
css::uno::Reference<css::security::XCertificate> m_xCertificate;
/// If m_xCertificate is not set, the time that would be used.
/// If m_xCertificate is not set, the time that would be used, in milliseconds since the epoch
/// (1970-01-01 UTC).
sal_Int64 m_nSignatureTime = 0;
};

View file

@ -35,6 +35,10 @@ namespace tools
{
class Rectangle;
}
namespace svl::crypto
{
class SigningContext;
}
namespace vcl::filter
{
@ -588,8 +592,8 @@ public:
void SetSignatureLine(std::vector<sal_Int8>&& rSignatureLine);
void SetSignaturePage(size_t nPage);
/// Sign the read document with xCertificate in the edit buffer.
bool Sign(const css::uno::Reference<css::security::XCertificate>& xCertificate,
const OUString& rDescription, bool bAdES);
bool Sign(svl::crypto::SigningContext& rSigningContext, const OUString& rDescription,
bool bAdES);
/// Serializes the contents of the edit buffer.
bool Write(SvStream& rStream);
/// Get a list of signatures embedded into this document.

Binary file not shown.

View file

@ -9,6 +9,8 @@
#include <test/unoapi_test.hxx>
#include <boost/property_tree/json_parser.hpp>
#include <com/sun/star/drawing/XDrawView.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
@ -21,6 +23,7 @@
#include <sfx2/bindings.hxx>
#include <sfx2/lokhelper.hxx>
#include <sfx2/sfxbasemodel.hxx>
#include <tools/json_writer.hxx>
using namespace com::sun::star;
@ -109,6 +112,28 @@ CPPUNIT_TEST_FIXTURE(Sfx2ViewTest, testLokHelperAddCertifices)
// i.e. the signature status for an opened document was not updated when trusting a CA.
CPPUNIT_ASSERT_EQUAL(SignatureState::OK, pObjectShell->GetDocumentSignatureState());
}
CPPUNIT_TEST_FIXTURE(Sfx2ViewTest, testLokHelperCommandValuesSignature)
{
// Given an unsigned PDF file:
loadFromFile(u"unsigned.pdf");
// When extracting hashes:
tools::JsonWriter aWriter;
SfxLokHelper::getCommandValues(aWriter, ".uno:Signature");
OString aJson = aWriter.finishAndGetAsOString();
// Then make sure that we get a signature time:
CPPUNIT_ASSERT(SfxLokHelper::supportsCommand(u"Signature"));
std::stringstream aStream{ std::string(aJson) };
boost::property_tree::ptree aTree;
boost::property_tree::read_json(aStream, aTree);
// Non-zero timestamp:
auto it = aTree.find("signatureTime");
CPPUNIT_ASSERT(it != aTree.not_found());
auto nSignatureTime = it->second.get_value<sal_Int64>();
CPPUNIT_ASSERT(nSignatureTime != 0);
}
#endif
CPPUNIT_PLUGIN_IMPLEMENT();

View file

@ -950,22 +950,18 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer)
return false;
#else
// Create the PKCS#7 object.
css::uno::Sequence<sal_Int8> aDerEncoded = m_xCertificate->getEncoded();
if (!aDerEncoded.hasElements())
css::uno::Sequence<sal_Int8> aDerEncoded;
if (m_rSigningContext.m_xCertificate.is())
{
SAL_WARN("svl.crypto", "Crypto::Signing: empty certificate");
return false;
aDerEncoded = m_rSigningContext.m_xCertificate->getEncoded();
if (!aDerEncoded.hasElements())
{
SAL_WARN("svl.crypto", "Crypto::Signing: empty certificate");
return false;
}
}
#if USE_CRYPTO_NSS
CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast<char *>(aDerEncoded.getArray()), aDerEncoded.getLength());
if (!cert)
{
SAL_WARN("svl.crypto", "CERT_DecodeCertFromPackage failed");
return false;
}
std::vector<unsigned char> aHashResult;
{
comphelper::Hash aHash(comphelper::HashType::SHA256);
@ -980,6 +976,24 @@ bool Signing::Sign(OStringBuffer& rCMSHexBuffer)
digest.len = aHashResult.size();
PRTime now = PR_Now();
if (!m_rSigningContext.m_xCertificate.is())
{
// The context unit is milliseconds, PR_Now() unit is microseconds.
m_rSigningContext.m_nSignatureTime = now / 1000;
// No certificate is provided: don't actually sign -- just update the context with the
// parameters for the signing and return.
return false;
}
CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast<char *>(aDerEncoded.getArray()), aDerEncoded.getLength());
if (!cert)
{
SAL_WARN("svl.crypto", "CERT_DecodeCertFromPackage failed");
return false;
}
NSSCMSSignedData *cms_sd(nullptr);
NSSCMSSignerInfo *cms_signer(nullptr);
NSSCMSMessage *cms_msg = CreateCMSMessage(nullptr, &cms_sd, &cms_signer, cert, &digest);

View file

@ -1789,7 +1789,9 @@ void SwEditShell::SignParagraph()
return;
// 3. Sign it.
svl::crypto::Signing signing(xCertificate);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
svl::crypto::Signing signing(aSigningContext);
signing.AddDataRange(utf8Text.getStr(), utf8Text.getLength());
OStringBuffer sigBuf;
if (!signing.Sign(sigBuf))

View file

@ -855,8 +855,8 @@ void PDFDocument::WriteXRef(sal_uInt64 nXRefOffset, PDFReferenceElement const* p
}
}
bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificate,
const OUString& rDescription, bool bAdES)
bool PDFDocument::Sign(svl::crypto::SigningContext& rSigningContext, const OUString& rDescription,
bool bAdES)
{
m_aEditBuffer.Seek(STREAM_SEEK_TO_END);
m_aEditBuffer.WriteOString("\n");
@ -923,11 +923,14 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
m_aEditBuffer.WriteOString(aByteRangeBuffer);
// Create the PKCS#7 object.
css::uno::Sequence<sal_Int8> aDerEncoded = xCertificate->getEncoded();
if (!aDerEncoded.hasElements())
if (rSigningContext.m_xCertificate)
{
SAL_WARN("vcl.filter", "PDFDocument::Sign: empty certificate");
return false;
css::uno::Sequence<sal_Int8> aDerEncoded = rSigningContext.m_xCertificate->getEncoded();
if (!aDerEncoded.hasElements())
{
SAL_WARN("vcl.filter", "PDFDocument::Sign: empty certificate");
return false;
}
}
m_aEditBuffer.Seek(0);
@ -941,12 +944,15 @@ bool PDFDocument::Sign(const uno::Reference<security::XCertificate>& xCertificat
m_aEditBuffer.ReadBytes(aBuffer2.get(), nBufferSize2);
OStringBuffer aCMSHexBuffer;
svl::crypto::Signing aSigning(xCertificate);
svl::crypto::Signing aSigning(rSigningContext);
aSigning.AddDataRange(aBuffer1.get(), nBufferSize1);
aSigning.AddDataRange(aBuffer2.get(), nBufferSize2);
if (!aSigning.Sign(aCMSHexBuffer))
{
SAL_WARN("vcl.filter", "PDFDocument::Sign: PDFWriter::Sign() failed");
if (rSigningContext.m_xCertificate.is())
{
SAL_WARN("vcl.filter", "PDFDocument::Sign: PDFWriter::Sign() failed");
}
return false;
}

View file

@ -5727,7 +5727,9 @@ bool PDFWriterImpl::finalizeSignature()
}
OStringBuffer aCMSHexBuffer;
svl::crypto::Signing aSigning(m_aContext.SignCertificate);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = m_aContext.SignCertificate;
svl::crypto::Signing aSigning(aSigningContext);
aSigning.AddDataRange(buffer1.get(), bytesRead1);
aSigning.AddDataRange(buffer2.get(), bytesRead2);
aSigning.SetSignTSA(m_aContext.SignTSA);

View file

@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_use_libraries,xmlsecurity_pdfsigning, \
sal \
sax \
sfx \
svl \
test \
tl \
unotest \

View file

@ -23,6 +23,7 @@ $(eval $(call gb_Executable_use_libraries,pdfverify,\
cppu \
cppuhelper \
sal \
svl \
tl \
vcl \
xmlsecurity \

View file

@ -53,6 +53,10 @@ namespace uno
class XComponentContext;
}
}
namespace svl::crypto
{
class SigningContext;
}
class PDFSignatureHelper;
class Xmlsec;
@ -93,7 +97,7 @@ public:
SignatureStreamHelper ImplOpenSignatureStream(sal_Int32 nStreamOpenMode, bool bTempStream);
/// Add a new signature, using xCert as a signing certificate, and rDescription as description.
bool add(const css::uno::Reference<css::security::XCertificate>& xCert,
bool add(svl::crypto::SigningContext& rSigningContext,
const css::uno::Reference<css::xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant,
const OUString& rSignatureLineId = OUString(),

View file

@ -37,6 +37,10 @@ namespace xml::crypto
class XSecurityEnvironment;
}
}
namespace svl::crypto
{
class SigningContext;
}
class SvStream;
/// Handles signatures of a PDF file.
@ -44,7 +48,7 @@ class XMLSECURITY_DLLPUBLIC PDFSignatureHelper
{
SignatureInformations m_aSignatureInfos;
css::uno::Reference<css::security::XCertificate> m_xCertificate;
svl::crypto::SigningContext* m_pSigningContext = nullptr;
OUString m_aDescription;
public:
@ -59,7 +63,7 @@ public:
/// Return the ID of the next created signature.
sal_Int32 GetNewSecurityId() const;
/// Certificate to be used next time signing is performed.
void SetX509Certificate(const css::uno::Reference<css::security::XCertificate>& xCertificate);
void SetX509Certificate(svl::crypto::SigningContext& rSigningContext);
/// Comment / reason to be used next time signing is performed.
void SetDescription(const OUString& rDescription);
/// Append a new signature at the end of xInputStream.

View file

@ -29,6 +29,7 @@
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/filter/pdfdocument.hxx>
#include <vcl/filter/PDFiumLibrary.hxx>
#include <svl/cryptosign.hxx>
#include <documentsignaturemanager.hxx>
#include <pdfsignaturehelper.hxx>
@ -136,7 +137,9 @@ bool PDFSigningTest::sign(const OUString& rInURL, const OUString& rOutURL,
// Only try certificates that are already active and not expired
if (IsValid(cert, xSecurityEnvironment))
{
bool bSignResult = aDocument.Sign(cert, u"test"_ustr, /*bAdES=*/true);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = cert;
bool bSignResult = aDocument.Sign(aSigningContext, u"test"_ustr, /*bAdES=*/true);
#ifdef _WIN32
if (!bSignResult)
{

View file

@ -159,7 +159,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testDescription)
return;
OUString aDescription(u"SigningTest::testDescription"_ustr);
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@ -190,7 +192,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSA)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId, false);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId, false);
// Read back the signature and make sure that it's valid.
aManager.read(/*bUseTempStream=*/true);
@ -224,7 +228,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSAOOXML)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId,
/*bAdESCompliant=*/false);
// Read back the signature and make sure that it's valid.
@ -259,7 +265,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testECDSAPDF)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId,
/*bAdESCompliant=*/true);
// Read back the signature and make sure that it's valid.
@ -301,7 +309,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testOOXMLDescription)
return;
OUString aDescription(u"SigningTest::testDescription"_ustr);
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, false);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, false);
// Read back the signature and make sure that the description survives the roundtrip.
aManager.read(/*bUseTempStream=*/true);
@ -334,7 +344,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testOOXMLAppend)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, OUString(), nSecurityId, false);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, OUString(), nSecurityId, false);
// Read back the signatures and make sure that we have the expected amount.
aManager.read(/*bUseTempStream=*/true);
@ -860,7 +872,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdESNotype)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
/*bAdESCompliant=*/true);
// Write to storage.
@ -915,7 +929,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testXAdES)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
/*bAdESCompliant=*/true);
// Write to storage.
@ -969,7 +985,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT)
if (!xCertificate.is())
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
/*bAdESCompliant=*/true);
// Read back the signature and make sure that it's valid.
@ -982,7 +1000,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT)
rInformations[0].nStatus);
}
aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
/*bAdESCompliant=*/true);
aManager.read(/*bUseTempStream=*/true);
{
@ -993,7 +1011,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_ODT)
rInformations[1].nStatus);
}
aManager.add(xCertificate, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
aManager.add(aSigningContext, mxSecurityContext, /*rDescription=*/OUString(), nSecurityId,
/*bAdESCompliant=*/true);
aManager.read(/*bUseTempStream=*/true);
{
@ -1042,7 +1060,9 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
return;
sal_Int32 nSecurityId;
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId,
/*bAdESCompliant=*/false);
aManager.read(/*bUseTempStream=*/true);
{
@ -1053,7 +1073,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
rInformations[0].nStatus);
}
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId,
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId,
/*bAdESCompliant=*/false);
aManager.read(/*bUseTempStream=*/true);
{
@ -1064,7 +1084,7 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testSigningMultipleTimes_OOXML)
rInformations[1].nStatus);
}
aManager.add(xCertificate, mxSecurityContext, u""_ustr, nSecurityId,
aManager.add(aSigningContext, mxSecurityContext, u""_ustr, nSecurityId,
/*bAdESCompliant=*/false);
aManager.read(/*bUseTempStream=*/true);
{
@ -1191,11 +1211,14 @@ CPPUNIT_TEST_FIXTURE(SigningTest, testImplicitScriptSign)
OUString aDescription;
sal_Int32 nSecurityId;
bool bAdESCompliant = true;
aScriptManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant);
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
aScriptManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId,
bAdESCompliant);
aScriptManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
aScriptManager.write(bAdESCompliant);
aManager.setScriptingSignatureStream(xScriptingStream);
aManager.add(xCertificate, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant);
aManager.add(aSigningContext, mxSecurityContext, aDescription, nSecurityId, bAdESCompliant);
aManager.read(/*bUseTempStream=*/true, /*bCacheLastSignature=*/false);
aManager.write(bAdESCompliant);

View file

@ -14,6 +14,7 @@
#include <comphelper/storagehelper.hxx>
#include <sfx2/lokhelper.hxx>
#include <svl/cryptosign.hxx>
#include <documentsignaturemanager.hxx>
@ -83,7 +84,10 @@ CPPUNIT_TEST_FIXTURE(Test, testInsertPrivateKey)
xSecurityEnvironment->getCertificateCharacters(xCertificate);
OUString aDescription;
sal_Int32 nSecurityId;
CPPUNIT_ASSERT(aManager.add(xCertificate, xSecurityContext, aDescription, nSecurityId, false));
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
CPPUNIT_ASSERT(
aManager.add(aSigningContext, xSecurityContext, aDescription, nSecurityId, false));
// Then make sure that signing succeeds:
aManager.read(/*bUseTempStream=*/true);

View file

@ -297,7 +297,9 @@ sal_Bool DocumentDigitalSignatures::signSignatureLine(
xSecurityContext = aSignatureManager.getSecurityContext();
sal_Int32 nSecurityId;
bool bSuccess = aSignatureManager.add(xCertificate, xSecurityContext, aComment, nSecurityId,
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = xCertificate;
bool bSuccess = aSignatureManager.add(aSigningContext, xSecurityContext, aComment, nSecurityId,
true, aSignatureLineId, xValidGraphic, xInvalidGraphic);
if (!bSuccess)
return false;
@ -852,7 +854,7 @@ bool DocumentDigitalSignatures::signWithCertificateImpl(
sal_Int32 nSecurityId;
bool bSuccess = aSignatureManager.add(rSigningContext.m_xCertificate, xSecurityContext, u""_ustr, nSecurityId, true);
bool bSuccess = aSignatureManager.add(rSigningContext, xSecurityContext, u""_ustr, nSecurityId, true);
if (!bSuccess)
return false;

View file

@ -53,6 +53,7 @@
#include <vcl/weld.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/viewsh.hxx>
#include <svl/cryptosign.hxx>
#ifdef _WIN32
#include <o3tl/char16_t2wchar_t.hxx>
@ -510,9 +511,11 @@ void DigitalSignaturesDialog::AddButtonHdlImpl()
{
sal_Int32 nSecurityId;
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = aChooser->GetSelectedCertificates()[0];
if (moScriptSignatureManager)
{
if (!moScriptSignatureManager->add(aChooser->GetSelectedCertificates()[0],
if (!moScriptSignatureManager->add(aSigningContext,
aChooser->GetSelectedSecurityContext(),
aChooser->GetDescription(), nSecurityId,
m_bAdESCompliant))
@ -526,7 +529,7 @@ void DigitalSignaturesDialog::AddButtonHdlImpl()
maSignatureManager.setScriptingSignatureStream(moScriptSignatureManager->getSignatureStream());
}
if (!maSignatureManager.add(aChooser->GetSelectedCertificates()[0], aChooser->GetSelectedSecurityContext(),
if (!maSignatureManager.add(aSigningContext, aChooser->GetSelectedSecurityContext(),
aChooser->GetDescription(), nSecurityId, m_bAdESCompliant))
return;
mbSignaturesChanged = true;

View file

@ -42,6 +42,7 @@
#include <sal/log.hxx>
#include <tools/datetime.hxx>
#include <o3tl/string_view.hxx>
#include <svl/cryptosign.hxx>
#include <certificate.hxx>
#include <biginteger.hxx>
@ -327,20 +328,23 @@ SignatureStreamHelper DocumentSignatureManager::ImplOpenSignatureStream(sal_Int3
}
bool DocumentSignatureManager::add(
const uno::Reference<security::XCertificate>& xCert,
svl::crypto::SigningContext& rSigningContext,
const uno::Reference<xml::crypto::XXMLSecurityContext>& xSecurityContext,
const OUString& rDescription, sal_Int32& nSecurityId, bool bAdESCompliant,
const OUString& rSignatureLineId, const Reference<XGraphic>& xValidGraphic,
const Reference<XGraphic>& xInvalidGraphic)
{
if (!xCert.is())
uno::Reference<security::XCertificate> xCert = rSigningContext.m_xCertificate;
uno::Reference<lang::XServiceInfo> xServiceInfo(xSecurityContext, uno::UNO_QUERY);
if (!xCert.is()
&& xServiceInfo->getImplementationName()
== "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
{
SAL_WARN("xmlsecurity.helper", "no certificate selected");
return false;
}
// GPG or X509 key?
uno::Reference<lang::XServiceInfo> xServiceInfo(xSecurityContext, uno::UNO_QUERY);
if (xServiceInfo->getImplementationName()
== "com.sun.star.xml.security.gpg.XMLSecurityContext_GpgImpl")
{
@ -374,6 +378,24 @@ bool DocumentSignatureManager::add(
}
else
{
if (!mxStore.is())
{
// Something not ZIP based, try PDF.
nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
getPDFSignatureHelper().SetX509Certificate(rSigningContext);
getPDFSignatureHelper().SetDescription(rDescription);
uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
if (!getPDFSignatureHelper().Sign(mxModel, xInputStream, bAdESCompliant))
{
if (rSigningContext.m_xCertificate.is())
{
SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
}
return false;
}
return true;
}
OUString aCertSerial = xmlsecurity::bigIntegerToNumericString(xCert->getSerialNumber());
if (aCertSerial.isEmpty())
{
@ -381,21 +403,6 @@ bool DocumentSignatureManager::add(
return false;
}
if (!mxStore.is())
{
// Something not ZIP based, try PDF.
nSecurityId = getPDFSignatureHelper().GetNewSecurityId();
getPDFSignatureHelper().SetX509Certificate(xCert);
getPDFSignatureHelper().SetDescription(rDescription);
uno::Reference<io::XInputStream> xInputStream(mxSignatureStream, uno::UNO_QUERY);
if (!getPDFSignatureHelper().Sign(mxModel, xInputStream, bAdESCompliant))
{
SAL_WARN("xmlsecurity.helper", "PDFSignatureHelper::Sign() failed");
return false;
}
return true;
}
maSignatureHelper.StartMission(xSecurityContext);
nSecurityId = maSignatureHelper.GetNewSecurityId();

View file

@ -536,10 +536,9 @@ PDFSignatureHelper::GetDocumentSignatureInformations(
sal_Int32 PDFSignatureHelper::GetNewSecurityId() const { return m_aSignatureInfos.size(); }
void PDFSignatureHelper::SetX509Certificate(
const uno::Reference<security::XCertificate>& xCertificate)
void PDFSignatureHelper::SetX509Certificate(svl::crypto::SigningContext& rSigningContext)
{
m_xCertificate = xCertificate;
m_pSigningContext = &rSigningContext;
}
void PDFSignatureHelper::SetDescription(const OUString& rDescription)
@ -571,9 +570,12 @@ bool PDFSignatureHelper::Sign(const uno::Reference<frame::XModel>& xModel,
aDocument.SetSignatureLine(std::move(aSignatureLineShape));
}
if (!aDocument.Sign(m_xCertificate, m_aDescription, bAdES))
if (!m_pSigningContext || !aDocument.Sign(*m_pSigningContext, m_aDescription, bAdES))
{
SAL_WARN("xmlsecurity.helper", "failed to sign");
if (m_pSigningContext && m_pSigningContext->m_xCertificate.is())
{
SAL_WARN("xmlsecurity.helper", "failed to sign");
}
return false;
}

View file

@ -26,6 +26,7 @@
#include <vcl/filter/pdfdocument.hxx>
#include <comphelper/scopeguard.hxx>
#include <svl/sigstruct.hxx>
#include <svl/cryptosign.hxx>
#include <pdfsignaturehelper.hxx>
@ -183,7 +184,9 @@ int pdfVerify(int nArgc, char** pArgv)
SAL_WARN("xmlsecurity.workben", "no signing certificates found");
return 1;
}
if (!aDocument.Sign(aCertificates[0], u"pdfverify"_ustr, /*bAdES=*/true))
svl::crypto::SigningContext aSigningContext;
aSigningContext.m_xCertificate = aCertificates[0];
if (!aDocument.Sign(aSigningContext, u"pdfverify"_ustr, /*bAdES=*/true))
{
SAL_WARN("xmlsecurity.workben", "failed to sign");
return 1;