https://bugs.freedesktop.org/show_bug.cgi?id=87030

--- Comment #5 from Tor Lillqvist <t...@iki.fi> ---
For reference, here is a diff with various hacks that I have tried to get it to
work, but no luck. It is interesting that if I don't use the certificate
created directly by CertCreateCertificateContext() from the DER data, but look
it up from the "MY" store using CertFindCertificateInStore(), then
CertEnumCertificateContextProperties() finds various properties in the
certificate.

Also, it is interesting that the certificate provided to me (the "Collabora Dev
Softtoken" one) is an AT_KEYEXCHANGE one!? That is what certutil -dump -v and
CryptAcquireCertificatePrivateKey() tell me. I would have expected it to be an
AT_SIGNATURE one. But probably I misunderstand something.

diff --git a/vcl/source/gdi/pdfwriter_impl.cxx
b/vcl/source/gdi/pdfwriter_impl.cxx
index b459a8d..ab9e2cf
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -6215,13 +6215,31 @@ bool PDFWriterImpl::finalizeSignature()

 #else

-    PCCERT_CONTEXT pCertContext =
CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
reinterpret_cast<const BYTE*>(n_derArray), n_derLength);
-    if (pCertContext == NULL)
+    PCCERT_CONTEXT pCertContextFromDER =
CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
reinterpret_cast<const BYTE*>(n_derArray), n_derLength);
+    if (pCertContextFromDER == NULL)
     {
         SAL_WARN("vcl.pdfwriter", "CertCreateCertificateContext failed: " <<
WindowsError(GetLastError()));
         return false;
     }

+#if 1
+    HCERTSTORE hCertStore = CertOpenSystemStore(NULL, "MY");
+    if (!hCertStore)
+    {
+        SAL_WARN("vcl.pdfwriter", "CertOpenSystemStore failed: " <<
WindowsError(GetLastError()));
+        return false;
+    }
+
+    PCCERT_CONTEXT pCertContext = CertFindCertificateInStore(hCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, (const void*)
pCertContextFromDER, NULL);
+    if (pCertContext == NULL)
+    {
+        SAL_WARN("vcl.pdfwriter", "CertFindCertificateInStore failed: " <<
WindowsError(GetLastError()));
+        return false;
+    }
+#else
+    PCCERT_CONTEXT pCertContext = pCertContextFromDER;
+#endif
+
 #if SAL_LOG_INFO
     DWORD nProperty(0);
     bool first(true);
@@ -6234,8 +6252,7 @@ bool PDFWriterImpl::finalizeSignature()
         DWORD nSize(0);
         if (!CertGetCertificateContextProperty(pCertContext, nProperty, NULL,
&nSize))
             SAL_INFO("vcl.pdfwriter", "  " << "(missing?) " << std::hex <<
nProperty);
-        else
-        {
+        else        {
             boost::scoped_array<char> aData(new char[nSize]);
             if (!CertGetCertificateContextProperty(pCertContext, nProperty,
aData.get(), &nSize))
                 SAL_INFO("vcl.pdfwriter", "  " << "(missing?) " << std::hex::
<< nProperty);
@@ -6243,7 +6260,7 @@ bool PDFWriterImpl::finalizeSignature()
                 SAL_INFO("vcl.pdfwriter", "  " <<
CertificatePropertyNameAndData(nProperty, aData, nSize));
         }
 #else
-        SAL_INFO("vcl.pdfwriter", "  " << std::hex << nProperty);
+        SAL_INFO("vcl.pdfwriter", "  " << nProperty);
 #endif
     }
 #endif
@@ -6252,7 +6269,7 @@ bool PDFWriterImpl::finalizeSignature()
     CHECK_RETURN( (osl::File::E_None == m_aFile.setPos(osl_Pos_Absolut, 0)) );

     HCRYPTPROV hCryptProvider;
-    if (!CryptAcquireContext(&hCryptProvider, NULL, MS_ENHANCED_PROV,
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
+    if (!CryptAcquireContext(&hCryptProvider, NULL, MS_ENH_RSA_AES_PROV,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
     {
         SAL_WARN("vcl.pdfwriter", "CryptAcquireContext failed: " <<
WindowsError(GetLastError()));
         CertFreeCertificateContext(pCertContext);
@@ -6268,6 +6285,7 @@ bool PDFWriterImpl::finalizeSignature()
         return false;
     }

+#if 0
     DWORD nHashSize;
     DWORD nHashSizeLen(sizeof(DWORD));
     if (!CryptGetHashParam(hHash, HP_HASHSIZE, reinterpret_cast<BYTE
*>(&nHashSize), &nHashSizeLen, 0))
@@ -6281,6 +6299,7 @@ bool PDFWriterImpl::finalizeSignature()

     assert(nHashSizeLen == sizeof(DWORD));
     assert(nHashSize == 20);
+#endif

     boost::scoped_array<char> buffer(new char[m_nSignatureContentOffset + 1]);
     sal_uInt64 bytesRead;
@@ -6337,8 +6356,26 @@ bool PDFWriterImpl::finalizeSignature()

     OString pass = OUStringToOString( m_aContext.SignPassword,
RTL_TEXTENCODING_UTF8 );

+    HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey;
+    DWORD nKeySpecType;
+    BOOL bMustFree;
+    if (!CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL,
&hCryptProvOrNCryptKey, &nKeySpecType, &bMustFree))
+    {
+        SAL_WARN("vcl.pdfwriter", "CryptAcquireCertificatePrivateKey failed: "
<< WindowsError(GetLastError()));
+        CryptDestroyHash(hHash);
+        CryptReleaseContext(hCryptProvider, 0);
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    SAL_INFO("vcl.pdfwriter", "Certificate has private key that is " <<
+             (nKeySpecType == AT_KEYEXCHANGE ? OUString("for key exchange") :
+              (nKeySpecType == AT_SIGNATURE ? OUString("for signatures") :
+               (nKeySpecType == CERT_NCRYPT_KEY_SPEC ? OUString("a CNG key,
whatever that is") :
+                OUString("unknown type (") + OUString::number(nKeySpecType,
16) + ")"))));
+
     DWORD nSigLen(0);
-    if (!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, NULL, &nSigLen))
+    if (!CryptSignHash(hHash, nKeySpecType, NULL, CRYPT_NOHASHOID, NULL,
&nSigLen))
     {
         SAL_WARN("vcl.pdfwriter", "CryptSignHash failed: " <<
WindowsError(GetLastError()));
         CryptDestroyHash(hHash);
@@ -6348,7 +6385,7 @@ bool PDFWriterImpl::finalizeSignature()
     }

     boost::scoped_array<BYTE> pSig(new BYTE[nSigLen]);
-    if (!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pSig.get(), &nSigLen))
+    if (!CryptSignHash(hHash, nKeySpecType, NULL, CRYPT_NOHASHOID, pSig.get(),
&nSigLen))
     {
         SAL_WARN("vcl.pdfwriter", "CryptSignHash failed: " <<
WindowsError(GetLastError()));
         CryptDestroyHash(hHash);

-- 
You are receiving this mail because:
You are the assignee for the bug.
_______________________________________________
Libreoffice-bugs mailing list
Libreoffice-bugs@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice-bugs

Reply via email to