packages feed

connection 0.2.3 → 0.2.4

raw patch · 7 files changed

+517/−8 lines, 7 filesdep +byteabledep +crypto-randomdep +securememdep −cprng-aesPVP ok

version bump matches the API change (PVP)

Dependencies added: byteable, crypto-random, securemem

Dependencies removed: cprng-aes

API changes (from Hackage documentation)

Files

Network/Connection.hs view
@@ -65,7 +65,8 @@ import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy as L -import qualified Crypto.Random.AESCtr as RNG+import           Crypto.Random (createEntropyPool, grabEntropyIO)+import qualified Network.Connection.ChachaRNG as RNG  import System.Environment import System.IO@@ -92,6 +93,7 @@ -- | Initialize the library with shared parameters between connection. initConnectionContext :: IO ConnectionContext initConnectionContext = ConnectionContext <$> getSystemCertificateStore+                                          <*> createEntropyPool  -- | Create a final TLS 'ClientParams' according to the destination and the -- TLSSettings.@@ -134,7 +136,7 @@                   -> IO Connection connectFromHandle cg h p = withSecurity (connectionUseSecure p)     where withSecurity Nothing            = connectionNew cid $ ConnectionStream h-          withSecurity (Just tlsSettings) = tlsEstablish h (makeTLSParams cg cid tlsSettings) >>= connectionNew cid . ConnectionTLS+          withSecurity (Just tlsSettings) = tlsEstablish cg h (makeTLSParams cg cid tlsSettings) >>= connectionNew cid . ConnectionTLS           cid = (connectionHostname p, connectionPort p)  -- | connect to a destination using the parameter@@ -298,7 +300,7 @@     modifyMVar_ (connectionBuffer connection) $ \b ->     modifyMVar (connectionBackend connection) $ \backend ->         case backend of-            (ConnectionStream h) -> do ctx <- tlsEstablish h (makeTLSParams cg (connectionID connection) params)+            (ConnectionStream h) -> do ctx <- tlsEstablish cg h (makeTLSParams cg (connectionID connection) params)                                        return (ConnectionTLS ctx, Just B.empty)             (ConnectionTLS _)    -> return (backend, b) @@ -308,9 +310,9 @@     where isSecure (ConnectionStream _) = return False           isSecure (ConnectionTLS _)    = return True -tlsEstablish :: Handle -> TLS.ClientParams -> IO TLS.Context-tlsEstablish handle tlsParams = do-    rng <- RNG.makeSystem+tlsEstablish :: ConnectionContext -> Handle -> TLS.ClientParams -> IO TLS.Context+tlsEstablish cg handle tlsParams = do+    rng <- RNG.initialize <$> grabEntropyIO 40 (globalEntropyPool cg)     ctx <- TLS.contextNew handle tlsParams rng     TLS.handshake ctx     return ctx
+ Network/Connection/ChachaRNG.hs view
@@ -0,0 +1,63 @@+-- |+-- Module      : Network.Connection.ChachaRNG+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : stable+-- Portability : good+--+{-# LANGUAGE ForeignFunctionInterface #-}+module Network.Connection.ChachaRNG+    ( initialize+    , generate+    , ChachaRNG+    ) where++import Crypto.Random+import Data.SecureMem+import Data.ByteString (ByteString)+import qualified Data.ByteString.Internal as B+import qualified Data.ByteString as B+import Data.Byteable+import Data.Word+import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.C.Types+import System.IO.Unsafe++instance CPRG ChachaRNG where+    cprgCreate entPool = initialize (grabEntropy 40 entPool)+    cprgGenerate = generate++-- | ChaCha context+newtype ChachaRNG = ChachaRNG SecureMem++-- | Initialize a new ChaCha context with the number of rounds,+-- the key and the nonce associated.+initialize :: Byteable seed+           => seed        -- ^ 40 bytes of seed+           -> ChachaRNG       -- ^ the initial ChaCha state+initialize seed+    | sLen /= 40 = error "ChaCha Random: seed length should be 40 bits"+    | otherwise = unsafePerformIO $ do+        stPtr <- createSecureMem 64 $ \stPtr ->+                    withBytePtr seed $ \seedPtr ->+                        ccryptonite_chacha_init (castPtr stPtr) seedPtr+        return $ ChachaRNG stPtr+  where sLen     = byteableLength seed++generate :: Int -> ChachaRNG -> (ByteString, ChachaRNG)+generate nbBytes st@(ChachaRNG prevSt)+    | nbBytes <= 0 = (B.empty, st)+    | otherwise    = unsafePerformIO $ do+        output <- B.mallocByteString nbBytes+        newSt  <- secureMemCopy prevSt+        withForeignPtr output $ \dstPtr ->+            withSecureMemPtr newSt $ \stPtr ->+                ccryptonite_chacha_random 8 dstPtr (castPtr stPtr) (fromIntegral nbBytes)+        return (B.PS output 0 nbBytes, ChachaRNG newSt)++foreign import ccall "connection_chacha_init"+    ccryptonite_chacha_init :: Ptr ChachaRNG -> Ptr Word8 -> IO ()++foreign import ccall "connection_chacha_random"+    ccryptonite_chacha_random :: Int -> Ptr Word8 -> Ptr ChachaRNG -> CUInt -> IO ()
Network/Connection/Types.hs view
@@ -11,6 +11,7 @@     where  import Control.Concurrent.MVar (MVar)+import Crypto.Random (EntropyPool)  import Data.Default.Class import Data.X509.CertificateStore@@ -93,4 +94,5 @@ -- when using a TLS enabled connection. data ConnectionContext = ConnectionContext     { globalCertificateStore :: !CertificateStore+    , globalEntropyPool      :: !EntropyPool     }
+ cbits/cryptonite_bitfn.h view
@@ -0,0 +1,251 @@+/*+ * Copyright (C) 2006-2014 Vincent Hanquez <vincent@snarc.org>+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ *+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.+ */++#ifndef BITFN_H+#define BITFN_H+#include <stdint.h>++#ifndef NO_INLINE_ASM+/**********************************************************/+# if (defined(__i386__))+#  define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}+/**********************************************************/+# elif (defined(__arm__))+#  define ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+	uint32_t tmp = a;+	asm volatile ("eor %1, %0, %0, ror #16\n"+	              "bic %1, %1, #0xff0000\n"+	              "mov %0, %0, ror #8\n"+	              "eor %0, %0, %1, lsr #8\n"+	             : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp));+	return a;+}+/**********************************************************/+# elif defined(__x86_64__)+#  define ARCH_HAS_SWAP32+#  define ARCH_HAS_SWAP64+static inline uint32_t bitfn_swap32(uint32_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}++static inline uint64_t bitfn_swap64(uint64_t a)+{+	asm ("bswap %0" : "=r" (a) : "0" (a));+	return a;+}++# endif+#endif /* NO_INLINE_ASM */+/**********************************************************/++#ifndef ARCH_HAS_ROL32+static inline uint32_t rol32(uint32_t word, uint32_t shift)+{+	return (word << shift) | (word >> (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROR32+static inline uint32_t ror32(uint32_t word, uint32_t shift)+{+	return (word >> shift) | (word << (32 - shift));+}+#endif++#ifndef ARCH_HAS_ROL64+static inline uint64_t rol64(uint64_t word, uint32_t shift)+{+	return (word << shift) | (word >> (64 - shift));+}+#endif++#ifndef ARCH_HAS_ROR64+static inline uint64_t ror64(uint64_t word, uint32_t shift)+{+	return (word >> shift) | (word << (64 - shift));+}+#endif++#ifndef ARCH_HAS_SWAP32+static inline uint32_t bitfn_swap32(uint32_t a)+{+	return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP32+static inline void array_swap32(uint32_t *d, uint32_t *s, uint32_t nb)+{+	while (nb--)+		*d++ = bitfn_swap32(*s++);+}+#endif++#ifndef ARCH_HAS_SWAP64+static inline uint64_t bitfn_swap64(uint64_t a)+{+	return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |+	       (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);+}+#endif++#ifndef ARCH_HAS_ARRAY_SWAP64+static inline void array_swap64(uint64_t *d, uint64_t *s, uint32_t nb)+{+	while (nb--)+		*d++ = bitfn_swap64(*s++);+}+#endif++#ifndef ARCH_HAS_MEMORY_ZERO+static inline void memory_zero(void *ptr, uint32_t len)+{+	uint32_t *ptr32 = ptr;+	uint8_t *ptr8;+	int i;++	for (i = 0; i < len / 4; i++)+		*ptr32++ = 0;+	if (len % 4) {+		ptr8 = (uint8_t *) ptr32;+		for (i = len % 4; i >= 0; i--)+			ptr8[i] = 0;+	}+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY32+static inline void array_copy32(uint32_t *d, uint32_t *s, uint32_t nb)+{+	while (nb--) *d++ = *s++;+}+#endif++#ifndef ARCH_HAS_ARRAY_XOR32+static inline void array_xor32(uint32_t *d, uint32_t *s, uint32_t nb)+{+	while (nb--) *d++ ^= *s++;+}+#endif++#ifndef ARCH_HAS_ARRAY_COPY64+static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb)+{+	while (nb--) *d++ = *s++;+}+#endif++#ifdef __GNUC__+#define bitfn_ntz(n) __builtin_ctz(n)+#else+#error "define ntz for your platform"+#endif++#ifdef __MINGW32__+  # define LITTLE_ENDIAN 1234+  # define BYTE_ORDER    LITTLE_ENDIAN+#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__)+  # include <sys/endian.h>+#elif defined(__OpenBSD__) || defined(__SVR4)+  # include <sys/types.h>+#elif defined(__APPLE__)+  # include <machine/endian.h>+#elif defined( BSD ) && ( BSD >= 199103 )+  # include <machine/endian.h>+#elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ )+  # define LITTLE_ENDIAN 1234+  # define BYTE_ORDER    LITTLE_ENDIAN+#elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ )+  # define BIG_ENDIAN 1234+  # define BYTE_ORDER    BIG_ENDIAN+#else+  # include <endian.h>+#endif+/* big endian to cpu */+#if LITTLE_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_be32(a) bitfn_swap32(a)+# define le32_to_cpu(a) (a)+# define cpu_to_le32(a) (a)+# define be64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_be64(a) bitfn_swap64(a)+# define le64_to_cpu(a) (a)+# define cpu_to_le64(a) (a)++# define cpu_to_le32_array(d, s, l) array_copy32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_copy32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_swap32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_swap32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_copy64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_copy64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_swap64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_swap64(d, s, l)++# define ror32_be(a, s) rol32(a, s)+# define rol32_be(a, s) ror32(a, s)++# define ARCH_IS_LITTLE_ENDIAN++#elif BIG_ENDIAN == BYTE_ORDER++# define be32_to_cpu(a) (a)+# define cpu_to_be32(a) (a)+# define be64_to_cpu(a) (a)+# define cpu_to_be64(a) (a)+# define le64_to_cpu(a) bitfn_swap64(a)+# define cpu_to_le64(a) bitfn_swap64(a)+# define le32_to_cpu(a) bitfn_swap32(a)+# define cpu_to_le32(a) bitfn_swap32(a)++# define cpu_to_le32_array(d, s, l) array_swap32(d, s, l)+# define le32_to_cpu_array(d, s, l) array_swap32(d, s, l)+# define cpu_to_be32_array(d, s, l) array_copy32(d, s, l)+# define be32_to_cpu_array(d, s, l) array_copy32(d, s, l)++# define cpu_to_le64_array(d, s, l) array_swap64(d, s, l)+# define le64_to_cpu_array(d, s, l) array_swap64(d, s, l)+# define cpu_to_be64_array(d, s, l) array_copy64(d, s, l)+# define be64_to_cpu_array(d, s, l) array_copy64(d, s, l)++# define ror32_be(a, s) ror32(a, s)+# define rol32_be(a, s) rol32(a, s)++# define ARCH_IS_BIG_ENDIAN++#else+# error "endian not supported"+#endif++#endif /* !BITFN_H */
+ cbits/random_chacha.c view
@@ -0,0 +1,141 @@+/*+ * Copyright (c) 2014 Vincent Hanquez <vincent@snarc.org>+ *+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */++#include <stdint.h>+#include <string.h>+#include "random_chacha.h"+#include "cryptonite_bitfn.h"+#include <stdio.h>++#define USE_8BITS 0++#define QR(a,b,c,d) \+	a += b; d = rol32(d ^ a,16); \+	c += d; b = rol32(b ^ c,12); \+	a += b; d = rol32(d ^ a, 8); \+	c += d; b = rol32(b ^ c, 7);++static const uint8_t sigma[16] = "expand 32-byte k";+static const uint8_t tau[16] = "expand 16-byte k";++static inline uint32_t load32(const uint8_t *p)+{+	return le32_to_cpu(*((uint32_t *) p));+}++static void chacha_core(int rounds, block *out, const cryptonite_chacha_state *in)+{+	uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;+	int i;++	x0 = in->d[0]; x1 = in->d[1]; x2 = in->d[2]; x3 = in->d[3];+	x4 = in->d[4]; x5 = in->d[5]; x6 = in->d[6]; x7 = in->d[7];+	x8 = in->d[8]; x9 = in->d[9]; x10 = in->d[10]; x11 = in->d[11];+	x12 = in->d[12]; x13 = in->d[13]; x14 = in->d[14]; x15 = in->d[15];++	for (i = rounds; i > 0; i -= 2) {+		QR(x0, x4, x8, x12);+		QR(x1, x5, x9, x13);+		QR(x2, x6, x10, x14);+		QR(x3, x7, x11, x15);++		QR(x0, x5, x10, x15);+		QR(x1, x6, x11, x12);+		QR(x2, x7, x8, x13);+		QR(x3, x4, x9, x14);+	}++	x0 += in->d[0]; x1 += in->d[1]; x2 += in->d[2]; x3 += in->d[3];+	x4 += in->d[4]; x5 += in->d[5]; x6 += in->d[6]; x7 += in->d[7];+	x8 += in->d[8]; x9 += in->d[9]; x10 += in->d[10]; x11 += in->d[11];+	x12 += in->d[12]; x13 += in->d[13]; x14 += in->d[14]; x15 += in->d[15];++	out->d[0] = cpu_to_le32(x0);+	out->d[1] = cpu_to_le32(x1);+	out->d[2] = cpu_to_le32(x2);+	out->d[3] = cpu_to_le32(x3);+	out->d[4] = cpu_to_le32(x4);+	out->d[5] = cpu_to_le32(x5);+	out->d[6] = cpu_to_le32(x6);+	out->d[7] = cpu_to_le32(x7);+	out->d[8] = cpu_to_le32(x8);+	out->d[9] = cpu_to_le32(x9);+	out->d[10] = cpu_to_le32(x10);+	out->d[11] = cpu_to_le32(x11);+	out->d[12] = cpu_to_le32(x12);+	out->d[13] = cpu_to_le32(x13);+	out->d[14] = cpu_to_le32(x14);+	out->d[15] = cpu_to_le32(x15);+}++/* 40 bytes of key (key (32 bytes) + nonce (8)) */+void connection_chacha_init(cryptonite_chacha_state *st, const uint8_t *key)+{+	const uint8_t *constants = sigma;+	const uint8_t *iv = key + 32;+	int i;++	st->d[0] = load32(constants + 0);+	st->d[1] = load32(constants + 4);+	st->d[2] = load32(constants + 8);+	st->d[3] = load32(constants + 12);++	st->d[4] = load32(key + 0);+	st->d[5] = load32(key + 4);+	st->d[6] = load32(key + 8);+	st->d[7] = load32(key + 12);+	key += 16;+	st->d[8] = load32(key + 0);+	st->d[9] = load32(key + 4);+	st->d[10] = load32(key + 8);+	st->d[11] = load32(key + 12);+	st->d[12] = 0;+	st->d[13] = 0;+	st->d[14] = load32(iv + 0);+	st->d[15] = load32(iv + 4);+}++void connection_chacha_random(uint32_t rounds, uint8_t *dst, cryptonite_chacha_state *st, uint32_t bytes)+{+	block out;++	if (!bytes)+		return;+	for (; bytes >= 16; bytes -= 16, dst += 16) {+		chacha_core(rounds, &out, st);+		memcpy(dst, out.b + 40, 16);+		connection_chacha_init(st, out.b);+	}+	if (bytes) {+		chacha_core(rounds, &out, st);+		memcpy(dst, out.b + 40, bytes);+		connection_chacha_init(st, out.b);+	}+}
+ cbits/random_chacha.h view
@@ -0,0 +1,44 @@+/*+ * Copyright (c) 2014 Vincent Hanquez <vincent@snarc.org>+ *+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without+ * modification, are permitted provided that the following conditions+ * are met:+ * 1. Redistributions of source code must retain the above copyright+ *    notice, this list of conditions and the following disclaimer.+ * 2. Redistributions in binary form must reproduce the above copyright+ *    notice, this list of conditions and the following disclaimer in the+ *    documentation and/or other materials provided with the distribution.+ * 3. Neither the name of the author nor the names of his contributors+ *    may be used to endorse or promote products derived from this software+ *    without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+ * SUCH DAMAGE.+ */+#ifndef CRYPTONITE_CHACHA+#define CRYPTONITE_CHACHA++typedef union {+	uint64_t q[8];+	uint32_t d[16];+	uint8_t  b[64];+} block;++typedef block cryptonite_chacha_state;++void connection_chacha_init(cryptonite_chacha_state *st, const uint8_t *seed);+void connection_chacha_random(uint32_t rounds, uint8_t *dst, cryptonite_chacha_state *st, uint32_t bytes);++#endif
connection.cabal view
@@ -1,5 +1,5 @@ Name:                connection-Version:             0.2.3+Version:             0.2.4 Description:     Simple network library for all your connection need.     .@@ -20,23 +20,29 @@ Homepage:            http://github.com/vincenthz/hs-connection extra-source-files:  README.md                      CHANGELOG.md+                     cbits/*.h  Library   Build-Depends:     base >= 3 && < 5                    , bytestring+                   , byteable+                   , crypto-random                    , containers                    , data-default-class                    , network >= 2.3                    , tls >= 1.2-                   , cprng-aes                    , socks >= 0.4+                   , securemem                    , x509 >= 1.4                    , x509-store >= 1.4                    , x509-system >= 1.4                    , x509-validation >= 1.5   Exposed-modules:   Network.Connection   Other-modules:     Network.Connection.Types+                     Network.Connection.ChachaRNG   ghc-options:       -Wall+  C-sources:         cbits/random_chacha.c+  include-dirs:      cbits  source-repository head   type: git