desktop/source/lib/init.cxx    |  125 -----------------------------------------
 include/sfx2/lokhelper.hxx     |    4 +
 sfx2/source/view/lokhelper.cxx |   97 +++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+), 122 deletions(-)

New commits:
commit ab2fd7c9af1f01b5582f3c990b64cd6c9ceb37e1
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Sep 20 08:13:04 2024 +0200
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Mon Sep 23 12:25:54 2024 +0200

    cool#9992 lok doc sign: extract duplicated code to SfxLokHelper
    
    I want to improve extractCertificate() so it can work on a certificate
    chain, but that's easier when this code is not directly in desktop/, but
    at some lower level.
    
    This allows covering the code with tests from CppunitTest_sfx2_view in a
    follow-up change.
    
    If this code will be needed by some non-LOK area as well, then it can be
    moved down further, but let's wait for a second area first.
    
    (cherry picked from commit 7bad76c3a5b319f8ede74be8f78e5645f9ffd050)
    
    Change-Id: I6291da0c3e56aed7dca1a8dc1446209044cace92
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173811
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index d1f7603d8d05..13efa144ba57 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -818,48 +818,6 @@ static uno::Reference<css::lang::XMultiComponentFactory> 
xFactory;
 
 namespace {
 
-std::string extractCertificate(const std::string & certificate)
-{
-    static constexpr std::string_view header("-----BEGIN CERTIFICATE-----");
-    static constexpr std::string_view footer("-----END CERTIFICATE-----");
-
-    std::string result;
-
-    size_t pos1 = certificate.find(header);
-    if (pos1 == std::string::npos)
-        return result;
-
-    size_t pos2 = certificate.find(footer, pos1 + 1);
-    if (pos2 == std::string::npos)
-        return result;
-
-    pos1 = pos1 + header.length();
-    pos2 = pos2 - pos1;
-
-    return certificate.substr(pos1, pos2);
-}
-
-std::string extractPrivateKey(const std::string & privateKey)
-{
-    static constexpr std::string_view header("-----BEGIN PRIVATE KEY-----");
-    static constexpr std::string_view footer("-----END PRIVATE KEY-----");
-
-    std::string result;
-
-    size_t pos1 = privateKey.find(header);
-    if (pos1 == std::string::npos)
-        return result;
-
-    size_t pos2 = privateKey.find(footer, pos1 + 1);
-    if (pos2 == std::string::npos)
-        return result;
-
-    pos1 = pos1 + header.length();
-    pos2 = pos2 - pos1;
-
-    return privateKey.substr(pos1, pos2);
-}
-
 OUString lcl_getCurrentDocumentMimeType(const LibLODocument_Impl* pDocument)
 {
     SfxBaseModel* pBaseModel = 
dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
@@ -3187,47 +3145,9 @@ static bool lo_signDocument(LibreOfficeKit* /*pThis*/,
     if (!xContext.is())
         return false;
 
-    uno::Sequence<sal_Int8> aCertificateSequence;
-
     std::string aCertificateString(reinterpret_cast<const 
char*>(pCertificateBinary), nCertificateBinarySize);
-    std::string aCertificateBase64String = 
extractCertificate(aCertificateString);
-    if (!aCertificateBase64String.empty())
-    {
-        OUString aBase64OUString = 
OUString::createFromAscii(aCertificateBase64String);
-        comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
-    }
-    else
-    {
-        aCertificateSequence.realloc(nCertificateBinarySize);
-        std::copy(pCertificateBinary, pCertificateBinary + 
nCertificateBinarySize, aCertificateSequence.getArray());
-    }
-
-    uno::Sequence<sal_Int8> aPrivateKeySequence;
     std::string aPrivateKeyString(reinterpret_cast<const 
char*>(pPrivateKeyBinary), nPrivateKeyBinarySize);
-    std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
-    if (!aPrivateKeyBase64String.empty())
-    {
-        OUString aBase64OUString = 
OUString::createFromAscii(aPrivateKeyBase64String);
-        comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
-    }
-    else
-    {
-        aPrivateKeySequence.realloc(nPrivateKeyBinarySize);
-        std::copy(pPrivateKeyBinary, pPrivateKeyBinary + 
nPrivateKeyBinarySize, aPrivateKeySequence.getArray());
-    }
-
-    uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = 
xml::crypto::SEInitializer::create(xContext);
-    uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = 
xSEInitializer->createSecurityContext(OUString());
-    if (!xSecurityContext.is())
-        return false;
-
-    uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = 
xSecurityContext->getSecurityEnvironment();
-    uno::Reference<xml::crypto::XCertificateCreator> 
xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
-
-    if (!xCertificateCreator.is())
-        return false;
-
-    uno::Reference<security::XCertificate> xCertificate = 
xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, 
aPrivateKeySequence);
+    uno::Reference<security::XCertificate> xCertificate = 
SfxLokHelper::getSigningCertificate(aCertificateString, aPrivateKeyString);
 
     if (!xCertificate.is())
         return false;
@@ -7332,48 +7252,9 @@ static bool 
doc_insertCertificate(LibreOfficeKitDocument* pThis,
     if (!pObjectShell)
         return false;
 
-    uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = 
xml::crypto::SEInitializer::create(xContext);
-    uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = 
xSEInitializer->createSecurityContext(OUString());
-    if (!xSecurityContext.is())
-        return false;
-
-    uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = 
xSecurityContext->getSecurityEnvironment();
-    uno::Reference<xml::crypto::XCertificateCreator> 
xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
-
-    if (!xCertificateCreator.is())
-        return false;
-
-    uno::Sequence<sal_Int8> aCertificateSequence;
-
     std::string aCertificateString(reinterpret_cast<const 
char*>(pCertificateBinary), nCertificateBinarySize);
-    std::string aCertificateBase64String = 
extractCertificate(aCertificateString);
-    if (!aCertificateBase64String.empty())
-    {
-        OUString aBase64OUString = 
OUString::createFromAscii(aCertificateBase64String);
-        comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
-    }
-    else
-    {
-        aCertificateSequence.realloc(nCertificateBinarySize);
-        std::copy(pCertificateBinary, pCertificateBinary + 
nCertificateBinarySize, aCertificateSequence.getArray());
-    }
-
-    uno::Sequence<sal_Int8> aPrivateKeySequence;
     std::string aPrivateKeyString(reinterpret_cast<const 
char*>(pPrivateKeyBinary), nPrivateKeySize);
-    std::string aPrivateKeyBase64String = extractPrivateKey(aPrivateKeyString);
-    if (!aPrivateKeyBase64String.empty())
-    {
-        OUString aBase64OUString = 
OUString::createFromAscii(aPrivateKeyBase64String);
-        comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
-    }
-    else
-    {
-        aPrivateKeySequence.realloc(nPrivateKeySize);
-        std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeySize, 
aPrivateKeySequence.getArray());
-    }
-
-    uno::Reference<security::XCertificate> xCertificate = 
xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, 
aPrivateKeySequence);
-
+    uno::Reference<security::XCertificate> xCertificate = 
SfxLokHelper::getSigningCertificate(aCertificateString, aPrivateKeyString);
     if (!xCertificate.is())
         return false;
 
@@ -7418,7 +7299,7 @@ static bool doc_addCertificate(LibreOfficeKitDocument* 
pThis,
     uno::Sequence<sal_Int8> aCertificateSequence;
 
     std::string aCertificateString(reinterpret_cast<const 
char*>(pCertificateBinary), nCertificateBinarySize);
-    std::string aCertificateBase64String = 
extractCertificate(aCertificateString);
+    std::string aCertificateBase64String = 
SfxLokHelper::extractCertificate(aCertificateString);
     if (!aCertificateBase64String.empty())
     {
         OUString aBase64OUString = 
OUString::createFromAscii(aCertificateBase64String);
diff --git a/include/sfx2/lokhelper.hxx b/include/sfx2/lokhelper.hxx
index 96974417430e..d6c514cd4f33 100644
--- a/include/sfx2/lokhelper.hxx
+++ b/include/sfx2/lokhelper.hxx
@@ -11,6 +11,7 @@
 #define INCLUDED_SFX2_LOKHELPER_HXX
 
 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
 
 #include <vcl/IDialogRenderable.hxx>
 #include <vcl/ITiledRenderable.hxx>
@@ -237,6 +238,9 @@ public:
 
     static void notifyLog(const std::ostringstream& stream);
 
+    static std::string extractCertificate(const std::string& rCert);
+    static css::uno::Reference<css::security::XCertificate> 
getSigningCertificate(const std::string& rCert, const std::string& rKey);
+
 private:
     static int createView(SfxViewFrame& rViewFrame, ViewShellDocId docId);
 };
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 66f8be5f2800..eb1a42bfbad9 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -18,6 +18,8 @@
 
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/ui/ContextChangeEventObject.hpp>
+#include <com/sun/star/xml/crypto/SEInitializer.hpp>
+#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
 
 #include <comphelper/processfactory.hxx>
 #include <o3tl/string_view.hxx>
@@ -37,6 +39,7 @@
 #include <comphelper/lok.hxx>
 #include <sfx2/msgpool.hxx>
 #include <comphelper/scopeguard.hxx>
+#include <comphelper/base64.hxx>
 #include <tools/json_writer.hxx>
 
 #include <boost/property_tree/json_parser.hpp>
@@ -823,6 +826,100 @@ void SfxLokHelper::notifyLog(const std::ostringstream& 
stream)
     }
 }
 
+std::string SfxLokHelper::extractCertificate(const std::string & certificate)
+{
+    static constexpr std::string_view header("-----BEGIN CERTIFICATE-----");
+    static constexpr std::string_view footer("-----END CERTIFICATE-----");
+
+    std::string result;
+
+    size_t pos1 = certificate.find(header);
+    if (pos1 == std::string::npos)
+        return result;
+
+    size_t pos2 = certificate.find(footer, pos1 + 1);
+    if (pos2 == std::string::npos)
+        return result;
+
+    pos1 = pos1 + header.length();
+    pos2 = pos2 - pos1;
+
+    return certificate.substr(pos1, pos2);
+}
+
+namespace
+{
+std::string extractKey(const std::string & privateKey)
+{
+    static constexpr std::string_view header("-----BEGIN PRIVATE KEY-----");
+    static constexpr std::string_view footer("-----END PRIVATE KEY-----");
+
+    std::string result;
+
+    size_t pos1 = privateKey.find(header);
+    if (pos1 == std::string::npos)
+        return result;
+
+    size_t pos2 = privateKey.find(footer, pos1 + 1);
+    if (pos2 == std::string::npos)
+        return result;
+
+    pos1 = pos1 + header.length();
+    pos2 = pos2 - pos1;
+
+    return privateKey.substr(pos1, pos2);
+}
+}
+
+css::uno::Reference<css::security::XCertificate> 
SfxLokHelper::getSigningCertificate(const std::string& rCert, const 
std::string& rKey)
+{
+    uno::Reference<uno::XComponentContext> xContext = 
comphelper::getProcessComponentContext();
+    uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = 
xml::crypto::SEInitializer::create(xContext);
+    uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext = 
xSEInitializer->createSecurityContext(OUString());
+    if (!xSecurityContext.is())
+    {
+        return {};
+    }
+
+    uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment = 
xSecurityContext->getSecurityEnvironment();
+    uno::Reference<xml::crypto::XCertificateCreator> 
xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
+
+    if (!xCertificateCreator.is())
+    {
+        return {};
+    }
+
+    uno::Sequence<sal_Int8> aCertificateSequence;
+
+    std::string aCertificateBase64String = extractCertificate(rCert);
+    if (!aCertificateBase64String.empty())
+    {
+        OUString aBase64OUString = 
OUString::createFromAscii(aCertificateBase64String);
+        comphelper::Base64::decode(aCertificateSequence, aBase64OUString);
+    }
+    else
+    {
+        aCertificateSequence.realloc(rCert.size());
+        std::copy(rCert.c_str(), rCert.c_str() + rCert.size(), 
aCertificateSequence.getArray());
+    }
+
+    uno::Sequence<sal_Int8> aPrivateKeySequence;
+    std::string aPrivateKeyBase64String = extractKey(rKey);
+    if (!aPrivateKeyBase64String.empty())
+    {
+        OUString aBase64OUString = 
OUString::createFromAscii(aPrivateKeyBase64String);
+        comphelper::Base64::decode(aPrivateKeySequence, aBase64OUString);
+    }
+    else
+    {
+        aPrivateKeySequence.realloc(rKey.size());
+        std::copy(rKey.c_str(), rKey.c_str() + rKey.size(), 
aPrivateKeySequence.getArray());
+    }
+
+    uno::Reference<security::XCertificate> xCertificate = 
xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, 
aPrivateKeySequence);
+    return xCertificate;
+}
+
 void SfxLokHelper::notifyUpdate(SfxViewShell const* pThisView, int nType)
 {
     if (DisableCallbacks::disabled())

Reply via email to