summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2015-02-19 13:57:52 +0200
committerAndras Timar <andras.timar@collabora.com>2015-03-05 15:20:58 +0100
commit41a0c12600f0fdfdb31c3fcc448fec89b8785f3f (patch)
tree63f4dc22958b0fcb7ce5d5bc25222c343f20bbf3
parentbed9f10da45c94feda7201acc91a553b4ab08cc6 (diff)
tdf#84881: Work in progress: Perform the RFC3161 interaction with the TSA
Use libcurl to perform the request and get the response. Improve error messages (only use SAL_WARN, though, so sadly not visible to end-users). Still to do: Decode the response and attach it to the signature. Implement request encoding and response decoding for Windows. I probably should extend (and rename) the HashContextScope class to handle all resources that need explicit deallocation, instead of calling curl_slist_free_all(), curl_easy_cleanup() and SECITEM_FreeItem() in so many places. The error handling of the PDF export functionality would need to be re-designed so that we could show actual error messages to the user instead of generic "signing failed" ones. But that is typical for much of our code... Change-Id: I6288de3f09021f8e0f385870143fefffbac2a706 (cherry picked from commit 27d7aea00d22ad3fcdff2e7b267be1cf5c28d43c)
-rw-r--r--vcl/Library_vcl.mk2
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx125
2 files changed, 121 insertions, 6 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index b8a758730517..20caba3115fb 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -54,6 +54,8 @@ $(eval $(call gb_Library_use_custom_headers,vcl,\
))
$(eval $(call gb_Library_use_externals,vcl,\
+ $(if $(filter LINUX MACOSX,$(OS)), \
+ curl) \
jpeg \
$(if $(filter-out WNT,$(OS)), \
nss3 \
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index a846658cb152..a731ba3b5430 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -75,6 +75,9 @@
#include "sechash.h"
#include "cms.h"
#include "cmst.h"
+
+// We use curl for RFC3161 time stamp requests
+#include <curl/curl.h>
#endif
#ifdef _WIN32
@@ -6125,12 +6128,20 @@ const SEC_ASN1Template TimeStampReq_Template[] =
{ 0, 0, 0, 0 }
};
+size_t AppendToBuffer(char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ OStringBuffer *pBuffer = reinterpret_cast<OStringBuffer*>(userdata);
+ pBuffer->append(ptr, size*nmemb);
+
+ return size*nmemb;
+}
+
#if 0
{
#endif
} // anonymous namespace
-#endif
+#endif // !defined(ANDROID) && !defined(IOS) && !defined(_WIN32)
#ifdef _WIN32
@@ -6308,19 +6319,121 @@ bool PDFWriterImpl::finalizeSignature()
src.extensions = NULL;
- SECItem* item = SEC_ASN1EncodeItem(NULL, NULL, &src, TimeStampReq_Template);
- SAL_INFO("vcl.pdfwriter", "item=" << item << " data=" << (item ? (void*)item->data : nullptr) << " len=" << (item ? item->len : -1));
+ SECItem* timestamp_request = SEC_ASN1EncodeItem(NULL, NULL, &src, TimeStampReq_Template);
+ if (timestamp_request == NULL)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: SEC_ASN1EncodeItem failed");
+ return false;
+ }
+
+ if (timestamp_request->data == NULL)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: SEC_ASN1EncodeItem succeeded but got NULL data");
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ SAL_INFO("vcl.pdfwriter", "request len=" << (timestamp_request ? timestamp_request->len : -1));
#ifdef DBG_UTIL
- if (item && item->data)
{
FILE *out = fopen("PDFWRITER.timestampreq.data", "wb");
- fwrite(item->data, item->len, 1, out);
+ fwrite(timestamp_request->data, timestamp_request->len, 1, out);
+ fclose(out);
+ }
+#endif
+
+ // Send time stamp request to TSA server, receive response
+
+ CURL* curl = curl_easy_init();
+ struct curl_slist* slist = NULL;
+
+ if (!curl)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_init failed");
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ SAL_INFO("vcl.pdfwriter", "Setting curl to verbose: " << (curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) == CURLE_OK ? "OK" : "FAIL"));
+
+ if (curl_easy_setopt(curl, CURLOPT_URL, OUStringToOString(m_aContext.SignTSA, RTL_TEXTENCODING_UTF8).getStr()) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_URL) failed");
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ slist = curl_slist_append(slist, "Content-Type: application/timestamp-query");
+ slist = curl_slist_append(slist, "Accept: application/timestamp-reply");
+
+ if (curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_HTTPHEADER) failed");
+ curl_slist_free_all(slist);
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ if (curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, timestamp_request->len) != CURLE_OK ||
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, timestamp_request->data) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_POSTFIELDSIZE or CURLOPT_POSTFIELDS) failed");
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ OStringBuffer reply_buffer;
+
+ if (curl_easy_setopt(curl, CURLOPT_WRITEDATA, &reply_buffer) != CURLE_OK ||
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToBuffer) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_WRITEDATA or CURLOPT_WRITEFUNCTION) failed");
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ if (curl_easy_setopt(curl, CURLOPT_POST, 1) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_POST) failed");
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ char error_buffer[CURL_ERROR_SIZE];
+ if (curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_setopt(CURLOPT_ERRORBUFFER) failed");
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+ if (curl_easy_perform(curl) != CURLE_OK)
+ {
+ SAL_WARN("vcl.pdfwriter", "PDF signing: curl_easy_perform failed: " << error_buffer);
+ curl_easy_cleanup(curl);
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
+ return false;
+ }
+
+#ifdef DBG_UTIL
+ {
+ FILE *out = fopen("PDFWRITER.reply.data", "wb");
+ fwrite(reply_buffer.getStr(), reply_buffer.getLength(), 1, out);
fclose(out);
}
#endif
- SECITEM_FreeItem(item, PR_TRUE);
+ curl_slist_free_all(slist);
+ curl_easy_cleanup(curl);
+
+ SECITEM_FreeItem(timestamp_request, PR_TRUE);
}
if (NSS_CMSSignerInfo_IncludeCerts(cms_signer, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess)