[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - 4 commits - desktop/qa desktop/source include/LibreOfficeKit xmlsecurity/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Thu Nov 8 14:16:31 UTC 2018


 desktop/qa/desktop_lib/test_desktop_lib.cxx                   |   35 ++
 desktop/source/lib/init.cxx                                   |   44 ++-
 include/LibreOfficeKit/LibreOfficeKit.h                       |    4 
 include/LibreOfficeKit/LibreOfficeKit.hxx                     |    8 
 xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx |  120 +++++++---
 xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx |   18 +
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx     |   26 ++
 xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx     |    6 
 8 files changed, 206 insertions(+), 55 deletions(-)

New commits:
commit 81400dcc0a062227021485dd994561dcfb454f9b
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Oct 24 10:52:09 2018 +0200
Commit:     Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Nov 8 15:08:31 2018 +0100

    lok: Get the object shell from the document
    
    Change-Id: Id62c0db3c9f404aaab70de0a73a20b2bb57b0393
    Reviewed-on: https://gerrit.libreoffice.org/62272
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit 15018316bca863c9d7329572af906850d47e0c63)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 79ca5055db1f..56e2bcfec907 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -3687,13 +3687,27 @@ static void doc_postWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindo
 }
 
 // CERTIFICATE AND DOCUMENT SIGNING
-static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/,
+static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
                                   const unsigned char* pCertificateBinary, const int nCertificateBinarySize,
                                   const unsigned char* pPrivateKeyBinary, const int nPrivateKeySize)
 {
     if (!xContext.is())
         return false;
 
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+
+    if (!pDocument->mxComponent.is())
+        return false;
+
+    SfxBaseModel* pBaseModel = dynamic_cast<SfxBaseModel*>(pDocument->mxComponent.get());
+    if (!pBaseModel)
+        return false;
+
+    SfxObjectShell* pObjectShell = pBaseModel->GetObjectShell();
+
+    if (!pObjectShell)
+        return false;
+
     uno::Reference<xml::crypto::XSEInitializer> xSEInitializer = xml::crypto::SEInitializer::create(xContext);
     uno::Reference<xml::crypto::XXMLSecurityContext> xSecurityContext;
     xSecurityContext = xSEInitializer->createSecurityContext(OUString());
@@ -3719,16 +3733,7 @@ static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/,
     if (!xCertificate.is())
         return false;
 
-    printf("CERTIFICATE\n\tIssuerName: %s \n\tSubjectName: %s\n\tPK %s\n\n",
-            xCertificate->getIssuerName().toUtf8().getStr(),
-            xCertificate->getSubjectName().toUtf8().getStr(),
-            xCertificate->getSubjectPublicKeyAlgorithm().toUtf8().getStr());
-
-    SfxObjectShell* pDoc = SfxObjectShell::Current();
-    if (!pDoc)
-        return false;
-
-    return pDoc->SignDocumentContentUsingCertificate(xCertificate);
+    return pObjectShell->SignDocumentContentUsingCertificate(xCertificate);
 }
 
 static int doc_getSignatureState(LibreOfficeKitDocument* pThis)
commit 025d881e56cdd2bf085a4df8f9f0183817df768f
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Wed Oct 24 10:27:26 2018 +0200
Commit:     Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Nov 8 15:08:10 2018 +0100

    fix importing the certificate and private key
    
    If importing the certificate and private key is done separately,
    they don't associate with each other, so with this you can add
    the private key to the certificate that it belongs to. If the
    private key is set in this way, then getPrivateKey() call doesn't
    look into the database but just returns the private key stored
    in the member variable.
    
    Additionally use CERT_DecodeCertFromPackage to import the DER
    certificate from the imput as CERT_DecodeDERCertificate doesn't
    import a complete certificate and doesn't add it into the
    certificate database.
    
    Change-Id: I29876030f167cc5fa6b887f9bfeb0b84622c751e
    Reviewed-on: https://gerrit.libreoffice.org/62271
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit 2286137c40a2abb26d36beb906962baffd779312)

diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
index 035896932ed3..a6905b96079f 100644
--- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
@@ -527,6 +527,30 @@ Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl::buildCertifi
     return Sequence< Reference < XCertificate > >();
 }
 
+X509Certificate_NssImpl* SecurityEnvironment_NssImpl::createAndAddCertificateFromPackage(
+                                                        const css::uno::Sequence<sal_Int8>& raDERCertificate,
+                                                        OUString const & raString)
+{
+    auto pCertificateBytes = reinterpret_cast<char *>(const_cast<sal_Int8 *>(raDERCertificate.getConstArray()));
+    CERTCertificate* pCERTCertificate = CERT_DecodeCertFromPackage(pCertificateBytes, raDERCertificate.getLength());
+
+    if (!pCERTCertificate)
+        return nullptr;
+
+    OString aTrustString = OUStringToOString(raString, RTL_TEXTENCODING_ASCII_US);
+
+    CERTCertTrust aTrust;
+    if (CERT_DecodeTrustString(&aTrust, aTrustString.getStr()) != SECSuccess)
+        return nullptr;
+
+    if (CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), pCERTCertificate, &aTrust) != SECSuccess)
+        return nullptr;
+
+    X509Certificate_NssImpl* pX509Certificate = new X509Certificate_NssImpl();
+    pX509Certificate->setCert(pCERTCertificate);
+    return pX509Certificate;
+}
+
 X509Certificate_NssImpl* SecurityEnvironment_NssImpl::createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate)
 {
     X509Certificate_NssImpl* pX509Certificate = nullptr;
@@ -945,68 +969,71 @@ xmlSecKeysMngrPtr SecurityEnvironment_NssImpl::createKeysManager() {
     // Adopt the private key of the signing certificate, if it has any.
     if (auto pCertificate = dynamic_cast<X509Certificate_NssImpl*>(m_xSigningCertificate.get()))
     {
-        if (auto pCERTCertificate = const_cast<CERTCertificate*>(pCertificate->getNssCert()))
+        SECKEYPrivateKey* pPrivateKey = pCertificate->getPrivateKey();
+        if (pPrivateKey)
         {
-            if (pCERTCertificate && pCERTCertificate->slot)
-            {
-                SECKEYPrivateKey* pPrivateKey = PK11_FindPrivateKeyFromCert(pCERTCertificate->slot, pCERTCertificate, nullptr);
-                xmlSecKeyDataPtr pKeyData = xmlSecNssPKIAdoptKey(pPrivateKey, nullptr);
-                xmlSecKeyPtr pKey = xmlSecKeyCreate();
-                xmlSecKeySetValue(pKey, pKeyData);
-                xmlSecNssAppDefaultKeysMngrAdoptKey(pKeysMngr, pKey);
-            }
-            else
-            {
-                SAL_WARN("xmlsecurity.xmlsec", "Can't get the private key from the certificate.");
-            }
+            xmlSecKeyDataPtr pKeyData = xmlSecNssPKIAdoptKey(pPrivateKey, nullptr);
+            xmlSecKeyPtr pKey = xmlSecKeyCreate();
+            xmlSecKeySetValue(pKey, pKeyData);
+            xmlSecNssAppDefaultKeysMngrAdoptKey(pKeysMngr, pKey);
+        }
+        else
+        {
+            SAL_WARN("xmlsecurity.xmlsec", "Can't get the private key from the certificate.");
         }
     }
 
-    return pKeysMngr ;
+    return pKeysMngr;
 }
+
 void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) {
     if( pKeysMngr != nullptr ) {
         xmlSecKeysMngrDestroy( pKeysMngr ) ;
     }
 }
 
-uno::Reference<security::XCertificate> SecurityEnvironment_NssImpl::createDERCertificateWithPrivateKey(
-        Sequence<sal_Int8> const & raDERCertificate, Sequence<sal_Int8> const & raPrivateKey)
+SECKEYPrivateKey* SecurityEnvironment_NssImpl::insertPrivateKey(css::uno::Sequence<sal_Int8> const & raPrivateKey)
 {
-    SECStatus nStatus = SECSuccess;
-
     PK11SlotInfo* pSlot = PK11_GetInternalKeySlot();
+
     if (!pSlot)
-        return uno::Reference<security::XCertificate>();
+        return nullptr;
 
     SECItem pDerPrivateKeyInfo;
     pDerPrivateKeyInfo.data = reinterpret_cast<unsigned char *>(const_cast<sal_Int8 *>(raPrivateKey.getConstArray()));
     pDerPrivateKeyInfo.len = raPrivateKey.getLength();
 
-    const unsigned int keyUsage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
+    const unsigned int aKeyUsage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
     SECKEYPrivateKey* pPrivateKey = nullptr;
 
     bool bPermanent = false;
     bool bSensitive = false;
 
-    nStatus = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+    SECStatus nStatus = PK11_ImportDERPrivateKeyInfoAndReturnKey(
           pSlot, &pDerPrivateKeyInfo, nullptr, nullptr, bPermanent, bSensitive,
-          keyUsage, &pPrivateKey, nullptr);
+          aKeyUsage, &pPrivateKey, nullptr);
 
     if (nStatus != SECSuccess)
-        return uno::Reference<security::XCertificate>();
+        return nullptr;
+
+    return pPrivateKey;
+}
+
+uno::Reference<security::XCertificate> SecurityEnvironment_NssImpl::createDERCertificateWithPrivateKey(
+        Sequence<sal_Int8> const & raDERCertificate, Sequence<sal_Int8> const & raPrivateKey)
+{
+
+    SECKEYPrivateKey* pPrivateKey = insertPrivateKey(raPrivateKey);
 
     if (!pPrivateKey)
         return uno::Reference<security::XCertificate>();
 
-    X509Certificate_NssImpl* pX509Certificate = createX509CertificateFromDER(raDERCertificate);
+    X509Certificate_NssImpl* pX509Certificate = createAndAddCertificateFromPackage(raDERCertificate, "TCu,Cu,Tu");
+
     if (!pX509Certificate)
         return uno::Reference<security::XCertificate>();
 
-    addCryptoSlot(pSlot);
-
-    CERTCertificate* pCERTCertificate = const_cast<CERTCertificate*>(pX509Certificate->getNssCert());
-    pCERTCertificate->slot = pSlot;
+    pX509Certificate->setCustomPrivateKey(pPrivateKey);
 
     return pX509Certificate;
 }
diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
index becde1168661..94dad6235767 100644
--- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
+++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
@@ -154,9 +154,15 @@ private:
         static void destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr) ;
 
 private:
+
         void updateSlots();
 
-        X509Certificate_NssImpl* createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate);
+        X509Certificate_NssImpl* createAndAddCertificateFromPackage(
+                                    const css::uno::Sequence<sal_Int8>& raDerCertificate,
+                                    OUString const & raString);
+        SECKEYPrivateKey* insertPrivateKey(css::uno::Sequence<sal_Int8> const & raPrivateKey);
+
+        X509Certificate_NssImpl* createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& raDerCertificate);
 
           /// @throws css::uno::Exception
           /// @throws css::uno::RuntimeException
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
index 941f8364f237..1bda73af613b 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.cxx
@@ -45,7 +45,8 @@ using ::com::sun::star::security::XCertificate ;
 using ::com::sun::star::util::DateTime ;
 
 X509Certificate_NssImpl::X509Certificate_NssImpl() :
-    m_pCert( nullptr )
+    m_pCert(nullptr),
+    m_pPrivateKey(nullptr)
 {
 }
 
@@ -330,6 +331,29 @@ void X509Certificate_NssImpl::setRawCert( const Sequence< sal_Int8 >& rawCert )
     m_pCert = cert ;
 }
 
+void X509Certificate_NssImpl::setCustomPrivateKey(SECKEYPrivateKey* pPrivateKey)
+{
+    m_pPrivateKey = pPrivateKey;
+}
+
+SECKEYPrivateKey* X509Certificate_NssImpl::getPrivateKey()
+{
+    if (m_pPrivateKey)
+    {
+        return m_pPrivateKey;
+    }
+    else
+    {
+        if (m_pCert && m_pCert->slot)
+        {
+            SECKEYPrivateKey* pPrivateKey = PK11_FindPrivateKeyFromCert(m_pCert->slot, m_pCert, nullptr);
+            if (pPrivateKey)
+                return pPrivateKey;
+        }
+    }
+    return nullptr;
+}
+
 /* XUnoTunnel */
 sal_Int64 SAL_CALL X509Certificate_NssImpl::getSomething( const Sequence< sal_Int8 >& aIdentifier ) {
     if( aIdentifier.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(), aIdentifier.getConstArray(), 16 ) ) {
diff --git a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
index 5c5794342c62..d537ff7942bb 100644
--- a/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
+++ b/xmlsecurity/source/xmlsec/nss/x509certificate_nssimpl.hxx
@@ -40,7 +40,8 @@ class X509Certificate_NssImpl : public ::cppu::WeakImplHelper<
     css::lang::XServiceInfo > , public xmlsecurity::Certificate
 {
     private:
-        CERTCertificate* m_pCert ;
+        CERTCertificate* m_pCert;
+        SECKEYPrivateKey* m_pPrivateKey;
 
     public:
         X509Certificate_NssImpl() ;
@@ -90,8 +91,11 @@ class X509Certificate_NssImpl : public ::cppu::WeakImplHelper<
         //Helper methods
         void setCert( CERTCertificate* cert ) ;
         const CERTCertificate* getNssCert() const ;
+
         /// @throws css::uno::RuntimeException
         void setRawCert( const css::uno::Sequence< sal_Int8 >& rawCert ) ;
+        void setCustomPrivateKey(SECKEYPrivateKey* pPrivateKey);
+        SECKEYPrivateKey* getPrivateKey();
 
         // XServiceInfo
         virtual OUString SAL_CALL getImplementationName() override;
commit 3e57de91fe6af9084809af951f31470e3e987e90
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Oct 18 10:35:25 2018 +0200
Commit:     Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Nov 8 15:07:09 2018 +0100

    lok: create certificate and private key with insertCertificate
    
    Change-Id: Ie114068d9aec5259f9f7ed395c5dfeecf8bb787d
    Reviewed-on: https://gerrit.libreoffice.org/61915
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit c2ceb1f54e85ebc8b38df3f2e4d1113a2fe1cc64)

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 752a14af81ef..f8cab66a0aee 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2261,24 +2261,37 @@ void DesktopLOKTest::testInsertCertificate()
 {
     comphelper::LibreOfficeKit::setActive();
 
+    // Load the document, save it into a temp file and load that file again
     LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
+    utl::TempFile aTempFile;
+    aTempFile.EnableKillingFile();
+    CPPUNIT_ASSERT(pDocument->pClass->saveAs(pDocument, aTempFile.GetURL().toUtf8().getStr(), "odt", nullptr));
+    closeDoc();
+
+    mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument");
+    pDocument = new LibLODocument_Impl(mxComponent);
 
     Scheduler::ProcessEventsToIdle();
     CPPUNIT_ASSERT(mxComponent.is());
     pDocument->m_pDocumentClass->initializeForRendering(pDocument, "{}");
 
-    OUString aFileURL;
-    createFileURL("certificate.der", aFileURL);
-
-    SvFileStream aStream(aFileURL, StreamMode::READ);
-    sal_uInt64 nSize = aStream.remainingSize();
-
+    OUString aCertificateURL;
+    createFileURL("certificate.der", aCertificateURL);
+    SvFileStream aCertificateStream(aCertificateURL, StreamMode::READ);
     std::vector<unsigned char> aCertificate;
-    aCertificate.resize(nSize);
-    aStream.ReadBytes(aCertificate.data(), nSize);
-
-    bool bResult = pDocument->m_pDocumentClass->insertCertificate(pDocument, aCertificate.data(), int(aCertificate.size()));
-    CPPUNIT_ASSERT(bResult);
+    aCertificate.resize(aCertificateStream.remainingSize());
+    aCertificateStream.ReadBytes(aCertificate.data(), aCertificateStream.remainingSize());
+
+    OUString aPrivateKeyURL;
+    createFileURL("pkey.der", aPrivateKeyURL);
+    SvFileStream aPrivateKeyStream(aPrivateKeyURL, StreamMode::READ);
+    std::vector<unsigned char> aPrivateKey;
+    aPrivateKey.resize(aPrivateKeyStream.remainingSize());
+    aPrivateKeyStream.ReadBytes(aPrivateKey.data(), aPrivateKeyStream.remainingSize());
+
+    pDocument->m_pDocumentClass->insertCertificate(pDocument,
+                        aCertificate.data(), int(aCertificate.size()),
+                        aPrivateKey.data(), int(aPrivateKey.size()));
 
     comphelper::LibreOfficeKit::setActive(false);
 }
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index cb248891e498..79ca5055db1f 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -75,6 +75,7 @@
 #include <com/sun/star/xml/crypto/SEInitializer.hpp>
 #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
 #include <com/sun/star/security/DocumentDigitalSignatures.hpp>
 #include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
 #include <com/sun/star/security/XCertificate.hpp>
@@ -696,7 +697,9 @@ static char* doc_getPartInfo(LibreOfficeKitDocument* pThis, int nPart);
 
 static bool doc_insertCertificate(LibreOfficeKitDocument* pThis,
                                   const unsigned char* pCertificateBinary,
-                                  const int pCertificateBinarySize);
+                                  const int nCertificateBinarySize,
+                                  const unsigned char* pPrivateKeyBinary,
+                                  const int nPrivateKeyBinarySize);
 
 static int doc_getSignatureState(LibreOfficeKitDocument* pThis);
 
@@ -3684,7 +3687,9 @@ static void doc_postWindow(LibreOfficeKitDocument* /*pThis*/, unsigned nLOKWindo
 }
 
 // CERTIFICATE AND DOCUMENT SIGNING
-static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/, const unsigned char* pCertificateBinary, const int nCertificateBinarySize)
+static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/,
+                                  const unsigned char* pCertificateBinary, const int nCertificateBinarySize,
+                                  const unsigned char* pPrivateKeyBinary, const int nPrivateKeySize)
 {
     if (!xContext.is())
         return false;
@@ -3697,11 +3702,19 @@ static bool doc_insertCertificate(LibreOfficeKitDocument* /*pThis*/, const unsig
 
     uno::Reference<xml::crypto::XSecurityEnvironment> xSecurityEnvironment;
     xSecurityEnvironment = xSecurityContext->getSecurityEnvironment();
+    uno::Reference<xml::crypto::XCertificateCreator> xCertificateCreator(xSecurityEnvironment, uno::UNO_QUERY);
+
+    if (!xCertificateCreator.is())
+        return false;
 
     uno::Sequence<sal_Int8> aCertificateSequence(nCertificateBinarySize);
     std::copy(pCertificateBinary, pCertificateBinary + nCertificateBinarySize, aCertificateSequence.begin());
 
-    uno::Reference<security::XCertificate> xCertificate = xSecurityEnvironment->createCertificateFromRaw(aCertificateSequence);
+    uno::Sequence<sal_Int8> aPrivateKeySequence(nPrivateKeySize);
+    std::copy(pPrivateKeyBinary, pPrivateKeyBinary + nPrivateKeySize, aPrivateKeySequence.begin());
+
+    uno::Reference<security::XCertificate> xCertificate;
+    xCertificate = xCertificateCreator->createDERCertificateWithPrivateKey(aCertificateSequence, aPrivateKeySequence);
 
     if (!xCertificate.is())
         return false;
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index fbbf1822e956..8a4c6d4ad659 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -323,7 +323,9 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::insertCertificate().
     bool (*insertCertificate) (LibreOfficeKitDocument* pThis,
                                 const unsigned char* pCertificateBinary,
-                                const int pCertificateBinarySize);
+                                const int nCertificateBinarySize,
+                                const unsigned char* pPrivateKeyBinary,
+                                const int nPrivateKeyBinarySize);
 
     /// @see lok::Document::getSignatureState().
     int (*getSignatureState) (LibreOfficeKitDocument* pThis);
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 077490674f70..f72badaae851 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -561,9 +561,13 @@ public:
      *  Insert certificate (in binary form) to the certificate store.
      */
     bool insertCertificate(const unsigned char* pCertificateBinary,
-                           const int pCertificateBinarySize)
+                           const int pCertificateBinarySize,
+                           const unsigned char* pPrivateKeyBinary,
+                           const int nPrivateKeyBinarySize)
     {
-        return mpDoc->pClass->insertCertificate(mpDoc, pCertificateBinary, pCertificateBinarySize);
+        return mpDoc->pClass->insertCertificate(mpDoc, 
+                                                pCertificateBinary, pCertificateBinarySize, 
+                                                pPrivateKeyBinary, nPrivateKeyBinarySize);
     }
 
     /**
commit 38cb72b307e5fdc4c4bd70a4841dac306892ff0c
Author:     Tomaž Vajngerl <tomaz.vajngerl at collabora.co.uk>
AuthorDate: Thu Oct 18 10:34:14 2018 +0200
Commit:     Miklos Vajna <vmiklos at collabora.co.uk>
CommitDate: Thu Nov 8 15:06:34 2018 +0100

    xmlsecurity: implement XCertificateCreator for NSS backend
    
    Reviewed-on: https://gerrit.libreoffice.org/61914
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <quikee at gmail.com>
    (cherry picked from commit ef2623b712d7417d8135279d654a16de2caf56fc)
    
    Conflicts:
            xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
    
    Change-Id: I28aa17e6c97494769185ed289836524064030f39

diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
index 3ba0062e86b4..035896932ed3 100644
--- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
+++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.cxx
@@ -26,7 +26,6 @@
 #include <sal/macros.h>
 #include <osl/diagnose.h>
 #include "securityenvironment_nssimpl.hxx"
-#include "x509certificate_nssimpl.hxx"
 #include <comphelper/servicehelper.hxx>
 
 #include <xmlsec-wrapper.h>
@@ -528,20 +527,23 @@ Sequence< Reference < XCertificate > > SecurityEnvironment_NssImpl::buildCertifi
     return Sequence< Reference < XCertificate > >();
 }
 
-Reference< XCertificate > SecurityEnvironment_NssImpl::createCertificateFromRaw( const Sequence< sal_Int8 >& rawCertificate ) {
-    X509Certificate_NssImpl* xcert ;
-
-    if( rawCertificate.getLength() > 0 ) {
-        xcert = new X509Certificate_NssImpl() ;
-        if( xcert == nullptr )
-            throw RuntimeException() ;
+X509Certificate_NssImpl* SecurityEnvironment_NssImpl::createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate)
+{
+    X509Certificate_NssImpl* pX509Certificate = nullptr;
 
-        xcert->setRawCert( rawCertificate ) ;
-    } else {
-        xcert = nullptr ;
+    if (aDerCertificate.getLength() > 0)
+    {
+        pX509Certificate = new X509Certificate_NssImpl();
+        if (pX509Certificate == nullptr)
+            throw RuntimeException();
+        pX509Certificate->setRawCert(aDerCertificate);
     }
+    return pX509Certificate;
+}
 
-    return xcert ;
+Reference<XCertificate> SecurityEnvironment_NssImpl::createCertificateFromRaw(const Sequence< sal_Int8 >& rawCertificate)
+{
+    return createX509CertificateFromDER(rawCertificate);
 }
 
 Reference< XCertificate > SecurityEnvironment_NssImpl::createCertificateFromAscii( const OUString& asciiCertificate )
@@ -968,4 +970,45 @@ void SecurityEnvironment_NssImpl::destroyKeysManager(xmlSecKeysMngrPtr pKeysMngr
     }
 }
 
+uno::Reference<security::XCertificate> SecurityEnvironment_NssImpl::createDERCertificateWithPrivateKey(
+        Sequence<sal_Int8> const & raDERCertificate, Sequence<sal_Int8> const & raPrivateKey)
+{
+    SECStatus nStatus = SECSuccess;
+
+    PK11SlotInfo* pSlot = PK11_GetInternalKeySlot();
+    if (!pSlot)
+        return uno::Reference<security::XCertificate>();
+
+    SECItem pDerPrivateKeyInfo;
+    pDerPrivateKeyInfo.data = reinterpret_cast<unsigned char *>(const_cast<sal_Int8 *>(raPrivateKey.getConstArray()));
+    pDerPrivateKeyInfo.len = raPrivateKey.getLength();
+
+    const unsigned int keyUsage = KU_KEY_ENCIPHERMENT | KU_DATA_ENCIPHERMENT | KU_DIGITAL_SIGNATURE;
+    SECKEYPrivateKey* pPrivateKey = nullptr;
+
+    bool bPermanent = false;
+    bool bSensitive = false;
+
+    nStatus = PK11_ImportDERPrivateKeyInfoAndReturnKey(
+          pSlot, &pDerPrivateKeyInfo, nullptr, nullptr, bPermanent, bSensitive,
+          keyUsage, &pPrivateKey, nullptr);
+
+    if (nStatus != SECSuccess)
+        return uno::Reference<security::XCertificate>();
+
+    if (!pPrivateKey)
+        return uno::Reference<security::XCertificate>();
+
+    X509Certificate_NssImpl* pX509Certificate = createX509CertificateFromDER(raDERCertificate);
+    if (!pX509Certificate)
+        return uno::Reference<security::XCertificate>();
+
+    addCryptoSlot(pSlot);
+
+    CERTCertificate* pCERTCertificate = const_cast<CERTCertificate*>(pX509Certificate->getNssCert());
+    pCERTCertificate->slot = pSlot;
+
+    return pX509Certificate;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
index 0e47cd9d4213..becde1168661 100644
--- a/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
+++ b/xmlsecurity/source/xmlsec/nss/securityenvironment_nssimpl.hxx
@@ -31,11 +31,14 @@
 
 #include <com/sun/star/lang/XServiceInfo.hpp>
 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
+#include <com/sun/star/xml/crypto/XCertificateCreator.hpp>
 #include <com/sun/star/security/XCertificate.hpp>
 #include <com/sun/star/security/CertificateCharacters.hpp>
 #include <com/sun/star/security/CertificateValidity.hpp>
 #include <com/sun/star/lang/XUnoTunnel.hpp>
 
+#include "x509certificate_nssimpl.hxx"
+
 #include <osl/mutex.hxx>
 
 #include <pk11func.h>
@@ -46,7 +49,8 @@
 #include <xmlsec-wrapper.h>
 
 class SecurityEnvironment_NssImpl : public ::cppu::WeakImplHelper<
-    css::xml::crypto::XSecurityEnvironment ,
+    css::xml::crypto::XSecurityEnvironment,
+    css::xml::crypto::XCertificateCreator,
     css::lang::XServiceInfo,
     css::lang::XUnoTunnel >
 {
@@ -137,6 +141,10 @@ private:
         virtual css::uno::Reference< css::security::XCertificate > SAL_CALL createCertificateFromRaw( const css::uno::Sequence< sal_Int8 >& rawCertificate ) override ;
         virtual css::uno::Reference< css::security::XCertificate > SAL_CALL createCertificateFromAscii( const OUString& asciiCertificate ) override ;
 
+        // Methods of XCertificateCreator
+        css::uno::Reference<css::security::XCertificate> SAL_CALL createDERCertificateWithPrivateKey(
+                css::uno::Sequence<sal_Int8> const & raDERCertificate,
+                css::uno::Sequence<sal_Int8> const & raPrivateKey) override;
 
         //Native methods
         /// @throws css::uno::RuntimeException
@@ -148,6 +156,8 @@ private:
 private:
         void updateSlots();
 
+        X509Certificate_NssImpl* createX509CertificateFromDER(const css::uno::Sequence<sal_Int8>& aDerCertificate);
+
           /// @throws css::uno::Exception
           /// @throws css::uno::RuntimeException
           void addCryptoSlot( PK11SlotInfo* aSlot ) ;


More information about the Libreoffice-commits mailing list