From cf43882e9fb55b66776b9fc6c812487d772d37ca Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Sun, 24 May 2015 15:41:28 -0400 Subject: 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. --- libqpdf/SecureRandomDataProvider.cc | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'libqpdf/SecureRandomDataProvider.cc') 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() -- cgit v1.2.3-54-g00ecf