-- Copyright 2013 Thomas Szczarkowski

{-# LANGUAGE ScopedTypeVariables #-}

module OpenSSL.Random(cryptoRandomBytes) where

import qualified Data.ByteString as ByteString
import Foreign
import Foreign.C.Types
import Foreign.C.String
import Foreign.Marshal.Alloc
import Control.Monad
import Control.Exception

import OpenSSL.Error


check cond err = if cond then return () else throw $ userError err


cryptoRandomBytes n =
  allocaBytes n $ \(buf :: Ptr CChar) -> 
  do ret <- c_RAND_bytes buf (fromIntegral n)
     assertSSL ret "Error using OpenSSL RNG:"
     peekByteArray n buf
  where peekByteArray count = liftM (ByteString.pack . map fromIntegral) . (peekArray count)
                              

foreign import ccall unsafe "RAND_bytes" c_RAND_bytes :: 
   Ptr CChar -> CInt -> IO CInt

