MyNixOS website logo
Description

Pretty Easy YOshikuni-made TLS library.

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
Metadata

Version

0.1.6.10

Platforms (75)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-darwin
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-darwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-windows