hsgnutls-0.2.3.2: Network/GnuTLS/GnuTLS.chs
module Network.GnuTLS.GnuTLS
(-- * Enumerations
CipherAlgorithm(..), KxAlgorithm(..), ParamsType(..), CredentialsType(..),
MacAlgorithm(..), DigestAlgorithm(..), CompressionMethod(..), ConnectionEnd(..),
AlertLevel(..), AlertDescription(..), HandshakeDescription(..), CertificateStatus(..),
CertificateRequest(..), CloseRequest(..), Protocol(..),
CertificateType(..), X509CertificateFormat(..), PkAlgorithm(..), SignAlgorithm(..),
-- * Types
Session, DH, RSA, AnonymousServerCredentials, AnonymousClientCredentials,
Server, Client, Transport, CertificateCredentials,Datum(..),
-- * Priority
SetPriority(..), setDefaultPriority, setDefaultExportPriority,
-- * Credentials
SetCredentials(..), Clear(..),
-- * Creating connections
tlsClient, tlsServer,
-- * Session Accessors
priorities, credentials, dhPrimeBits, transport, handle, clientCert,
#ifdef NETWORK_ALT
sock,
#endif
-- * Managing connection
handshake, rehandshake, bye,
setMaxHandshakePacketLength,
-- * Querying connection attributes
serverWantedAuth, verifyPeer, isResumed,
getAlert, getCipher, getKx, getMac, getCompression, getCertificateType, getProtocol,
getCredentialsType,
#ifndef COMPAT_GNUTLS_1_0
getServerCredentialsType, getClientCredentialsType,
#endif
getPeersCertificatesRaw,
-- * Sending and receiving data
tlsSend, tlsSendString, tlsRecv, tlsRecvString, tlsCheckPending,
-- * Certificate functions
certificateCredentials, freeKeys, freeCas, freeCaNames, freeCrls,
certificateTrustFile, certificateCrlFile, certificateKeyFile,
-- * Miscellaneous
anonymousServerCredentials, anonymousClientCredentials,
SetDHParams(..), CredParameter(..),
newDH, newRSA,cipherKeySize,cipherSuiteName,
version, gnutlsGlobalInit
) where
import Control.Concurrent
import Data.Bits((.&.), (.|.))
import Data.IORef(newIORef, readIORef)
import Foreign
import Foreign.C
import qualified Foreign.Concurrent as FC
import Foreign.Ptr
import System.IO
import System.IO.Unsafe
import Network.GnuTLS.Attributes
import Network.GnuTLS.Internals
import Network.GnuTLS.RefCount
#ifdef NETWORK_ALT
import Network.Alt
#endif
#include <gnutls/gnutls.h>
{#context prefix = "gnutls" #}
--------------------------------------------------------------------------------
------------------------------ Types ---------------------------------------
--------------------------------------------------------------------------------
data DH = DH (ForeignPtr ())! RefCount
data RSA = RSA (ForeignPtr ())! RefCount
data AnonymousServerCredentials = ASC (ForeignPtr ())! RefCount
data AnonymousClientCredentials = ACC (ForeignPtr ())! RefCount
data CertificateCredentials = CC (ForeignPtr ())! RefCount
data Server
data Client
type Transport = Ptr () -> Int -> Ptr CInt -> IO Int
withDH (DH fp _) = withForeignPtr fp
withRSA (RSA fp _) = withForeignPtr fp
withAnonymousServerCredentials (ASC fp _) = withForeignPtr fp
withAnonymousClientCredentials (ACC fp _) = withForeignPtr fp
withCertificateCredentials (CC fp _) = withForeignPtr fp
--------------------------------------------------------------------------------
------------------------- Show Functions -----------------------------------
--------------------------------------------------------------------------------
instance Show AlertDescription where
show a = unsafePerformIO $ gnutlsAlertGetName a
{#fun unsafe gnutls_alert_get_name as ^ {enumCInt `AlertDescription'} -> `String' safePeekCString* #}
instance Show CipherAlgorithm where
show a = unsafePerformIO $ gnutlsCipherGetName a
{#fun unsafe gnutls_cipher_get_name as ^ {enumCInt `CipherAlgorithm'} -> `String' safePeekCString* #}
instance Show MacAlgorithm where
show a = unsafePerformIO $ gnutlsMacGetName a
{#fun unsafe gnutls_mac_get_name as ^ {enumCInt `MacAlgorithm'} -> `String' safePeekCString* #}
instance Show CompressionMethod where
show a = unsafePerformIO $ gnutlsCompressionGetName a
{#fun unsafe gnutls_compression_get_name as ^ {enumCInt `CompressionMethod'} -> `String' safePeekCString* #}
instance Show KxAlgorithm where
show a = unsafePerformIO $ gnutlsKxGetName a
{#fun unsafe gnutls_kx_get_name as ^ {enumCInt `KxAlgorithm'} -> `String' safePeekCString* #}
instance Show CertificateType where
show a = unsafePerformIO $ gnutlsCertificateTypeGetName a
{#fun unsafe gnutls_certificate_type_get_name as ^ {enumCInt `CertificateType'} -> `String' safePeekCString* #}
instance Show Protocol where
show a = unsafePerformIO $ gnutlsProtocolGetName a
{#fun unsafe gnutls_protocol_get_name as ^ {enumCInt `Protocol'} -> `String' safePeekCString* #}
instance Show PkAlgorithm where
show a = unsafePerformIO $ gnutlsPkAlgorithmGetName a
{#fun unsafe gnutls_pk_algorithm_get_name as ^ {enumCInt `PkAlgorithm'} -> `String' safePeekCString* #}
instance Show SignAlgorithm where
show a = unsafePerformIO $ gnutlsSignAlgorithmGetName a
{#fun unsafe gnutls_sign_algorithm_get_name as ^ {enumCInt `SignAlgorithm'} -> `String' safePeekCString* #}
--------------------------------------------------------------------------------
-------------------------- Set Priority ------------------------------------
--------------------------------------------------------------------------------
setpwrap :: Enum e => (Ptr () -> Ptr CInt -> IO CInt) -> Session t -> [e] -> IO ()
setpwrap comp s x = do
withEnumList0 x $ \e -> do
withSession s $ \p -> do
comp p e >>= throwGnutlsIf
-- | Set the priority of the specified category.
-- On servers this means the set of acceptable values,
-- on clients it sets the priorities.
class SetPriority a where setPriority :: Session t -> [a] -> IO ()
instance SetPriority CipherAlgorithm where
setPriority = setpwrap {#call unsafe gnutls_cipher_set_priority #}
instance SetPriority MacAlgorithm where
setPriority = setpwrap {#call unsafe gnutls_mac_set_priority #}
instance SetPriority CompressionMethod where
setPriority = setpwrap {#call unsafe gnutls_compression_set_priority #}
instance SetPriority KxAlgorithm where
setPriority = setpwrap {#call unsafe gnutls_kx_set_priority #}
instance SetPriority Protocol where
setPriority = setpwrap {#call unsafe gnutls_protocol_set_priority #}
instance SetPriority CertificateType where
setPriority = setpwrap {#call unsafe gnutls_certificate_type_set_priority #}
-- | Set default priorities. This is called whenever a new 'Session' is created to
-- ensure sensible defaults.
{#fun gnutls_set_default_priority as setDefaultPriority {withSession* `Session t'} -> `()' #}
-- | Set default priorities conforming with various export regulations.
-- /Includes weak algorithms./
{#fun gnutls_set_default_export_priority as setDefaultExportPriority {withSession* `Session t'} -> `()' #}
--------------------------------------------------------------------------------
------------------------ Setting Credentials -------------------------------
--------------------------------------------------------------------------------
-- | Set the credentials associated with a session.
class SetCredentials st a where setCredentials :: Session st -> a -> IO ()
instance SetCredentials st a => SetCredentials st (IO a) where
setCredentials s c = setCredentials s =<< c
instance SetCredentials Server AnonymousServerCredentials where
setCredentials s (ASC a rc) = setcred_ s CrdAnon (castForeignPtr a)
instance SetCredentials Client AnonymousClientCredentials where
setCredentials s (ACC a rc) = setcred_ s CrdAnon (castForeignPtr a)
instance SetCredentials t CertificateCredentials where
setCredentials s (CC a rc) = setcred_ s CrdCertificate (castForeignPtr a)
setcred_ :: Session t -> CredentialsType -> ForeignPtr a -> IO ()
setcred_ (Session sfp refc) ct fp = do
withForeignPtr sfp $ \sptr -> do
withForeignPtr fp $ \dptr -> do
{#call gnutls_credentials_set #} sptr (enumCInt ct) (castPtr dptr) >>= throwGnutlsIf
addRefFinalizer refc (touchForeignPtr fp)
-- | Used to clear all credentials associated with a session.
data Clear = Clear
instance SetCredentials t Clear where
setCredentials s _ = withSession s (\s -> {#call gnutls_credentials_clear #} s >> return ())
--------------------------------------------------------------------------------
--------------------------- Session Creation -------------------------------
--------------------------------------------------------------------------------
tlsClient :: [AttrOp (Session Client)] -> IO (Session Client)
tlsClient p = do s <- newSession Client
set s p
return s
tlsServer :: [AttrOp (Session Server)] -> IO (Session Server)
tlsServer p = do s <- newSession Server
set s p
return s
newSession :: ConnectionEnd -> IO (Session t)
newSession ce = gnutlsGlobalInit >> alloca (\err -> do
let efun b l e = putStrLn "TLS pull/push functions not set" >> return 0
ef1 <- newStablePtr efun
ef2 <- newStablePtr efun
sp <- init_session_wrap (enumCInt ce) ef1 ef2 err
peek err >>= throwGnutlsIf
rc <- newRefCount (replace_transport_stable_ptrs sp stableNull stableNull >> gnutls_deinit sp)
ps <- FC.newForeignPtr sp (freeRef rc)
return $ Session ps rc)
stableNull = castPtrToStablePtr nullPtr
foreign import ccall unsafe "TLS.h gnutls_init" gnutls_init :: Ptr (Ptr ()) -> CInt -> IO CInt
foreign import ccall unsafe "TLS.h gnutls_deinit" gnutls_deinit :: Ptr () -> IO ()
foreign import ccall unsafe "TLS.h init_session_wrap"
init_session_wrap :: CInt -> StablePtr Transport -> StablePtr Transport -> Ptr CInt -> IO (Ptr ())
#c
#ifdef COMPAT_GNUTLS_1_0
typedef gnutls_transport_ptr gnutls_transport_ptr_t;
typedef gnutls_connection_end gnutls_connection_end_t;
typedef gnutls_session gnutls_session_t;
typedef gnutls_dh_params gnutls_dh_params_t;
typedef gnutls_rsa_params gnutls_rsa_params_t;
typedef gnutls_anon_server_credentials gnutls_anon_server_credentials_t;
typedef gnutls_anon_client_credentials gnutls_anon_client_credentials_t;
typedef gnutls_certificate_credentials gnutls_certificate_credentials_t;
#endif
gnutls_session_t init_session_wrap(gnutls_connection_end_t con_end, void *sptr1, void *sptr2, int *err);
#endc
--------------------------------------------------------------------------------
------------------------- Session Accessors --------------------------------
--------------------------------------------------------------------------------
priorities :: SetPriority a => WriteAttr (Session t) [a]
priorities = writeAttr setPriority
credentials :: SetCredentials t a => WriteAttr (Session t) a
credentials = writeAttr setCredentials
dhPrimeBits :: ReadWriteAttr (Session t) Int Int
dhPrimeBits = newAttr get set
where get s = withSession s {#call gnutls_dh_get_prime_bits #} >>= return . fromIntegral
set s v = withSession s (\sp -> {#call gnutls_dh_set_prime_bits #} sp (fromIntegral v))
transport :: ReadWriteAttr (Session t) (Transport,Transport) (Transport,Transport)
transport = newAttr gnutls_transport_get_ptr2 set
where set s (a,b) = do a' <- newStablePtr a
b' <- newStablePtr b
withSession s $ \sp -> replace_transport_stable_ptrs sp a' b'
{#fun unsafe gnutls_transport_get_ptr2
{withSession* `Session t',
alloca- `Transport' ptrDeS*,
alloca- `Transport' ptrDeS*}
-> `()' #}
foreign import ccall "replace_transport_stable_ptrs"
replace_transport_stable_ptrs :: Ptr () -> StablePtr Transport -> StablePtr Transport -> IO ()
#c
void replace_transport_stable_ptrs(gnutls_session_t session, void *p1, void *p2);
#endc
#ifdef NETWORK_ALT
sock :: WriteAttr (Session t) Socket
sock = writeAttr ss
where rf sfd buf len err = recv sfd buf len `catch` ef err
sf sfd buf len err = send sfd buf len `catch` ef err
ef err _ = do (Errno iv) <- getErrno; poke err iv; return (-1)
ss (Session sfp sr) sfd = do rf' <- newStablePtr $ rf sfd
sf' <- newStablePtr $ sf sfd
withForeignPtr sfp $ \p -> replace_transport_stable_ptrs p rf' sf'
addRefFinalizer sr (close sfd)
#endif /* NETWORK_ALT */
handle :: WriteAttr (Session t) Handle
handle = writeAttr ss
where rf hdl buf len err = (hGetBuf hdl buf (fromIntegral len)) `catch` ef err
sf hdl buf len err = (hPutBuf hdl buf (fromIntegral len) >> return len) `catch` ef err
ef err _ = do (Errno iv) <- getErrno; poke err iv; return (-1)
ss (Session sfp sr) hdl = do rf' <- newStablePtr $ rf hdl
sf' <- newStablePtr $ sf hdl
hSetBuffering hdl NoBuffering
withForeignPtr sfp $ \p -> replace_transport_stable_ptrs p rf' sf'
addRefFinalizer sr (hClose hdl)
--------------------------------------------------------------------------------
----------------------------- Session Actions -------------------------------
--------------------------------------------------------------------------------
-- | Terminates the current TLS connection, which has been succesfully established
-- with 'handshake'. Notifies the peer with an alert that the connection is closing.
{#fun gnutls_bye as bye {withSession* `Session t',enumCInt `CloseRequest'} -> `()' throwGnutlsIf* #}
-- | Perform a handshake with the peer and initialize a TLS\/SSL connection.
-- Note that after the handshake completes applications /must/ check
-- whether a high enough level of confidentiality was established.
{#fun gnutls_handshake as handshake {withSession* `Session t'} -> `' throwGnutlsIf* #}
-- | Tells the client that we want to renogotiate the handshake. If the function
-- succeeds then 'handshake' can be called again on the connection.
{#fun gnutls_rehandshake as rehandshake {withSession* `Session Server'} -> `' throwGnutlsIf* #}
-- | Set the maximum size of a handshake request. Larger requests are ignored.
-- Defaults to 16kb which should be large enough.
{#fun gnutls_handshake_set_max_packet_length as setMaxHandshakePacketLength
{withSession* `Session t', fromIntegral `Int'} -> `()' #}
-- | Set whether we want to do client authentication.
clientCert :: WriteAttr (Session Server) CertificateRequest
clientCert = writeAttr p
where p s v = withSession s $ \sp -> {#call unsafe gnutls_certificate_server_set_request #} sp (enumCInt v)
--------------------------------------------------------------------------------
---------------------------- Session Getters --------------------------------
--------------------------------------------------------------------------------
serverWantedAuth :: Session Client -> IO Bool
serverWantedAuth s = withSession s $ \sp -> do
iv <- {#call gnutls_certificate_client_get_request_status #} sp
throwGnutlsIfNeg iv
return (iv /= 0)
verifyPeer :: Session t -> IO [CertificateStatus]
verifyPeer ses = do
withSession ses $ \sp -> do
alloca $ \stat -> do
{#call gnutls_certificate_verify_peers2 #} sp stat >>= throwGnutlsIf
ci <- peekEnum stat
return $ filter (\e -> fromEnum e .&. ci /= 0) [CertInvalid, CertRevoked, CertSignerNotFound, CertSignerNotCa]
-- | Test whether this session is a resumed one.
{#fun gnutls_session_is_resumed as isResumed {withSession* `Session t'} -> `Bool' isNotZero #}
isNotZero :: CInt -> Bool
isNotZero 0 = False
isNotZero _ = True
-- | Return the value of the last alert received - undefined if no alert has been received.
{#fun unsafe gnutls_alert_get as getAlert {withSession* `Session t'} -> `AlertDescription' cintEnum #}
-- | Return the currently used cipher.
{#fun unsafe gnutls_cipher_get as getCipher {withSession* `Session t'} -> `CipherAlgorithm' cintEnum #}
-- | Return the key exchange algorithm used in the last handshake.
{#fun unsafe gnutls_kx_get as getKx {withSession* `Session t'} -> `KxAlgorithm' cintEnum #}
-- | Return the mac algorithm currently used.
{#fun unsafe gnutls_mac_get as getMac {withSession* `Session t'} -> `MacAlgorithm' cintEnum #}
-- | Return the compression method currently used.
{#fun unsafe gnutls_compression_get as getCompression {withSession* `Session t'} -> `CompressionMethod' cintEnum #}
-- | Return the currently used certificate type.
{#fun unsafe gnutls_certificate_type_get as getCertificateType {withSession* `Session t'} -> `CertificateType' cintEnum #}
-- | Return the currently used protocol version.
{#fun unsafe gnutls_protocol_get_version as getProtocol {withSession* `Session t'} -> `Protocol' cintEnum #}
-- | Return type of credentials for the current authentication schema.
{#fun gnutls_auth_get_type as getCredentialsType {withSession* `Session t'} -> `CredentialsType' cintEnum #}
#ifndef COMPAT_GNUTLS_1_0
-- | Return the type of credentials used for authenticating the server. Available with GnuTLS 1.2.
{#fun gnutls_auth_server_get_type as getServerCredentialsType {withSession* `Session t'} -> `CredentialsType' cintEnum #}
-- | Return the type of credentials used for authenticating the client. Available with GnuTLS 1.2.
{#fun gnutls_auth_client_get_type as getClientCredentialsType {withSession* `Session t'} -> `CredentialsType' cintEnum #}
#endif
-- | Get the certificate chain of the peer.
-- In the case of X509 will return DER encoded certificate list
-- beginning with the peers key and continuing in the issuer chain.
-- With OpenPGP a single key will be returned in the raw format.
getPeersCertificatesRaw :: Session t -> IO [(Ptr CChar,Int)]
getPeersCertificatesRaw ses = do
withSession ses $ \sp ->
alloca $ \lenp -> do
res <- {#call gnutls_certificate_get_peers #} sp lenp
if res == nullPtr
then return []
else do len <- peek lenp
peekDatumArray (fromIntegral len - 1) res
--------------------------------------------------------------------------------
---------------------------- Read/Write Data --------------------------------
--------------------------------------------------------------------------------
{#fun gnutls_record_send as tlsSend
{withSession* `Session t', castPtr `Ptr a', fromIntegral `Int' } -> `Int' throwGnutlsIfNeg* #}
tlsSendString :: Session t -> String -> IO ()
tlsSendString ses str = withCStringLen str $ \(ptr,len) -> loop ptr len
where loop ptr len = do r <- tlsSend ses ptr len
case len-r of
x | x > 0 -> loop (plusPtr ptr r) x
| True -> return ()
{#fun gnutls_record_check_pending as tlsCheckPending
{withSession* `Session t'} -> `Int' fromIntegral #}
{#fun gnutls_record_recv as tlsRecv
{withSession* `Session t', castPtr `Ptr a', fromIntegral `Int'} -> `Int' throwGnutlsIfNeg* #}
tlsRecvString :: Session t -> IO String
tlsRecvString ses = allocaBytes 1024 $ \ptr -> do
r <- tlsRecv ses ptr 1024
peekCAStringLen (ptr,r)
--------------------------------------------------------------------------------
--------------------- Anonymous Server Credentials -------------------------
--------------------------------------------------------------------------------
anonymousServerCredentials :: IO AnonymousServerCredentials
anonymousServerCredentials = alloca $ \ptr -> do
gnutls_anon_allocate_server_credentials ptr >>= throwGnutlsIf
raw<- peek ptr
rc <- newRefCount $ gnutls_anon_free_server_credentials raw
fp <- FC.newForeignPtr raw $ freeRef rc
return $ ASC fp rc
foreign import ccall safe "TLS.h gnutls_anon_free_server_credentials"
gnutls_anon_free_server_credentials :: Ptr () -> IO ()
foreign import ccall safe "TLS.h gnutls_anon_allocate_server_credentials"
gnutls_anon_allocate_server_credentials :: Ptr (Ptr ()) -> IO CInt
class SetDHParams a where setDHParams :: a -> DH -> IO ()
instance SetDHParams AnonymousServerCredentials where
setDHParams asc@(ASC _ rc) dh@(DH _ refc) =
do gnutls_anon_set_server_dh_params asc dh
allocRef refc
addRefFinalizer rc $ freeRef refc
{#fun gnutls_anon_set_server_dh_params
{withAnonymousServerCredentials* `AnonymousServerCredentials', withDH* `DH'} -> `()' #}
--------------------------------------------------------------------------------
--------------------- Anonymous Client Credentials -------------------------
--------------------------------------------------------------------------------
anonymousClientCredentials :: IO AnonymousClientCredentials
anonymousClientCredentials = alloca $ \ptr -> do
gnutls_anon_allocate_client_credentials ptr >>= throwGnutlsIf
raw<- peek ptr
rc <- newRefCount $ gnutls_anon_free_client_credentials raw
fp <- FC.newForeignPtr raw $ freeRef rc
return $ ACC fp rc
foreign import ccall safe "TLS.h gnutls_anon_free_client_credentials"
gnutls_anon_free_client_credentials :: Ptr () -> IO ()
foreign import ccall safe "TLS.h gnutls_anon_allocate_client_credentials"
gnutls_anon_allocate_client_credentials :: Ptr (Ptr ()) -> IO CInt
--------------------------------------------------------------------------------
----------------------- Certificate Credentials ----------------------------
--------------------------------------------------------------------------------
certificateCredentials :: IO CertificateCredentials
certificateCredentials = alloca $ \ptr -> do
gnutls_certificate_allocate_credentials ptr >>= throwGnutlsIf
raw<- peek ptr
rc <- newRefCount $ gnutls_certificate_free_credentials raw
fp <- FC.newForeignPtr raw $ freeRef rc
return $ CC fp rc
foreign import ccall safe "TLS.h gnutls_certificate_free_credentials"
gnutls_certificate_free_credentials :: Ptr () -> IO ()
foreign import ccall safe "TLS.h gnutls_certificate_allocate_credentials"
gnutls_certificate_allocate_credentials :: Ptr (Ptr ()) -> IO CInt
{#fun gnutls_certificate_free_keys as freeKeys {withCertificateCredentials* `CertificateCredentials'} -> `()' #}
{#fun gnutls_certificate_free_cas as freeCas {withCertificateCredentials* `CertificateCredentials'} -> `()' #}
{#fun gnutls_certificate_free_ca_names as freeCaNames {withCertificateCredentials* `CertificateCredentials'} -> `()' #}
{#fun gnutls_certificate_free_crls as freeCrls {withCertificateCredentials* `CertificateCredentials'} -> `()' #}
instance SetDHParams CertificateCredentials where
setDHParams cc@(CC _ rc) dh@(DH _ refc) =
do gnutls_certificate_set_dh_params cc dh
allocRef refc
addRefFinalizer rc $ freeRef refc
{#fun gnutls_certificate_set_dh_params
{withCertificateCredentials* `CertificateCredentials', withDH* `DH'} -> `()' #}
{#fun gnutls_certificate_set_x509_trust_file as certificateTrustFile
{withCertificateCredentials* `CertificateCredentials',
withCAString* `FilePath',
enumCInt `X509CertificateFormat'}
-> `Int' throwGnutlsIfNeg* #}
{#fun gnutls_certificate_set_x509_crl_file as certificateCrlFile
{withCertificateCredentials* `CertificateCredentials',
withCAString* `FilePath',
enumCInt `X509CertificateFormat'}
-> `Int' throwGnutlsIfNeg* #}
{#fun gnutls_certificate_set_x509_key_file as certificateKeyFile
{withCertificateCredentials* `CertificateCredentials',
withCAString* `FilePath',
withCAString* `FilePath',
enumCInt `X509CertificateFormat'}
-> `Int' throwGnutlsIfNeg* #}
{-
void gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t res, gnutls_rsa_params_t rsa_params);
void gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t res, unsigned int flags);
void gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t res, unsigned int max_bits, unsigned int max_depth);
int gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t res, const gnutls_datum_t *CA, gnutls_x509_crt_fmt_t type);
int gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res, gnutls_x509_crt_t *ca_list, int ca_list_size);
int gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t res, const gnutls_datum_t *CRL, gnutls_x509_crt_fmt_t type);
int gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res, gnutls_x509_crl_t *crl_list, int crl_list_size);
int gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t res, const gnutls_datum_t *CERT, const gnutls_datum_t *KEY, gnutls_x509_crt_fmt_t type);
int gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res, gnutls_x509_crt_t *cert_list, int cert_list_size, gnutls_x509_privkey_t key);
-}
--------------------------------------------------------------------------------
------------------------- DH and RSA Parameters ----------------------------
--------------------------------------------------------------------------------
class CredParameter a where
-- | Generate a new key with the given number of bits.
generate :: a -> Int -> IO ()
newDH :: IO DH
newDH = alloca $ \ptr -> do
gnutls_dh_params_init ptr >>= throwGnutlsIf
raw<- peek ptr
rc <- newRefCount (gnutls_dh_params_deinit raw)
fp <- FC.newForeignPtr raw (freeRef rc)
return $ DH fp rc
foreign import ccall safe "TLS.h gnutls_dh_params_deinit" gnutls_dh_params_deinit :: Ptr () -> IO ()
foreign import ccall safe "TLS.h gnutls_dh_params_init" gnutls_dh_params_init :: Ptr (Ptr ()) -> IO CInt
instance CredParameter DH where
generate a i = withDH a (\ap -> {#call gnutls_dh_params_generate2 #} ap (fromIntegral i) >>= throwGnutlsIf)
newRSA :: IO RSA
newRSA = alloca $ \ptr -> do
gnutls_rsa_params_init ptr >>= throwGnutlsIf
raw<- peek ptr
rc <- newRefCount (gnutls_rsa_params_deinit raw)
fp <- FC.newForeignPtr raw (freeRef rc)
return $ RSA fp rc
foreign import ccall safe "TLS.h gnutls_rsa_params_deinit" gnutls_rsa_params_deinit :: Ptr () -> IO ()
foreign import ccall safe "TLS.h gnutls_rsa_params_init" gnutls_rsa_params_init :: Ptr (Ptr ()) -> IO CInt
instance CredParameter RSA where
generate a i = withRSA a (\ap -> {#call gnutls_rsa_params_generate2 #} ap (fromIntegral i) >>= throwGnutlsIf)
--------------------------------------------------------------------------------
--------------------------- Miscellaneous ----------------------------------
--------------------------------------------------------------------------------
-- | Return the cipher's key size in bytes.
{#fun pure unsafe gnutls_cipher_get_key_size as cipherKeySize
{enumCInt `CipherAlgorithm'} -> `Int' fromIntegral #}
-- | Return the name of the ciphersuite.
{#fun pure unsafe gnutls_cipher_suite_get_name as cipherSuiteName
{enumCInt `KxAlgorithm',
enumCInt `CipherAlgorithm',
enumCInt `MacAlgorithm'}
-> `String' safePeekCString* #}
-- | The version of /Gnutls/ used.
version = unsafePerformIO $ {#call gnutls_check_version #} nullPtr >>= safePeekCString
{-# NOINLINE gnutlsGlobalInitIORef #-}
gnutlsGlobalInitIORef = unsafePerformIO $ do
gcry_init_helper
{#call unsafe gnutls_global_init #} >>= throwGnutlsIf
newIORef ()
gnutlsGlobalInit = readIORef gnutlsGlobalInitIORef
foreign import ccall unsafe "gcry_init_helper" gcry_init_helper :: IO ()