summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2015-05-24 21:41:28 +0200
committerJay Berkenbilt <ejb@ql.org>2015-05-24 22:52:42 +0200
commitcf43882e9fb55b66776b9fc6c812487d772d37ca (patch)
treec92e42e670f9fa08712639caf4eced920014f20d
parent857bb208d338e117f2a864407e34de76da360d8a (diff)
downloadqpdf-cf43882e9fb55b66776b9fc6c812487d772d37ca.tar.zst
Handle Microsoft crypt provider without prior keys
As reported in issue #40, a call to CryptAcquireContext in SecureRandomDataProvider fails in a fresh windows install prior to any user keys being created in AppData\Roaming\Microsoft\Crypto\RSA. Thanks michalrames.
-rw-r--r--ChangeLog4
-rw-r--r--libqpdf/SecureRandomDataProvider.cc35
2 files changed, 37 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 99c1690f..8220c9b5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2015-05-24 Jay Berkenbilt <ejb@ql.org>
+ * Handle Microsoft crypt provider initialization properly for case
+ where no keys have been previously created, such as in a fresh
+ Windows installation.
+
* Include time.h in QUtil.hh for time_t
2015-02-21 Jay Berkenbilt <ejb@ql.org>
diff --git a/libqpdf/SecureRandomDataProvider.cc b/libqpdf/SecureRandomDataProvider.cc
index 2870ab98..0b0b6c73 100644
--- a/libqpdf/SecureRandomDataProvider.cc
+++ b/libqpdf/SecureRandomDataProvider.cc
@@ -42,9 +42,40 @@ class WindowsCryptProvider
public:
WindowsCryptProvider()
{
- if (! CryptAcquireContext(&crypt_prov, NULL, NULL, PROV_RSA_FULL, 0))
+ if (!CryptAcquireContext(&crypt_prov,
+ "Container",
+ NULL,
+ PROV_RSA_FULL,
+ 0))
{
- throw std::runtime_error("unable to acquire crypt context");
+#ifdef __GNUC__
+# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wold-style-cast"
+# pragma GCC diagnostic ignored "-Wsign-compare"
+# endif
+#endif
+ if (GetLastError() == NTE_BAD_KEYSET)
+#ifdef __GNUC__
+# if ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406
+# pragma GCC diagnostic pop
+# endif
+#endif
+ {
+ if (! CryptAcquireContext(&crypt_prov,
+ "Container",
+ NULL,
+ PROV_RSA_FULL,
+ CRYPT_NEWKEYSET))
+ {
+ throw std::runtime_error(
+ "unable to acquire crypt context with new keyset");
+ }
+ }
+ else
+ {
+ throw std::runtime_error("unable to acquire crypt context");
+ }
}
}
~WindowsCryptProvider()