From cf7b6169c68bd3a9cf01c2304cfb125abf200616 Mon Sep 17 00:00:00 2001 From: Christopher Dykes Date: Fri, 5 Aug 2016 09:49:03 -0700 Subject: [PATCH] Handle creating the default crypto context if it doesn't already exist Summary: It's perfectly possible that the default crypto context simply hasn't been created yet, so try to create it if the initial acquisition fails. Reviewed By: yfeldblum Differential Revision: D3673138 fbshipit-source-id: 122955df04055ff4f99513b182375d4388dd0305 --- folly/Random.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/folly/Random.cpp b/folly/Random.cpp index c6b611be..8f5e3128 100644 --- a/folly/Random.cpp +++ b/folly/Random.cpp @@ -42,8 +42,16 @@ void readRandomDevice(void* data, size_t size) { static folly::once_flag flag; static HCRYPTPROV cryptoProv; folly::call_once(flag, [&] { - PCHECK(CryptAcquireContext(&cryptoProv, nullptr, nullptr, - PROV_RSA_FULL, 0)); + if (!CryptAcquireContext(&cryptoProv, nullptr, nullptr, PROV_RSA_FULL, 0)) { + if (GetLastError() == NTE_BAD_KEYSET) { + // Mostly likely cause of this is that no key container + // exists yet, so try to create one. + PCHECK(CryptAcquireContext( + &cryptoProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_NEWKEYSET)); + } else { + LOG(FATAL) << "Failed to acquire the default crypto context."; + } + } }); CHECK(size <= std::numeric_limits::max()); PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data)); -- 2.34.1