@hackage peyotls0.1.6.10
Pretty Easy YOshikuni-made TLS library
Categories
License
BSD-3-Clause
Maintainer
Yoshikuni Jujo <PAF01143@nifty.ne.jp>
Links
Versions
Installation
Dependencies (21)
- base >=4 && <5
- bytestring >=0.10 && <0.11
- stm >=2.4 && <2.5
- asn1-encoding >=0.9 && <0.10
- asn1-types >=0.3 && <0.4
- bytable >=0.1 && <0.2 Show all…
Dependents (2)
@hackage/acme-everything, @hackage/xml-push
Currently implement the TLS1.2 protocol (RFC 5246, RFC 4492) only, and support the following cipher suites.
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
implement the following curves
SEC p256r1
And support client certificate with the following algorithms.
RSA with SHA256
ECDSA with SHA256
And support secure renegotiation (RFC 5746)
Currently not implement the following features.
session resumption (RFC 5077)
curves other than SEC p256r1
Server sample
file: examples/simpleServer.hs
localhost.key: key file
-----BEGIN RSA PRIVATE KEY----- ... -----END RSA PRIVATE KEY-----
localhost.crt: certificate file
-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
examples/simpleServer.hs
extensions
OverloadedStrings
PackageImports
import Control.Applicative import Control.Monad import "monads-tf" Control.Monad.State import Control.Concurrent import Data.HandleLike import Network import Network.PeyoTLS.Server import Network.PeyoTLS.ReadFile import "crypto-random" Crypto.Random import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BSC main :: IO () main = do k <- readKey "localhost.key" c <- readCertificateChain ["localhost.crt"] g0 <- cprgCreate <$> createEntropyPool :: IO SystemRNG soc <- listenOn $ PortNumber 443 void . (`runStateT` g0) . forever $ do (h, _, _) <- liftIO $ accept soc g <- StateT $ return . cprgFork liftIO . forkIO . (`run` g) $ do p <- open h ["TLS_RSA_WITH_AES_128_CBC_SHA"] [(k, c)] Nothing doUntil BS.null (hlGetLine p) >>= liftIO . mapM_ BSC.putStrLn hlPut p $ BS.concat [ "HTTP/1.1 200 OK\r\n", "Transfer-Encoding: chunked\r\n", "Content-Type: text/plain\r\n\r\n", "5\r\nHello0\r\n\r\n" ] hlClose p doUntil :: Monad m => (a -> Bool) -> m a -> m [a] doUntil p rd = rd >>= \x -> (if p x then return . (: []) else (`liftM` doUntil p rd) . (:)) x
Client sample (only show HTTP header)
file: examples/simpleClient.hs
cacert.pem: self-signed root certificate to validate server
-----BEGIN CERTIFICATE----- ... -----END CERTIFICATE-----
examples/simpleClient.hs
extensions
OverloadedStrings
PackageImports
import Control.Applicative import Control.Monad import "monads-tf" Control.Monad.Trans import Data.HandleLike import Network import Network.PeyoTLS.ReadFile import Network.PeyoTLS.Client import "crypto-random" Crypto.Random import qualified Data.ByteString.Char8 as BSC main :: IO () main = do ca <- readCertificateStore ["cacert.pem"] h <- connectTo "localhost" $ PortNumber 443 g <- cprgCreate <$> createEntropyPool :: IO SystemRNG (`run` g) $ do p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [] ca nms <- getNames p hlPut p "GET / HTTP/1.1 \r\n" hlPut p "Host: localhost\r\n\r\n" doUntil BSC.null (hlGetLine p) >>= liftIO . mapM_ BSC.putStrLn hlClose p doUntil :: Monad m => (a -> Bool) -> m a -> m [a] doUntil p rd = rd >>= \x -> (if p x then return . (: []) else (`liftM` doUntil p rd) . (:)) x
Client certificate server
file: examples/clcertServer.hs
% diff examples/simpleServer.hs examples/clcertServer.hs 19a20 > ca <- readCertificateStore ["cacert.pem"] 27c28 < Nothing --- > $ Just ca
Client certificate client (RSA certificate)
file: examples/clcertClient.hs
% diff examples/simpleClient.hs examples/clcertClient.hs 15a16,17 > rk <- readKey "client_rsa.key" > rc <- readCertificateChain ["client_rsa.crt"] 20c22 < p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [] ca --- > p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [(rk, rc)] ca
Client certificate client (ECDSA or RSA certificate)
file: examples/clcertEcdsaClient.hs
% diff examples/clcertClient.hs examples/clcertEcdsaClient.hs 17a18,19 > ek <- readKey "client_ecdsa.key" > ec <- readCertificateChain ["client_ecdsa.crt"] 22c24 < p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [(rk, rc)] ca --- > p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [(ek, ec), (rk, rc)] ca
ECC server (use ECC or RSA depending on client)
file: examples/eccServer.hs
% diff examples/simpleServer.hs examples/eccServer.hs 15a16,26 > cipherSuites :: [CipherSuite] > cipherSuites = [ > "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", > "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", > "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", > "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", > "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", > "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", > "TLS_RSA_WITH_AES_128_CBC_SHA256", > "TLS_RSA_WITH_AES_128_CBC_SHA" ] > 18,19c29,32 < k <- readKey "localhost.key" < c <- readCertificateChain ["localhost.crt"] --- > rk <- readKey "localhost.key" > rc <- readCertificateChain ["localhost.crt"] > ek <- readKey "localhost_ecdsa.key" > ec <- readCertificateChain ["localhost_ecdsa.crt"] 26c39 < p <- open h ["TLS_RSA_WITH_AES_128_CBC_SHA"] [(k, c)] --- > p <- open h cipherSuites [(rk, rc), (ek, ec)]
ECC client (use ECC or RSA depending on server)
file: examples/eccClient.hs
% diff examples/simpleClient.hs examples/eccClient.hs 13a14,24 > cipherSuites :: [CipherSuite] > cipherSuites = [ > "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", > "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", > "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", > "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", > "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", > "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", > "TLS_RSA_WITH_AES_128_CBC_SHA256", > "TLS_RSA_WITH_AES_128_CBC_SHA" ] > 20c31 < p <- open' h "localhost" ["TLS_RSA_WITH_AES_128_CBC_SHA"] [] ca --- > p <- open' h "localhost" cipherSuites [] ca