module Network.CommSec.KeyExchange
( connect
, accept
, CS.send, CS.recv, CS.Connection, CS.close
, Net.HostName, Net.PortNumber
) where
import qualified Network.Socket as Net
import qualified Network.Socket.ByteString as NetBS
import Crypto.Types.PubKey.RSA
import Crypto.Cipher.AES128
import Crypto.Classes
import Crypto.Util
import Crypto.Modes (zeroIV)
import Crypto.Hash.CryptoAPI
import Control.Monad
import Control.Monad.CryptoRandom
import qualified Codec.Crypto.RSA as RSA
import qualified Data.ByteString as B
import Data.ByteString (ByteString)
import Data.ByteString.Lazy (fromStrict, toChunks)
import qualified Data.ByteString.Lazy as L
import Data.Serialize
import Data.Serialize.Get
import Data.Serialize.Put
import Crypto.Random.DRBG
import Data.Maybe (listToMaybe)
import Control.Concurrent
import Foreign.Storable
import qualified Network.CommSec as CS
import Network.CommSec hiding (accept, connect)
import Network.CommSec.Package (InContext(..), OutContext(..))
import qualified Network.CommSec.KeyExchange.Internal as I
import qualified Network.CommSec.KeyExchange.Socket as S
connect :: Net.HostName
-> Net.PortNumber
-> [PublicKey]
-> PrivateKey
-> IO (PublicKey,Connection)
connect host port thems us = do
sockaddr <- resolve host port
socket <- Net.socket Net.AF_INET Net.Stream Net.defaultProtocol
maybe (error "Could not agree on a key.") id
`fmap` (S.connect socket sockaddr thems us)
where
resolve :: Net.HostName -> Net.PortNumber -> IO Net.SockAddr
resolve h port = do
ai <- Net.getAddrInfo (Just $ Net.defaultHints {
Net.addrFamily = Net.AF_INET, Net.addrSocketType = Net.Stream } ) (Just h) (Just (show port))
return (maybe (error $ "Could not resolve host " ++ h) Net.addrAddress (listToMaybe ai))
accept :: Net.PortNumber -> [PublicKey] -> PrivateKey -> IO (PublicKey,Connection)
accept port thems us = do
let sockaddr = Net.SockAddrInet port Net.iNADDR_ANY
sock <- Net.socket Net.AF_INET Net.Stream Net.defaultProtocol
Net.setSocketOption sock Net.ReuseAddr 1
Net.bind sock sockaddr
Net.listen sock 1
mconn <- S.accept sock thems us
case mconn of
Nothing -> error "Failed to perform key exchange"
Just (t,c) -> do
Net.close sock
return (t,c)