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:
parent
e02efcb136
commit
0de900cec7
20 changed files with 189 additions and 77 deletions
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
BIN
sfx2/qa/cppunit/data/unsigned.pdf
Normal file
BIN
sfx2/qa/cppunit/data/unsigned.pdf
Normal file
Binary file not shown.
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,6 +22,7 @@ $(eval $(call gb_CppunitTest_use_libraries,xmlsecurity_pdfsigning, \
|
|||
sal \
|
||||
sax \
|
||||
sfx \
|
||||
svl \
|
||||
test \
|
||||
tl \
|
||||
unotest \
|
||||
|
|
|
@ -23,6 +23,7 @@ $(eval $(call gb_Executable_use_libraries,pdfverify,\
|
|||
cppu \
|
||||
cppuhelper \
|
||||
sal \
|
||||
svl \
|
||||
tl \
|
||||
vcl \
|
||||
xmlsecurity \
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue