/mordor/streams/random.cpp
http://github.com/mozy/mordor · C++ · 51 lines · 44 code · 7 blank · 0 comment · 10 complexity · 7b62db54f2c0018e8bc0d118c654413e MD5 · raw file
- #include "random.h"
- #ifndef WINDOWS
- #include <openssl/rand.h>
- #include "ssl.h"
- #endif
- #include "mordor/endian.h"
- #include "mordor/exception.h"
- namespace Mordor {
- RandomStream::RandomStream()
- {
- #ifdef WINDOWS
- BOOL ret = ::CryptAcquireContext(&m_hCP, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
- if(!ret || !m_hCP) {
- if(lastError() == NTE_BAD_KEYSET) {
- ret = ::CryptAcquireContext(&m_hCP, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_VERIFYCONTEXT);
- if(!ret || !m_hCP) {
- MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptAcquireContext");
- }
- } else {
- MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptAcquireContext");
- }
- }
- #endif
- }
- RandomStream::~RandomStream()
- {
- #ifdef WINDOWS
- ::CryptReleaseContext(m_hCP, 0);
- #endif
- }
- size_t RandomStream::read(void *buffer, size_t length)
- {
- #ifdef WINDOWS
- if (length >= 0xffffffffu)
- length = 0xffffffffu;
- if (!::CryptGenRandom(m_hCP, static_cast<DWORD>(length), static_cast<BYTE *>(buffer)))
- MORDOR_THROW_EXCEPTION_FROM_LAST_ERROR_API("CryptGenRandom");
- #else
- if (!RAND_bytes(static_cast<unsigned char *>(buffer), length))
- MORDOR_THROW_EXCEPTION(OpenSSLException());
- #endif
- return length;
- }
- }