hsgnutls-0.2.3.2: Network/GnuTLS/Internals.chs
module Network.GnuTLS.Internals where
#include <gnutls/gnutls.h>
{#context prefix = "gnutls" #}
import Foreign
import Foreign.C
import System.Time(ClockTime(TOD))
import Network.GnuTLS.RefCount
import Data.ByteString.Internal
import Data.ByteString.Unsafe
data Session a = Session (ForeignPtr ())! RefCount
--------------------------------------------------------------------------------
------------------------------ Enums ---------------------------------------
--------------------------------------------------------------------------------
{#enum gnutls_cipher_algorithm_t as CipherAlgorithm {underscoreToCase} #}
{#enum gnutls_kx_algorithm_t as KxAlgorithm {underscoreToCase} deriving(Eq) #}
{#enum gnutls_params_type_t as ParamsType {underscoreToCase} #}
{#enum gnutls_credentials_type_t as CredentialsType {underscoreToCase} deriving(Eq) #}
{#enum gnutls_mac_algorithm_t as MacAlgorithm {underscoreToCase} #}
{#enum gnutls_digest_algorithm_t as DigestAlgorithm {underscoreToCase} deriving(Show) #}
{#enum gnutls_compression_method_t as CompressionMethod {underscoreToCase} #}
{#enum gnutls_connection_end_t as ConnectionEnd {underscoreToCase} #}
{#enum gnutls_alert_level_t as AlertLevel {underscoreToCase} #}
{#enum gnutls_alert_description_t as AlertDescription {underscoreToCase} #}
{#enum gnutls_handshake_description_t as HandshakeDescription {underscoreToCase} #}
{#enum gnutls_certificate_status_t as CertificateStatus {underscoreToCase} deriving(Show,Eq) #}
{#enum gnutls_certificate_request_t as CertificateRequest {underscoreToCase} #}
--{#enum gnutls_openpgp_key_status_t as KeyStatus {underscoreToCase} #}
{#enum gnutls_close_request_t as CloseRequest {underscoreToCase} #}
{#enum gnutls_protocol_t as Protocol {underscoreToCase} #}
{#enum gnutls_certificate_type_t as CertificateType {underscoreToCase} #}
{#enum gnutls_x509_crt_fmt_t as X509CertificateFormat {underscoreToCase} #}
{#enum gnutls_pk_algorithm_t as PkAlgorithm {underscoreToCase} #}
{#enum gnutls_sign_algorithm_t as SignAlgorithm {underscoreToCase} #}
#c
#ifdef COMPAT_GNUTLS_1_0
typedef gnutls_cipher_algorithm gnutls_cipher_algorithm_t;
typedef gnutls_kx_algorithm gnutls_kx_algorithm_t;
typedef gnutls_mac_algorithm gnutls_mac_algorithm_t;
typedef gnutls_digest_algorithm gnutls_digest_algorithm_t;
typedef gnutls_datum gnutls_datum_t;
typedef gnutls_params_type gnutls_params_type_t;
typedef gnutls_credentials_type gnutls_credentials_type_t;
typedef gnutls_compression_method gnutls_compression_method_t;
typedef gnutls_connection_end gnutls_connection_end_t;
typedef gnutls_alert_level gnutls_alert_level_t;
typedef gnutls_alert_description gnutls_alert_description_t;
typedef gnutls_handshake_description gnutls_handshake_description_t;
typedef gnutls_certificate_status gnutls_certificate_status_t;
typedef gnutls_certificate_request gnutls_certificate_request_t;
typedef gnutls_openpgp_key_status gnutls_openpgp_key_status_t;
typedef gnutls_close_request gnutls_close_request_t;
typedef gnutls_protocol_version gnutls_protocol_t;
typedef gnutls_certificate_type gnutls_certificate_type_t;
typedef gnutls_x509_crt_fmt gnutls_x509_crt_fmt_t;
typedef gnutls_pk_algorithm gnutls_pk_algorithm_t;
typedef gnutls_sign_algorithm gnutls_sign_algorithm_t;
#endif
#endc
--------------------------------------------------------------------------------
---------------------------- Time Management -------------------------------
--------------------------------------------------------------------------------
integralToClockTime :: Integral n => n -> ClockTime
integralToClockTime ct = TOD (fromIntegral ct) 0
--------------------------------------------------------------------------------
----------------------------- Helpers --------------------------------------
--------------------------------------------------------------------------------
enumCInt :: Enum e => e -> CInt
enumCInt x = fromIntegral $ fromEnum x
cintEnum :: Enum e => CInt -> e
cintEnum x = toEnum $ fromIntegral x
safePeekCString :: CString -> IO String
safePeekCString pointer = if pointer == nullPtr then return "" else peekCString pointer
withEnumList0 :: Enum e => [e] -> (Ptr CInt -> IO ()) -> IO ()
withEnumList0 es f = withArray0 0 is f
where is = map enumCInt es
withSession :: Session t -> (Ptr () -> IO a) -> IO a
withSession (Session s _) = withForeignPtr s
{-# SPECIALIZE throwGnutlsIf :: CInt -> IO () #-}
{-# SPECIALIZE throwGnutlsIf :: CLong -> IO () #-}
throwGnutlsIf :: Integral n => n -> IO ()
throwGnutlsIf 0 = return ()
throwGnutlsIf v = {#call gnutls_strerror #} (fromIntegral v) >>= safePeekCString >>= (\str -> fail (str++" ("++show v++")"))
{-# SPECIALIZE throwGnutlsIfNeg :: CInt -> IO Int #-}
{-# SPECIALIZE throwGnutlsIfNeg :: CLong -> IO Int #-}
throwGnutlsIfNeg :: (Num b, Integral a) => a -> IO b
throwGnutlsIfNeg v = if v < 0 then throwGnutlsIf v >> return 0 else return (fromIntegral v)
{-# INLINE peekEnum #-}
peekEnum :: (Storable s, Integral s, Num e, Enum e) => Ptr s -> IO e
peekEnum pointer = peek pointer >>= return . fromIntegral
isZero, isNonZero :: (Num a) => a -> Bool
isZero x = x == 0
isNonZero x = x /= 0
ptrDeS :: Ptr (Ptr ()) -> IO a
ptrDeS p = deRefStablePtr $ castPtrToStablePtr $ castPtr p
--------------------------------------------------------------------------------
------------------------------ Datums --------------------------------------
--------------------------------------------------------------------------------
peekDatum :: Ptr a -> IO (Ptr CChar,Int)
peekDatum pntr = do pv <- {#get gnutls_datum_t->data #} (castPtr pntr)
iv <- {#get gnutls_datum_t->size #} (castPtr pntr)
return (castPtr pv, fromIntegral iv)
peekDatumArray :: Int -> Ptr a -> IO [(Ptr CChar,Int)]
peekDatumArray i pntr = loop i (plusPtr pntr (i*{#sizeof gnutls_datum_t #})) []
where loop 0 pointer acc = do d <- peekDatum pointer
return (d:acc)
loop k pointer acc = do d <- peekDatum pointer
loop (k-1) (plusPtr pointer (0-{#sizeof gnutls_datum_t #})) (d:acc)
class Datum a where
withDatum :: a -> (Ptr () -> IO b) -> IO b
instance Datum String where
withDatum s p = withCStringLen s (\v -> withDatum v p)
instance Datum (Ptr CChar,Int) where
withDatum (p,l) c = allocaBytes {#sizeof gnutls_datum_t #} $ \dptr -> do
{#set gnutls_datum_t->data #} dptr (castPtr p)
{#set gnutls_datum_t->size #} dptr (fromIntegral l)
c dptr
instance Datum ByteString where
withDatum bs f = unsafeUseAsCStringLen bs (\v -> withDatum v f)
--{#fun gnutls_pem_base64_decode_alloc as datumBase64Decode
-- {with
datumBase64Decode :: (Datum d) => Int -> d -> IO ByteString
datumBase64Decode sz dat = withDatum dat $
\p1 -> createAndTrim sz $
\pointer -> with (fromIntegral sz::CSize) $
\sptr -> do
{#call gnutls_pem_base64_decode#} nullPtr p1 (castPtr pointer) (castPtr sptr) >>= throwGnutlsIf
peek sptr >>= return . fromIntegral